Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Concerns/HasValidations.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace A2Workspace\ModelBuilder\Concerns;

use Illuminate\Container\Container;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Validation\ValidationException;
use A2Workspace\ModelBuilder\Exceptions\ValidationException as BuilderValidationException;
Expand Down Expand Up @@ -103,6 +104,6 @@ public function customAttributes(): array
*/
protected function getValidationFactory()
{
return app(Factory::class);
return Container::getInstance()->make(Factory::class);
}
}
72 changes: 72 additions & 0 deletions src/Concerns/ResolvesBuilderNames.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace A2Workspace\ModelBuilder\Concerns;

use Illuminate\Support\Str;

trait ResolvesBuilderNames
{
/**
* 名稱解析器。
*
* @var callable
*/
protected static $nameResolver = null;

/**
* 定義 ModelBuilder 的命名空間所在。
*
* @var string
*/
protected static $namespace = 'App\\ModelBuilders\\';

/**
* 定義 App 的命名空間。
*
* @var string
*/
protected static $appNamespace = 'App\\';

/**
* 透過給定的 Model 名稱,取得一個新的 ModelBuilder 實體。
*
* @param string $modelName
* @return static
*/
public static function builderForModel(string $modelName)
{
$factory = static::resolveBuilderName($modelName);

return new $factory;
}

/**
* 透過給定的 Model 名稱,嘗試取得 ModelBuilder 類別名稱。
*
* @param string $modelName
* @return string
*/
public static function resolveBuilderName(string $modelName)
{
$resolver = static::$nameResolver ?: function (string $modelName) {
$modelName = Str::startsWith($modelName, static::$appNamespace . 'Models\\')
? Str::after($modelName, static::$appNamespace . 'Models\\')
: Str::after($modelName, static::$appNamespace);

return static::$namespace . $modelName . 'Builder';
};

return $resolver($modelName);
}

/**
* 指定一個函式用來處理 ModelBuilder 的名稱解析。
*
* @param callable $callback
* @return void
*/
public static function guessNamesUsing(callable $callback)
{
static::$nameResolver = $callback;
}
}
2 changes: 1 addition & 1 deletion src/HasModelBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait HasModelBuilder
*/
public static function builder(array $attributes = []): ModelBuilder
{
$builder = static::newModelBuilder();
$builder = static::newModelBuilder() ?: ModelBuilder::builderForModel(get_called_class());

if ($builder instanceof ModelBuilder) {
$builder->fill($attributes);
Expand Down
3 changes: 2 additions & 1 deletion src/ModelBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ abstract class ModelBuilder
{
use Concerns\HasAttributes,
Concerns\HasSubtasks,
Concerns\HasValidations;
Concerns\HasValidations,
Concerns\ResolvesBuilderNames;

/**
* 呼叫生成器創見後的產物集合。
Expand Down
20 changes: 20 additions & 0 deletions tests/Unit/HasModelBuilderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Tests\Unit;

require __DIR__ . '/stubs/HasModelBuilderTestModelStub.php';
require __DIR__ . '/stubs/HasModelBuilderTestBuilderStub.php';

use Tests\TestCase;
use App\Models\Post;
use App\ModelBuilders\PostBuilder;

class HasModelBuilderTest extends TestCase
{
public function test_resolve_builder_name()
{
$builder = Post::builder();

$this->assertInstanceOf(PostBuilder::class, $builder);
}
}
36 changes: 36 additions & 0 deletions tests/Unit/ResolvesBuilderNamesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Tests\Unit;

use Tests\TestCase;
use A2Workspace\ModelBuilder\Concerns\ResolvesBuilderNames;

class ResolvesBuilderNamesTest extends TestCase
{
public function test_resolve_builder_name()
{
$this->assertEquals(
'App\\ModelBuilders\\PostBuilder',
ModelBuilder::resolveBuilderName('App\\Models\\Post')
);

$this->assertEquals(
'App\\ModelBuilders\\PostBuilder',
ModelBuilder::resolveBuilderName('App\\Post')
);

$this->assertEquals(
'App\\ModelBuilders\\Admin\\PostBuilder',
ModelBuilder::resolveBuilderName('App\\Admin\\Post')
);
}
}

// =============================================================================
// = Stubs
// =============================================================================

abstract class ModelBuilder
{
use ResolvesBuilderNames;
}
11 changes: 11 additions & 0 deletions tests/Unit/stubs/HasModelBuilderTestBuilderStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\ModelBuilders;

class PostBuilder extends \A2Workspace\ModelBuilder\ModelBuilder
{
public function make()
{
// ...
}
}
8 changes: 8 additions & 0 deletions tests/Unit/stubs/HasModelBuilderTestModelStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace App\Models;

class Post
{
use \A2Workspace\ModelBuilder\HasModelBuilder;
}