From ee9188acf125efb495d90b196b474c2103e45389 Mon Sep 17 00:00:00 2001 From: Jefemy Date: Sun, 22 May 2022 14:07:54 -0400 Subject: [PATCH] Implement new config to specify return type of custom relations (#1300) * Implement new config to specify return type of custom relations * Apply suggestions from code review Co-authored-by: Markus Podar * add test for morphed * fix test output * add info about how to add custom relationships * fix wording Co-authored-by: Markus Podar --- CHANGELOG.md | 1 + README.md | 20 +++++++++++ config/ide-helper.php | 13 +++++++ src/Console/ModelsCommand.php | 18 ++++++++-- .../ModelsCommand/Relations/Models/Simple.php | 10 ++++++ .../Console/ModelsCommand/Relations/Test.php | 8 +++++ .../Relations/Traits/HasTestRelations.php | 14 ++++++++ .../Types/SampleToAnyMorphedRelationType.php | 36 +++++++++++++++++++ .../Types/SampleToAnyRelationType.php | 36 +++++++++++++++++++ .../Relations/__snapshots__/Test__test__1.php | 13 +++++++ 10 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 tests/Console/ModelsCommand/Relations/Types/SampleToAnyMorphedRelationType.php create mode 100644 tests/Console/ModelsCommand/Relations/Types/SampleToAnyRelationType.php diff --git a/CHANGELOG.md b/CHANGELOG.md index a2f51d5..96f709b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ All notable changes to this project will be documented in this file. ### Added - Add support for custom casts that using `Castable` [#1287 / binotaliu](https://github.com/barryvdh/laravel-ide-helper/pull/1287) - Added Laravel 9 support [#1297 / rcerljenko](https://github.com/barryvdh/laravel-ide-helper/pull/1297) +- Added option `additional_relation_return_types` for custom relations that don't fit the typical naming scheme 2022-01-03, 2.11.0 ------------------ diff --git a/README.md b/README.md index 9e651b4..73e1201 100644 --- a/README.md +++ b/README.md @@ -281,6 +281,26 @@ For those special cases, you can map them via the config `custom_db_types`. Exam ], ``` +#### Custom Relationship Types + +If you are using relationships not built into Laravel you will need to specify the name and returning class in the config to get proper generation. + +```php +'additional_relation_types' => [ + 'externalHasMany' => \My\Package\externalHasMany::class +], +``` + +Found relationships will typically generate a return value based on the name of the relationship. + +If your custom relationships don't follow this traditional naming scheme you can define its return type manually. The available options are `many` and `morphTo`. + +```php +'additional_relation_return_types' => [ + 'externalHasMultiple' => 'many' +], +``` + #### Model Hooks If you need additional information on your model from sources that are not handled by default, you can hook in to the diff --git a/config/ide-helper.php b/config/ide-helper.php index 51fcdf2..f9110aa 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -304,6 +304,19 @@ return [ */ 'additional_relation_types' => [], + /* + |-------------------------------------------------------------------------- + | Additional relation return types + |-------------------------------------------------------------------------- + | + | When using custom relation types its possible for the class name to not contain + | the proper return type of the relation. The key of the array is the relationship + | method name. The value of the array is the return type of the relation. + | e.g. `'relationName' => 'many'`. + | + */ + 'additional_relation_return_types' => [], + /* |-------------------------------------------------------------------------- | Run artisan commands after migrations to generate model helpers diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index fd8dd01..cd4f89f 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -702,7 +702,10 @@ class ModelsCommand extends Command get_class($relationObj->getRelated()) ); - if (strpos(get_class($relationObj), 'Many') !== false) { + if ( + strpos(get_class($relationObj), 'Many') !== false || + ($this->getRelationReturnTypes()[$relation] ?? '') === 'many' + ) { //Collection or array of models (because Collection is Arrayable) $relatedClass = '\\' . get_class($relationObj->getRelated()); $collectionClass = $this->getCollectionClass($relatedClass); @@ -726,7 +729,10 @@ class ModelsCommand extends Command // What kind of comments should be added to the relation count here? ); } - } elseif ($relation === 'morphTo') { + } elseif ( + $relation === 'morphTo' || + ($this->getRelationReturnTypes()[$relation] ?? '') === 'morphTo' + ) { // Model isn't specified because relation is polymorphic $this->setProperty( $method, @@ -1074,6 +1080,14 @@ class ModelsCommand extends Command return array_merge(self::RELATION_TYPES, $configuredRelations); } + /** + * Returns the return types of relations + */ + protected function getRelationReturnTypes(): array + { + return $this->laravel['config']->get('ide-helper.additional_relation_return_types', []); + } + /** * @return bool */ diff --git a/tests/Console/ModelsCommand/Relations/Models/Simple.php b/tests/Console/ModelsCommand/Relations/Models/Simple.php index dc9e01e..12e8c87 100644 --- a/tests/Console/ModelsCommand/Relations/Models/Simple.php +++ b/tests/Console/ModelsCommand/Relations/Models/Simple.php @@ -97,4 +97,14 @@ class Simple extends Model { return $this->testToManyRelation(Simple::class); } + + public function relationSampleToAnyRelationType() + { + return $this->testToAnyRelation(Simple::class); + } + + public function relationSampleToAnyMorphedRelationType() + { + return $this->testToAnyMorphedRelation(Simple::class); + } } diff --git a/tests/Console/ModelsCommand/Relations/Test.php b/tests/Console/ModelsCommand/Relations/Test.php index 2d1456a..fd94d23 100644 --- a/tests/Console/ModelsCommand/Relations/Test.php +++ b/tests/Console/ModelsCommand/Relations/Test.php @@ -6,6 +6,7 @@ namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations; use Barryvdh\LaravelIdeHelper\Console\ModelsCommand; use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand; +use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyRelationType; use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToManyRelationType; use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToOneRelationType; use Illuminate\Support\Facades\Config; @@ -19,6 +20,13 @@ class Test extends AbstractModelsCommand Config::set('ide-helper.additional_relation_types', [ 'testToOneRelation' => SampleToOneRelationType::class, 'testToManyRelation' => SampleToManyRelationType::class, + 'testToAnyRelation' => SampleToAnyRelationType::class, + 'testToAnyMorphedRelation' => SampleToAnyMorphedRelationType::class, + ]); + + Config::set('ide-helper.additional_relation_return_types', [ + 'testToAnyRelation' => 'many', + 'testToAnyMorphedRelation' => 'morphTo', ]); } diff --git a/tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php b/tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php index d82d60c..49058e6 100644 --- a/tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php +++ b/tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Traits; +use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyRelationType; +use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyMorphedRelationType; use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToManyRelationType; use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToOneRelationType; @@ -20,4 +22,16 @@ trait HasTestRelations $instance = $this->newRelatedInstance($related); return new SampleToManyRelationType($instance->newQuery(), $this); } + + public function testToAnyRelation($related) + { + $instance = $this->newRelatedInstance($related); + return new SampleToAnyRelationType($instance->newQuery(), $this); + } + + public function testToAnyMorphedRelation($related) + { + $instance = $this->newRelatedInstance($related); + return new SampleToAnyMorphedRelationType($instance->newQuery(), $this); + } } diff --git a/tests/Console/ModelsCommand/Relations/Types/SampleToAnyMorphedRelationType.php b/tests/Console/ModelsCommand/Relations/Types/SampleToAnyMorphedRelationType.php new file mode 100644 index 0000000..f3a8ee1 --- /dev/null +++ b/tests/Console/ModelsCommand/Relations/Types/SampleToAnyMorphedRelationType.php @@ -0,0 +1,36 @@ +testToManyRelation(Simple::class); } + + public function relationSampleToAnyRelationType() + { + return $this->testToAnyRelation(Simple::class); + } + + public function relationSampleToAnyMorphedRelationType() + { + return $this->testToAnyMorphedRelation(Simple::class); + } }