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 1313use Illuminate \Contracts \Support \Jsonable ;
1414use Illuminate \Database \ConnectionResolverInterface as Resolver ;
1515use Illuminate \Database \Eloquent \Attributes \Scope as LocalScope ;
16+ use Illuminate \Database \Eloquent \Attributes \UseEloquentBuilder ;
1617use Illuminate \Database \Eloquent \Collection as EloquentCollection ;
1718use Illuminate \Database \Eloquent \Relations \BelongsToMany ;
1819use Illuminate \Database \Eloquent \Relations \Concerns \AsPivot ;
2627use JsonException ;
2728use JsonSerializable ;
2829use LogicException ;
30+ use ReflectionClass ;
2931use ReflectionMethod ;
3032use Stringable ;
3133
@@ -1651,9 +1653,30 @@ public function newQueryForRestoration($ids)
16511653 */
16521654 public function newEloquentBuilder ($ query )
16531655 {
1656+ $ builderClass = $ this ->resolveCustomBuilderClass ();
1657+
1658+ if ($ builderClass && is_subclass_of ($ builderClass , Builder::class)) {
1659+ return new $ builderClass ($ query );
1660+ }
1661+
16541662 return new static::$ builder ($ query );
16551663 }
16561664
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+
16571680 /**
16581681 * Get a new query builder instance for the connection.
16591682 *
Original file line number Diff line number Diff line change @@ -3365,6 +3365,39 @@ public function testUseFactoryAttribute()
33653365 $ this ->assertEquals (EloquentModelWithUseFactoryAttribute::class, $ factory ->modelName ());
33663366 $ this ->assertEquals ('test name ' , $ instance ->name ); // Small smoke test to ensure the factory is working
33673367 }
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+ {
33683401}
33693402
33703403class EloquentTestObserverStub
You can’t perform that action at this time.
0 commit comments