Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6b4f671

Browse files
committed
Make eloquent builder generic
1 parent 5fa082e commit 6b4f671

File tree

7 files changed

+84
-3
lines changed

7 files changed

+84
-3
lines changed

src/Extensions/StubExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public function getFiles(): array
1717
{
1818
return [
1919
__DIR__ . '/../../stubs/database/eloquent/builder.stub',
20+
__DIR__ . '/../../stubs/database/eloquent/model.stub',
2021
];
2122
}
2223
}

stubs/database/eloquent/builder.stub

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
namespace Illuminate\Database\Eloquent;
44

5+
/**
6+
* @template TModel of \Illuminate\Database\Eloquent\Model
7+
*/
58
class Builder
69
{
710
/**
811
* @param string[]|string $columns
9-
* @return \Illuminate\Database\Eloquent\Model|null
12+
* @return TModel|null
1013
*/
1114
public function first($columns = ['*']);
1215
}

stubs/database/eloquent/model.stub

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Illuminate\Database\Eloquent;
4+
5+
class Model
6+
{
7+
/**
8+
* @param \Illuminate\Database\Query\Builder $query
9+
* @return \Illuminate\Database\Eloquent\Builder<static>
10+
*/
11+
public function newEloquentBuilder($query);
12+
13+
/**
14+
* @return \Illuminate\Database\Eloquent\Builder<static>
15+
*/
16+
public static function query();
17+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Tests\Types\Database\Eloquent;
4+
5+
use PHPStan\Testing\TypeInferenceTestCase;
6+
use PHPUnit\Framework\Attributes\DataProvider;
7+
8+
final class ModelTest extends TypeInferenceTestCase
9+
{
10+
/**
11+
* @return iterable<string, mixed[]>
12+
*/
13+
public static function fileAsserts(): iterable
14+
{
15+
yield from self::gatherAssertTypes(__DIR__ . '/../../data/database/eloquent/model.php');
16+
}
17+
18+
#[DataProvider('fileAsserts')]
19+
public function testFileAsserts(
20+
string $assertType,
21+
string $file,
22+
mixed ...$args
23+
): void {
24+
$this->assertFileAsserts($assertType, $file, ...$args);
25+
}
26+
27+
public static function getAdditionalConfigFiles(): array
28+
{
29+
return [__DIR__ . '/../../../../extension.neon'];
30+
}
31+
}

tests/Types/Fakes/User.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Tests\Types\Fakes;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
final class User extends Model
8+
{
9+
//
10+
}

tests/Types/data/database/eloquent/builder.php

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

33
use function PHPStan\Testing\assertType;
44

5-
/** @var \Illuminate\Database\Eloquent\Builder $builder */
5+
/** @var \Illuminate\Database\Eloquent\Builder<\Tests\Types\Fakes\User> $builder */
66

7-
assertType('Illuminate\Database\Eloquent\Model|null', $builder->first());
7+
assertType('Tests\Types\Fakes\User|null', $builder->first());
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use Illuminate\Database\Eloquent\Model;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class User extends Model
8+
{
9+
public function test(): void
10+
{
11+
/** @var \Illuminate\Database\Query\Builder $baseBuilder */
12+
13+
assertType('Illuminate\Database\Eloquent\Builder<static(User)>', $this->newEloquentBuilder($baseBuilder));
14+
assertType('static(User)|null', $this->newEloquentBuilder($baseBuilder)->first());
15+
16+
assertType('Illuminate\Database\Eloquent\Builder<static(User)>', self::query());
17+
assertType('static(User)|null', self::query()->first());
18+
}
19+
}

0 commit comments

Comments
 (0)