Skip to content

Commit f032548

Browse files
authored
增加名稱解析功能 (#1)
* 修改服務容器的取得方式 * 增加 ModelBuilder 名稱解析功能 * 增加 HasModelBuilder 單元測試
1 parent 845ee90 commit f032548

File tree

8 files changed

+152
-3
lines changed

8 files changed

+152
-3
lines changed

src/Concerns/HasValidations.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace A2Workspace\ModelBuilder\Concerns;
44

5+
use Illuminate\Container\Container;
56
use Illuminate\Contracts\Validation\Factory;
67
use Illuminate\Validation\ValidationException;
78
use A2Workspace\ModelBuilder\Exceptions\ValidationException as BuilderValidationException;
@@ -103,6 +104,6 @@ public function customAttributes(): array
103104
*/
104105
protected function getValidationFactory()
105106
{
106-
return app(Factory::class);
107+
return Container::getInstance()->make(Factory::class);
107108
}
108109
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace A2Workspace\ModelBuilder\Concerns;
4+
5+
use Illuminate\Support\Str;
6+
7+
trait ResolvesBuilderNames
8+
{
9+
/**
10+
* 名稱解析器。
11+
*
12+
* @var callable
13+
*/
14+
protected static $nameResolver = null;
15+
16+
/**
17+
* 定義 ModelBuilder 的命名空間所在。
18+
*
19+
* @var string
20+
*/
21+
protected static $namespace = 'App\\ModelBuilders\\';
22+
23+
/**
24+
* 定義 App 的命名空間。
25+
*
26+
* @var string
27+
*/
28+
protected static $appNamespace = 'App\\';
29+
30+
/**
31+
* 透過給定的 Model 名稱,取得一個新的 ModelBuilder 實體。
32+
*
33+
* @param string $modelName
34+
* @return static
35+
*/
36+
public static function builderForModel(string $modelName)
37+
{
38+
$factory = static::resolveBuilderName($modelName);
39+
40+
return new $factory;
41+
}
42+
43+
/**
44+
* 透過給定的 Model 名稱,嘗試取得 ModelBuilder 類別名稱。
45+
*
46+
* @param string $modelName
47+
* @return string
48+
*/
49+
public static function resolveBuilderName(string $modelName)
50+
{
51+
$resolver = static::$nameResolver ?: function (string $modelName) {
52+
$modelName = Str::startsWith($modelName, static::$appNamespace . 'Models\\')
53+
? Str::after($modelName, static::$appNamespace . 'Models\\')
54+
: Str::after($modelName, static::$appNamespace);
55+
56+
return static::$namespace . $modelName . 'Builder';
57+
};
58+
59+
return $resolver($modelName);
60+
}
61+
62+
/**
63+
* 指定一個函式用來處理 ModelBuilder 的名稱解析。
64+
*
65+
* @param callable $callback
66+
* @return void
67+
*/
68+
public static function guessNamesUsing(callable $callback)
69+
{
70+
static::$nameResolver = $callback;
71+
}
72+
}

src/HasModelBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trait HasModelBuilder
1414
*/
1515
public static function builder(array $attributes = []): ModelBuilder
1616
{
17-
$builder = static::newModelBuilder();
17+
$builder = static::newModelBuilder() ?: ModelBuilder::builderForModel(get_called_class());
1818

1919
if ($builder instanceof ModelBuilder) {
2020
$builder->fill($attributes);

src/ModelBuilder.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ abstract class ModelBuilder
2323
{
2424
use Concerns\HasAttributes,
2525
Concerns\HasSubtasks,
26-
Concerns\HasValidations;
26+
Concerns\HasValidations,
27+
Concerns\ResolvesBuilderNames;
2728

2829
/**
2930
* 呼叫生成器創見後的產物集合。

tests/Unit/HasModelBuilderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Tests\Unit;
4+
5+
require __DIR__ . '/stubs/HasModelBuilderTestModelStub.php';
6+
require __DIR__ . '/stubs/HasModelBuilderTestBuilderStub.php';
7+
8+
use Tests\TestCase;
9+
use App\Models\Post;
10+
use App\ModelBuilders\PostBuilder;
11+
12+
class HasModelBuilderTest extends TestCase
13+
{
14+
public function test_resolve_builder_name()
15+
{
16+
$builder = Post::builder();
17+
18+
$this->assertInstanceOf(PostBuilder::class, $builder);
19+
}
20+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Tests\Unit;
4+
5+
use Tests\TestCase;
6+
use A2Workspace\ModelBuilder\Concerns\ResolvesBuilderNames;
7+
8+
class ResolvesBuilderNamesTest extends TestCase
9+
{
10+
public function test_resolve_builder_name()
11+
{
12+
$this->assertEquals(
13+
'App\\ModelBuilders\\PostBuilder',
14+
ModelBuilder::resolveBuilderName('App\\Models\\Post')
15+
);
16+
17+
$this->assertEquals(
18+
'App\\ModelBuilders\\PostBuilder',
19+
ModelBuilder::resolveBuilderName('App\\Post')
20+
);
21+
22+
$this->assertEquals(
23+
'App\\ModelBuilders\\Admin\\PostBuilder',
24+
ModelBuilder::resolveBuilderName('App\\Admin\\Post')
25+
);
26+
}
27+
}
28+
29+
// =============================================================================
30+
// = Stubs
31+
// =============================================================================
32+
33+
abstract class ModelBuilder
34+
{
35+
use ResolvesBuilderNames;
36+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\ModelBuilders;
4+
5+
class PostBuilder extends \A2Workspace\ModelBuilder\ModelBuilder
6+
{
7+
public function make()
8+
{
9+
// ...
10+
}
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
class Post
6+
{
7+
use \A2Workspace\ModelBuilder\HasModelBuilder;
8+
}

0 commit comments

Comments
 (0)