File tree Expand file tree Collapse file tree 3 files changed +74
-0
lines changed
src/Illuminate/Database/Eloquent Expand file tree Collapse file tree 3 files changed +74
-0
lines changed Original file line number Diff line number Diff line change
1
+ <?php
2
+
3
+ namespace Illuminate \Database \Eloquent \Attributes ;
4
+
5
+ use Attribute ;
6
+
7
+ #[Attribute(Attribute::TARGET_CLASS )]
8
+ class UseEloquentBuilder
9
+ {
10
+ /**
11
+ * Create a new attribute instance.
12
+ *
13
+ * @param class-string<\Illuminate\Database\Eloquent\Builder> $builderClass
14
+ */
15
+ public function __construct (public string $ builderClass )
16
+ {
17
+ }
18
+ }
Original file line number Diff line number Diff line change 13
13
use Illuminate \Contracts \Support \Jsonable ;
14
14
use Illuminate \Database \ConnectionResolverInterface as Resolver ;
15
15
use Illuminate \Database \Eloquent \Attributes \Scope as LocalScope ;
16
+ use Illuminate \Database \Eloquent \Attributes \UseEloquentBuilder ;
16
17
use Illuminate \Database \Eloquent \Collection as EloquentCollection ;
17
18
use Illuminate \Database \Eloquent \Relations \BelongsToMany ;
18
19
use Illuminate \Database \Eloquent \Relations \Concerns \AsPivot ;
26
27
use JsonException ;
27
28
use JsonSerializable ;
28
29
use LogicException ;
30
+ use ReflectionClass ;
29
31
use ReflectionMethod ;
30
32
use Stringable ;
31
33
@@ -1651,9 +1653,30 @@ public function newQueryForRestoration($ids)
1651
1653
*/
1652
1654
public function newEloquentBuilder ($ query )
1653
1655
{
1656
+ $ builderClass = $ this ->resolveCustomBuilderClass ();
1657
+
1658
+ if ($ builderClass && is_subclass_of ($ builderClass , Builder::class)) {
1659
+ return new $ builderClass ($ query );
1660
+ }
1661
+
1654
1662
return new static::$ builder ($ query );
1655
1663
}
1656
1664
1665
+ /**
1666
+ * Resolve the custom Eloquent builder class from the model attributes.
1667
+ *
1668
+ * @return class-string<\Illuminate\Database\Eloquent\Builder>|false
1669
+ */
1670
+ protected function resolveCustomBuilderClass ()
1671
+ {
1672
+ $ attributes = (new ReflectionClass ($ this ))
1673
+ ->getAttributes (UseEloquentBuilder::class);
1674
+
1675
+ return ! empty ($ attributes )
1676
+ ? $ attributes [0 ]->newInstance ()->builderClass
1677
+ : false ;
1678
+ }
1679
+
1657
1680
/**
1658
1681
* Get a new query builder instance for the connection.
1659
1682
*
Original file line number Diff line number Diff line change @@ -3365,6 +3365,39 @@ public function testUseFactoryAttribute()
3365
3365
$ this ->assertEquals (EloquentModelWithUseFactoryAttribute::class, $ factory ->modelName ());
3366
3366
$ this ->assertEquals ('test name ' , $ instance ->name ); // Small smoke test to ensure the factory is working
3367
3367
}
3368
+
3369
+ public function testUseCustomBuilderWithUseEloquentBuilderAttribute ()
3370
+ {
3371
+ $ model = new EloquentModelWithUseEloquentBuilderAttributeStub ();
3372
+
3373
+ $ query = $ this ->createMock (\Illuminate \Database \Query \Builder::class);
3374
+ $ eloquentBuilder = $ model ->newEloquentBuilder ($ query );
3375
+
3376
+ $ this ->assertInstanceOf (CustomBuilder::class, $ eloquentBuilder );
3377
+ }
3378
+
3379
+ public function testDefaultBuilderIsUsedWhenUseEloquentBuilderAttributeIsNotPresent ()
3380
+ {
3381
+ $ model = new EloquentModelWithoutUseEloquentBuilderAttributeStub ();
3382
+
3383
+ $ query = $ this ->createMock (\Illuminate \Database \Query \Builder::class);
3384
+ $ eloquentBuilder = $ model ->newEloquentBuilder ($ query );
3385
+
3386
+ $ this ->assertNotInstanceOf (CustomBuilder::class, $ eloquentBuilder );
3387
+ }
3388
+ }
3389
+
3390
+ class CustomBuilder extends Builder
3391
+ {
3392
+ }
3393
+
3394
+ #[\Illuminate \Database \Eloquent \Attributes \UseEloquentBuilder(CustomBuilder::class)]
3395
+ class EloquentModelWithUseEloquentBuilderAttributeStub extends Model
3396
+ {
3397
+ }
3398
+
3399
+ class EloquentModelWithoutUseEloquentBuilderAttributeStub extends Model
3400
+ {
3368
3401
}
3369
3402
3370
3403
class EloquentTestObserverStub
You can’t perform that action at this time.
0 commit comments