Skip to content

Commit

Permalink
feat: add builder and relation generics
Browse files Browse the repository at this point in the history
  • Loading branch information
calebdw committed Jun 20, 2024
1 parent 83e28d0 commit 90b5bd0
Show file tree
Hide file tree
Showing 40 changed files with 1,794 additions and 1,564 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
"nyholm/psr7": "^1.2",
"orchestra/testbench-core": "^10.0",
"pda/pheanstalk": "^5.0",
"phpstan/phpstan": "^1.4.7",
"phpstan/phpstan": "^1.11.5",
"phpunit/phpunit": "^10.5|^11.0",
"predis/predis": "^2.0.2",
"resend/resend-php": "^0.10.0",
Expand Down
12 changes: 7 additions & 5 deletions src/Illuminate/Auth/EloquentUserProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class EloquentUserProvider implements UserProvider
/**
* The callback that may modify the user retrieval queries.
*
* @var (\Closure(\Illuminate\Database\Eloquent\Builder):mixed)|null
* @var (\Closure(\Illuminate\Database\Eloquent\Builder<*>):mixed)|null
*/
protected $queryCallback;

Expand Down Expand Up @@ -177,8 +177,10 @@ public function rehashPasswordIfRequired(UserContract $user, array $credentials,
/**
* Get a new query builder for the model instance.
*
* @param \Illuminate\Database\Eloquent\Model|null $model
* @return \Illuminate\Database\Eloquent\Builder
* @template TModel of \Illuminate\Database\Eloquent\Model
*
* @param TModel|null $model
* @return \Illuminate\Database\Eloquent\Builder<TModel>
*/
protected function newModelQuery($model = null)
{
Expand Down Expand Up @@ -252,7 +254,7 @@ public function setModel($model)
/**
* Get the callback that modifies the query before retrieving users.
*
* @return \Closure|null
* @param (\Closure(\Illuminate\Database\Eloquent\Builder<*>):mixed)|null
*/
public function getQueryCallback()
{
Expand All @@ -262,7 +264,7 @@ public function getQueryCallback()
/**
* Sets the callback to modify the query before retrieving users.
*
* @param (\Closure(\Illuminate\Database\Eloquent\Builder):mixed)|null $queryCallback
* @param (\Closure(\Illuminate\Database\Eloquent\Builder<*>):mixed)|null $queryCallback
* @return $this
*/
public function withQuery($queryCallback = null)
Expand Down
12 changes: 9 additions & 3 deletions src/Illuminate/Database/Concerns/BuildsQueries.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
use InvalidArgumentException;
use RuntimeException;

/**
* @template TValue
*
* @mixin \Illuminate\Database\Eloquent\Builder
* @mixin \Illuminate\Database\Query\Builder
*/
trait BuildsQueries
{
use Conditionable;
Expand Down Expand Up @@ -328,7 +334,7 @@ protected function orderedLazyById($chunkSize = 1000, $column = null, $alias = n
* Execute the query and get the first result.
*
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model|object|static|null
* @return TValue|null
*/
public function first($columns = ['*'])
{
Expand All @@ -339,7 +345,7 @@ public function first($columns = ['*'])
* Execute the query and get the first result if it's the sole matching record.
*
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model|object|static|null
* @return TValue
*
* @throws \Illuminate\Database\RecordsNotFoundException
* @throws \Illuminate\Database\MultipleRecordsFoundException
Expand Down Expand Up @@ -463,7 +469,7 @@ protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName =
/**
* Get the original column name of the given column, without any aliasing.
*
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder<*> $builder
* @param string $parameter
* @return string
*/
Expand Down
77 changes: 41 additions & 36 deletions src/Illuminate/Database/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
use ReflectionMethod;

/**
* @template TModel of \Illuminate\Database\Eloquent\Model
*
* @property-read HigherOrderBuilderProxy $orWhere
* @property-read HigherOrderBuilderProxy $whereNot
* @property-read HigherOrderBuilderProxy $orWhereNot
Expand All @@ -31,6 +33,7 @@
*/
class Builder implements BuilderContract
{
/** @use \Illuminate\Database\Concerns\BuildsQueries<TModel> */
use BuildsQueries, ForwardsCalls, QueriesRelationships {
BuildsQueries::sole as baseSole;
}
Expand All @@ -45,7 +48,7 @@ class Builder implements BuilderContract
/**
* The model being queried.
*
* @var \Illuminate\Database\Eloquent\Model
* @var TModel
*/
protected $model;

Expand Down Expand Up @@ -160,7 +163,7 @@ public function __construct(QueryBuilder $query)
* Create and return an un-saved model instance.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function make(array $attributes = [])
{
Expand Down Expand Up @@ -320,7 +323,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
* @param mixed $operator
* @param mixed $value
* @param string $boolean
* @return \Illuminate\Database\Eloquent\Model|static|null
* @return TModel|null
*/
public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')
{
Expand Down Expand Up @@ -409,7 +412,7 @@ public function oldest($column = null)
* Create a collection of models from plain arrays.
*
* @param array $items
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Collection<int, TModel>
*/
public function hydrate(array $items)
{
Expand All @@ -431,7 +434,7 @@ public function hydrate(array $items)
*
* @param string $query
* @param array $bindings
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Collection<int, TModel>
*/
public function fromQuery($query, $bindings = [])
{
Expand All @@ -445,7 +448,7 @@ public function fromQuery($query, $bindings = [])
*
* @param mixed $id
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null
* @return TModel|\Illuminate\Database\Eloquent\Collection<int, TModel>|null
*/
public function find($id, $columns = ['*'])
{
Expand All @@ -461,7 +464,7 @@ public function find($id, $columns = ['*'])
*
* @param \Illuminate\Contracts\Support\Arrayable|array $ids
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Collection<int, TModel>
*/
public function findMany($ids, $columns = ['*'])
{
Expand All @@ -479,9 +482,9 @@ public function findMany($ids, $columns = ['*'])
*
* @param mixed $id
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static|static[]
* @return TModel|\Illuminate\Database\Eloquent\Collection<int, TModel>
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<TModel>
*/
public function findOrFail($id, $columns = ['*'])
{
Expand Down Expand Up @@ -513,7 +516,7 @@ public function findOrFail($id, $columns = ['*'])
*
* @param mixed $id
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function findOrNew($id, $columns = ['*'])
{
Expand All @@ -530,7 +533,7 @@ public function findOrNew($id, $columns = ['*'])
* @param mixed $id
* @param \Closure|array|string $columns
* @param \Closure|null $callback
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|mixed
* @return TModel|\Illuminate\Database\Eloquent\Collection<int, TModel>|mixed
*/
public function findOr($id, $columns = ['*'], ?Closure $callback = null)
{
Expand All @@ -552,7 +555,7 @@ public function findOr($id, $columns = ['*'], ?Closure $callback = null)
*
* @param array $attributes
* @param array $values
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function firstOrNew(array $attributes = [], array $values = [])
{
Expand All @@ -568,7 +571,7 @@ public function firstOrNew(array $attributes = [], array $values = [])
*
* @param array $attributes
* @param array $values
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function firstOrCreate(array $attributes = [], array $values = [])
{
Expand All @@ -584,7 +587,7 @@ public function firstOrCreate(array $attributes = [], array $values = [])
*
* @param array $attributes
* @param array $values
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function createOrFirst(array $attributes = [], array $values = [])
{
Expand All @@ -600,7 +603,7 @@ public function createOrFirst(array $attributes = [], array $values = [])
*
* @param array $attributes
* @param array $values
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function updateOrCreate(array $attributes, array $values = [])
{
Expand All @@ -615,9 +618,9 @@ public function updateOrCreate(array $attributes, array $values = [])
* Execute the query and get the first result or throw an exception.
*
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<TModel>
*/
public function firstOrFail($columns = ['*'])
{
Expand All @@ -633,7 +636,7 @@ public function firstOrFail($columns = ['*'])
*
* @param \Closure|array|string $columns
* @param \Closure|null $callback
* @return \Illuminate\Database\Eloquent\Model|static|mixed
* @return TModel|mixed
*/
public function firstOr($columns = ['*'], ?Closure $callback = null)
{
Expand All @@ -654,9 +657,9 @@ public function firstOr($columns = ['*'], ?Closure $callback = null)
* Execute the query and get the first result if it's the sole matching record.
*
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model
* @return TModel
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<TModel>
* @throws \Illuminate\Database\MultipleRecordsFoundException
*/
public function sole($columns = ['*'])
Expand Down Expand Up @@ -689,7 +692,7 @@ public function value($column)
* @param string|\Illuminate\Contracts\Database\Query\Expression $column
* @return mixed
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<TModel>
* @throws \Illuminate\Database\MultipleRecordsFoundException
*/
public function soleValue($column)
Expand All @@ -705,7 +708,7 @@ public function soleValue($column)
* @param string|\Illuminate\Contracts\Database\Query\Expression $column
* @return mixed
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model>
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<TModel>
*/
public function valueOrFail($column)
{
Expand All @@ -718,7 +721,7 @@ public function valueOrFail($column)
* Execute the query as a "select" statement.
*
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Collection|static[]
* @return \Illuminate\Database\Eloquent\Collection<int, TModel>
*/
public function get($columns = ['*'])
{
Expand All @@ -740,7 +743,7 @@ public function get($columns = ['*'])
* Get the hydrated models without eager loading.
*
* @param array|string $columns
* @return \Illuminate\Database\Eloquent\Model[]|static[]
* @return array<int, TModel>
*/
public function getModels($columns = ['*'])
{
Expand All @@ -752,8 +755,8 @@ public function getModels($columns = ['*'])
/**
* Eager load the relationships for the models.
*
* @param array $models
* @return array
* @param array<int, TModel> $models
* @return array<int, TModel>
*/
public function eagerLoadRelations(array $models)
{
Expand Down Expand Up @@ -801,7 +804,7 @@ protected function eagerLoadRelation(array $models, $name, Closure $constraints)
* Get the relation instance for the given relation name.
*
* @param string $name
* @return \Illuminate\Database\Eloquent\Relations\Relation
* @return \Illuminate\Database\Eloquent\Relations\Relation<\Illuminate\Database\Eloquent\Model, TModel, *>
*/
public function getRelation($name)
{
Expand Down Expand Up @@ -893,7 +896,7 @@ public function applyAfterQueryCallbacks($result)
/**
* Get a lazy collection for the given query.
*
* @return \Illuminate\Support\LazyCollection
* @return \Illuminate\Support\LazyCollection<int, TModel>
*/
public function cursor()
{
Expand Down Expand Up @@ -921,7 +924,7 @@ protected function enforceOrderBy()
*
* @param string|\Illuminate\Contracts\Database\Query\Expression $column
* @param string|null $key
* @return \Illuminate\Support\Collection
* @return \Illuminate\Support\Collection<int|string, mixed>
*/
public function pluck($column, $key = null)
{
Expand Down Expand Up @@ -1060,7 +1063,7 @@ protected function ensureOrderForCursorPagination($shouldReverse = false)
* Save a new model and return the instance.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|$this
* @return TModel
*/
public function create(array $attributes = [])
{
Expand All @@ -1073,7 +1076,7 @@ public function create(array $attributes = [])
* Save a new model and return the instance. Allow mass-assignment.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|$this
* @return TModel
*/
public function forceCreate(array $attributes)
{
Expand All @@ -1086,7 +1089,7 @@ public function forceCreate(array $attributes)
* Save a new model instance with mass assignment without raising model events.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|$this
* @return TModel
*/
public function forceCreateQuietly(array $attributes = [])
{
Expand Down Expand Up @@ -1575,7 +1578,7 @@ public function withOnly($relations)
* Create a new instance of the model being queried.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function newModelInstance($attributes = [])
{
Expand Down Expand Up @@ -1875,7 +1878,7 @@ protected function defaultKeyName()
/**
* Get the model instance being queried.
*
* @return \Illuminate\Database\Eloquent\Model|static
* @return TModel
*/
public function getModel()
{
Expand All @@ -1885,8 +1888,10 @@ public function getModel()
/**
* Set a model instance for the model being queried.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return $this
* @template TModelNew of \Illuminate\Database\Eloquent\Model
*
* @param TModelNew $model
* @return static<TModelNew>
*/
public function setModel(Model $model)
{
Expand Down
Loading

0 comments on commit 90b5bd0

Please sign in to comment.