Skip to content

Commit b8018a2

Browse files
authored
Merge branch 'master' into numeric-string-on-decimal-casts
2 parents 3b383ed + 7549f58 commit b8018a2

File tree

56 files changed

+1576
-1413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1576
-1413
lines changed

.github/workflows/run-integration-tests.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,8 @@ jobs:
1919
strategy:
2020
fail-fast: false
2121
matrix:
22-
php: [8.3, 8.2, 8.1]
23-
laravel: [11.*, 10.*]
24-
exclude:
25-
- php: 8.1
26-
laravel: 11.*
22+
php: [8.4, 8.3, 8.2]
23+
laravel: [^11.15]
2724

2825
name: P${{ matrix.php }} - Laravel${{ matrix.laravel }}
2926
steps:

.github/workflows/run-tests.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@ jobs:
2121
fail-fast: false
2222
matrix:
2323
os: [ubuntu-22.04, windows-2019]
24-
php: [8.3, 8.2, 8.1]
25-
laravel: [10.*, 11.*]
24+
php: [8.4, 8.3, 8.2]
25+
laravel: [^11.15]
2626
stability: [prefer-lowest, prefer-stable]
27-
exclude:
28-
- php: 8.1
29-
laravel: 11.*
3027
steps:
3128
- name: Set git to use LF
3229
if: ${{ matrix.os == 'windows-2019' }}

CHANGELOG.md

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

33
All notable changes to this project will be documented in this file.
44

5-
[Next release](https://github.com/barryvdh/laravel-ide-helper/compare/v3.1.0...master)
5+
[Next release](https://github.com/barryvdh/laravel-ide-helper/compare/v3.2.0...master)
6+
--------------
7+
8+
### Changed
9+
- Add support for multiple pivot types when using the same accessor.
10+
- Smarter reset, keep tags that IDE helper doesn't use
11+
- Use `numeric` type on fields with `decimal` casts
12+
13+
14+
2024-10-18, 3.2.0
615
--------------
716

817
### Fixed
918
- Fix type of hashed model property to `string`
1019

1120
### Changed
12-
- Use `numeric` type on fields with `decimal` casts
21+
- Add support for EloquentBuilder generics introduced in Laravel 11.15.
22+
- Drop support for Laravel versions earlier than 11.15.
1323

1424
### Added
1525

26+
- Add support for AsCollection::using and AsEnumCollection::of casts [#1577 / uno-sw](https://github.com/barryvdh/laravel-ide-helper/pull/1577)
27+
1628
2024-07-12, 3.1.0
1729
------------------
1830

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# IDE Helper Generator for Laravel
22

33
[![Tests](https://github.com/barryvdh/laravel-ide-helper/actions/workflows/run-tests.yml/badge.svg)](https://github.com/barryvdh/laravel-ide-helper/actions)
4-
[![Packagist License](https://poser.pugx.org/barryvdh/laravel-ide-helper/license.png)](http://choosealicense.com/licenses/mit/)
5-
[![Latest Stable Version](https://poser.pugx.org/barryvdh/laravel-ide-helper/version.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
6-
[![Total Downloads](https://poser.pugx.org/barryvdh/laravel-ide-helper/d/total.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
4+
[![Packagist License](https://img.shields.io/badge/Licence-MIT-blue)](http://choosealicense.com/licenses/mit/)
5+
[![Latest Stable Version](https://img.shields.io/packagist/v/barryvdh/laravel-ide-helper?label=Stable)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
6+
[![Total Downloads](https://img.shields.io/packagist/dt/barryvdh/laravel-ide-helper?label=Downloads)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
77
[![Fruitcake](https://img.shields.io/badge/Powered%20By-Fruitcake-b2bc35.svg)](https://fruitcake.nl/)
88

99
**Complete PHPDocs, directly from the source**
@@ -169,11 +169,11 @@ php artisan ide-helper:models "App\Models\Post"
169169
* @property \Illuminate\Support\Carbon $updated_at
170170
* @property-read \User $author
171171
* @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
172-
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Post newModelQuery()
173-
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Post newQuery()
174-
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Post query()
175-
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Post whereTitle($value)
176-
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Post forAuthors(\User ...$authors)
172+
* @method static \Illuminate\Database\Eloquent\Builder<static>|\App\Models\Post newModelQuery()
173+
* @method static \Illuminate\Database\Eloquent\Builder<static>|\App\Models\Post newQuery()
174+
* @method static \Illuminate\Database\Eloquent\Builder<static>|\App\Models\Post query()
175+
* @method static \Illuminate\Database\Eloquent\Builder<static>|\App\Models\Post whereTitle($value)
176+
* @method static \Illuminate\Database\Eloquent\Builder<static>|\App\Models\Post forAuthors(\User ...$authors)
177177
* …
178178
*/
179179
```

composer.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,24 @@
2020
}
2121
],
2222
"require": {
23-
"php": "^8.1",
23+
"php": "^8.2",
2424
"ext-json": "*",
25-
"barryvdh/reflection-docblock": "^2.1.1",
25+
"barryvdh/reflection-docblock": "^2.1.2",
2626
"composer/class-map-generator": "^1.0",
27-
"illuminate/console": "^10 || ^11",
28-
"illuminate/database": "^10.38 || ^11",
29-
"illuminate/filesystem": "^10 || ^11",
30-
"illuminate/support": "^10 || ^11",
27+
"illuminate/console": "^11.15",
28+
"illuminate/database": "^11.15",
29+
"illuminate/filesystem": "^11.15",
30+
"illuminate/support": "^11.15",
3131
"nikic/php-parser": "^4.18 || ^5",
3232
"phpdocumentor/type-resolver": "^1.1.0"
3333
},
3434
"require-dev": {
3535
"ext-pdo_sqlite": "*",
3636
"friendsofphp/php-cs-fixer": "^3",
37-
"illuminate/config": "^9 || ^10 || ^11",
38-
"illuminate/view": "^9 || ^10 || ^11",
37+
"illuminate/config": "^11.15",
38+
"illuminate/view": "^11.15",
3939
"mockery/mockery": "^1.4",
40-
"orchestra/testbench": "^8 || ^9",
40+
"orchestra/testbench": "^9.2",
4141
"phpunit/phpunit": "^10.5",
4242
"spatie/phpunit-snapshot-assertions": "^4 || ^5",
4343
"vimeo/psalm": "^5.4"
@@ -65,7 +65,7 @@
6565
},
6666
"extra": {
6767
"branch-alias": {
68-
"dev-master": "3.1-dev"
68+
"dev-master": "3.2-dev"
6969
},
7070
"laravel": {
7171
"providers": [

src/Console/ModelsCommand.php

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ protected function getOptions()
219219
],
220220
['nowrite', 'N', InputOption::VALUE_NONE, 'Don\'t write to Model file'],
221221
['reset', 'R', InputOption::VALUE_NONE, 'Remove the original phpdocs instead of appending'],
222-
['smart-reset', 'r', InputOption::VALUE_NONE, 'Refresh the properties/methods list, but keep the text'],
222+
['smart-reset', 'r', InputOption::VALUE_NONE, 'Retained for compatibility, while it no longer has any effect'],
223223
['phpstorm-noinspections', 'p', InputOption::VALUE_NONE,
224224
'Add PhpFullyQualifiedNameUsageInspection and PhpUnnecessaryFullyQualifiedNameInspection PHPStorm ' .
225225
'noinspection tags',
@@ -412,8 +412,6 @@ public function castPropertiesType($model)
412412
case 'immutable_datetime':
413413
$realType = '\Carbon\CarbonImmutable';
414414
break;
415-
case AsCollection::class:
416-
case AsEnumCollection::class:
417415
case 'collection':
418416
$realType = '\Illuminate\Support\Collection';
419417
break;
@@ -439,6 +437,18 @@ public function castPropertiesType($model)
439437
continue;
440438
}
441439

440+
if (Str::startsWith($type, AsCollection::class)) {
441+
$realType = $this->getTypeInModel($model, $params[0] ?? null) ?? '\Illuminate\Support\Collection';
442+
}
443+
444+
if (Str::startsWith($type, AsEnumCollection::class)) {
445+
$realType = '\Illuminate\Support\Collection';
446+
$relatedModel = $this->getTypeInModel($model, $params[0] ?? null);
447+
if ($relatedModel) {
448+
$realType = $this->getCollectionTypeHint($realType, $relatedModel);
449+
}
450+
}
451+
442452
$realType = $this->checkForCastableCasts($realType, $params);
443453
$realType = $this->checkForCustomLaravelCasts($realType);
444454
$realType = $this->getTypeOverride($realType);
@@ -555,7 +565,7 @@ public function getPropertiesFromTable($model)
555565
$this->setMethod(
556566
Str::camel('where_' . $name),
557567
$this->getClassNameInDestinationFile($model, $builderClass)
558-
. '|'
568+
. '<static>|'
559569
. $this->getClassNameInDestinationFile($model, get_class($model)),
560570
['$value']
561571
);
@@ -634,14 +644,14 @@ public function getPropertiesFromMethods($model)
634644
new ReflectionClass($model),
635645
get_class($model)
636646
);
637-
$this->setMethod($name, $builder . '|' . $modelName, $args, $comment);
647+
$this->setMethod($name, $builder . '<static>|' . $modelName, $args, $comment);
638648
}
639649
} elseif (in_array($method, ['query', 'newQuery', 'newModelQuery'])) {
640650
$builder = $this->getClassNameInDestinationFile($model, get_class($model->newModelQuery()));
641651

642652
$this->setMethod(
643653
$method,
644-
$builder . '|' . $this->getClassNameInDestinationFile($model, get_class($model))
654+
$builder . '<static>|' . $this->getClassNameInDestinationFile($model, get_class($model))
645655
);
646656

647657
if ($this->write_model_external_builder_methods) {
@@ -716,14 +726,25 @@ public function getPropertiesFromMethods($model)
716726
if ($relationObj instanceof BelongsToMany) {
717727
$pivot = get_class($relationObj->newPivot());
718728
if (!in_array($pivot, [Pivot::class, MorphPivot::class])) {
729+
$pivot = $this->getClassNameInDestinationFile($model, $pivot);
730+
731+
if ($existingPivot = ($this->properties[$relationObj->getPivotAccessor()] ?? null)) {
732+
// If the pivot is already set, we need to append the type to it
733+
$pivot .= '|' . $existingPivot['type'];
734+
} else {
735+
// pivots are not always set
736+
$pivot .= '|null';
737+
}
738+
719739
$this->setProperty(
720740
$relationObj->getPivotAccessor(),
721-
$this->getClassNameInDestinationFile($model, $pivot),
741+
$pivot,
722742
true,
723743
false
724744
);
725745
}
726746
}
747+
727748
//Collection or array of models (because Collection is Arrayable)
728749
$relatedClass = '\\' . get_class($relationObj->getRelated());
729750
$collectionClass = $this->getCollectionClass($relatedClass);
@@ -907,7 +928,7 @@ public function getMethodType(Model $model, string $classType)
907928
{
908929
$modelName = $this->getClassNameInDestinationFile($model, get_class($model));
909930
$builder = $this->getClassNameInDestinationFile($model, $classType);
910-
return $builder . '|' . $modelName;
931+
return $builder . '<static>|' . $modelName;
911932
}
912933

913934
/**
@@ -926,13 +947,19 @@ protected function createPhpDocs($class)
926947
$reflection->getParentClass()->getInterfaceNames()
927948
);
928949

950+
$phpdoc = new DocBlock($reflection, new Context($namespace));
929951
if ($this->reset) {
930-
$phpdoc = new DocBlock('', new Context($namespace));
931952
$phpdoc->setText(
932953
(new DocBlock($reflection, new Context($namespace)))->getText()
933954
);
934-
} else {
935-
$phpdoc = new DocBlock($reflection, new Context($namespace));
955+
foreach ($phpdoc->getTags() as $tag) {
956+
if (
957+
in_array($tag->getName(), ['property', 'property-read', 'property-write', 'method', 'mixin'])
958+
|| ($tag->getName() === 'noinspection' && in_array($tag->getContent(), ['PhpUnnecessaryFullyQualifiedNameInspection', 'PhpFullyQualifiedNameUsageInspection']))
959+
) {
960+
$phpdoc->deleteTag($tag);
961+
}
962+
}
936963
}
937964

938965
$properties = [];
@@ -1322,9 +1349,9 @@ protected function getSoftDeleteMethods($model)
13221349
if (in_array('Illuminate\\Database\\Eloquent\\SoftDeletes', $traits)) {
13231350
$modelName = $this->getClassNameInDestinationFile($model, get_class($model));
13241351
$builder = $this->getClassNameInDestinationFile($model, \Illuminate\Database\Eloquent\Builder::class);
1325-
$this->setMethod('withTrashed', $builder . '|' . $modelName, []);
1326-
$this->setMethod('withoutTrashed', $builder . '|' . $modelName, []);
1327-
$this->setMethod('onlyTrashed', $builder . '|' . $modelName, []);
1352+
$this->setMethod('withTrashed', $builder . '<static>|' . $modelName, []);
1353+
$this->setMethod('withoutTrashed', $builder . '<static>|' . $modelName, []);
1354+
$this->setMethod('onlyTrashed', $builder . '<static>|' . $modelName, []);
13281355
}
13291356
}
13301357

@@ -1528,7 +1555,7 @@ protected function writeModelExternalBuilderMethods(Model $model): void
15281555

15291556
$this->setMethod(
15301557
$builderMethod,
1531-
$builderClassBasedOnFQCNOption . '|' . $this->getClassNameInDestinationFile($model, get_class($model)),
1558+
$builderClassBasedOnFQCNOption . '<static>|' . $this->getClassNameInDestinationFile($model, get_class($model)),
15321559
$args
15331560
);
15341561
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AdvancedCasts\Collections;
6+
7+
use Illuminate\Support\Collection;
8+
9+
class AdvancedCastCollection extends Collection
10+
{
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AdvancedCasts\Enums;
6+
7+
enum AdvancedCastEnum
8+
{
9+
case apple;
10+
case banana;
11+
case orange;
12+
}

tests/Console/ModelsCommand/AdvancedCasts/Models/AdvancedCast.php

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,35 @@
44

55
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AdvancedCasts\Models;
66

7+
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AdvancedCasts\Collections\AdvancedCastCollection;
8+
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AdvancedCasts\Enums\AdvancedCastEnum;
79
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
810
use Illuminate\Database\Eloquent\Casts\AsCollection;
911
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;
1012
use Illuminate\Database\Eloquent\Model;
1113

1214
class AdvancedCast extends Model
1315
{
14-
protected $casts = [
15-
'cast_to_date_serialization' => 'date:Y-m-d',
16-
'cast_to_datetime_serialization' => 'datetime:Y-m-d H:i:s',
17-
'cast_to_custom_datetime' => 'custom_datetime:Y-m-d H:i:s',
18-
'cast_to_immutable_date' => 'immutable_date',
19-
'cast_to_immutable_custom_datetime' => 'immutable_custom_datetime:Y-m-d H:i:s',
20-
'cast_to_immutable_datetime' => 'immutable_datetime',
21-
'cast_to_timestamp' => 'timestamp',
22-
'cast_to_encrypted' => 'encrypted',
23-
'cast_to_encrypted_array' => 'encrypted:array',
24-
'cast_to_encrypted_collection' => 'encrypted:collection',
25-
'cast_to_encrypted_json' => 'encrypted:json',
26-
'cast_to_encrypted_object' => 'encrypted:object',
27-
'cast_to_as_collection' => AsCollection::class,
28-
'cast_to_as_enum_collection' => AsEnumCollection::class,
29-
'cast_to_as_array_object' => AsArrayObject::class,
30-
];
16+
protected function casts(): array
17+
{
18+
return [
19+
'cast_to_date_serialization' => 'date:Y-m-d',
20+
'cast_to_datetime_serialization' => 'datetime:Y-m-d H:i:s',
21+
'cast_to_custom_datetime' => 'custom_datetime:Y-m-d H:i:s',
22+
'cast_to_immutable_date' => 'immutable_date',
23+
'cast_to_immutable_custom_datetime' => 'immutable_custom_datetime:Y-m-d H:i:s',
24+
'cast_to_immutable_datetime' => 'immutable_datetime',
25+
'cast_to_timestamp' => 'timestamp',
26+
'cast_to_encrypted' => 'encrypted',
27+
'cast_to_encrypted_array' => 'encrypted:array',
28+
'cast_to_encrypted_collection' => 'encrypted:collection',
29+
'cast_to_encrypted_json' => 'encrypted:json',
30+
'cast_to_encrypted_object' => 'encrypted:object',
31+
'cast_to_as_collection' => AsCollection::class,
32+
'cast_to_as_collection_using' => AsCollection::using(AdvancedCastCollection::class),
33+
'cast_to_as_enum_collection' => AsEnumCollection::class,
34+
'cast_to_as_enum_collection_of' => AsEnumCollection::of(AdvancedCastEnum::class),
35+
'cast_to_as_array_object' => AsArrayObject::class,
36+
];
37+
}
3138
}

0 commit comments

Comments
 (0)