From 7305504c99c3840c8ef5176eee7f2caad23349e6 Mon Sep 17 00:00:00 2001 From: efinder2 Date: Tue, 8 Sep 2020 07:18:43 +0200 Subject: [PATCH] Created a positiblity to add custom relation type (#987) * Created a positiblity to add custom relation type * Changed access modifier Co-authored-by: Markus Podar * fixed hints from code review * Added Test for https://github.com/barryvdh/laravel-ide-helper/pull/987 * composer fix-style * Clarify doc in config entry * Update CHANGELOG.md Co-authored-by: Markus Podar --- CHANGELOG.md | 1 + config/ide-helper.php | 13 +++++ src/Console/ModelsCommand.php | 55 ++++++++++++------- .../ModelsCommand/Relations/Models/Simple.php | 13 +++++ .../Console/ModelsCommand/Relations/Test.php | 13 +++++ .../Relations/Traits/HasTestRelations.php | 23 ++++++++ .../Types/SampleToManyRelationType.php | 36 ++++++++++++ .../Types/SampleToOneRelationType.php | 52 ++++++++++++++++++ .../Relations/__snapshots__/Test__test__1.php | 16 ++++++ 9 files changed, 201 insertions(+), 21 deletions(-) create mode 100644 tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php create mode 100644 tests/Console/ModelsCommand/Relations/Types/SampleToManyRelationType.php create mode 100644 tests/Console/ModelsCommand/Relations/Types/SampleToOneRelationType.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 78881c2..f71af44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Fix phpdoc generate for custom cast with parameter [\#986 / artelkr](https://github.com/barryvdh/laravel-ide-helper/pull/986) +- Created a possibility to add custom relation type [\#987 / efinder2](https://github.com/barryvdh/laravel-ide-helper/pull/987) 2020-09-07, 2.8.1 ----------------- diff --git a/config/ide-helper.php b/config/ide-helper.php index e287fea..5386130 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -253,4 +253,17 @@ return [ | */ 'force_fqn' => false, + + /* + |-------------------------------------------------------------------------- + | Additional relation types + |-------------------------------------------------------------------------- + | + | Sometimes it's needed to create custom relation types. The key of the array + | is the Relationship Method name. The value of the array is the canonical class + | name of the Relationship, e.g. `'relationName' => RelationShipClass::class`. + | + */ + 'additional_relation_types' => [], + ]; diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index 09526b8..55a845d 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -19,6 +19,16 @@ use Composer\Autoload\ClassMapGenerator; use Illuminate\Console\Command; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; +use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Relations\HasOneThrough; +use Illuminate\Database\Eloquent\Relations\MorphMany; +use Illuminate\Database\Eloquent\Relations\MorphOne; +use Illuminate\Database\Eloquent\Relations\MorphTo; +use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Str; @@ -36,6 +46,20 @@ use Symfony\Component\Console\Output\OutputInterface; */ class ModelsCommand extends Command { + protected const RELATION_TYPES = [ + 'hasMany' => HasMany::class, + 'hasManyThrough' => HasManyThrough::class, + 'hasOneThrough' => HasOneThrough::class, + 'belongsToMany' => BelongsToMany::class, + 'hasOne' => HasOne::class, + 'belongsTo' => BelongsTo::class, + 'morphOne' => MorphOne::class, + 'morphTo' => MorphTo::class, + 'morphMany' => MorphMany::class, + 'morphToMany' => MorphToMany::class, + 'morphedByMany' => MorphToMany::class, + ]; + /** * @var Filesystem $files */ @@ -561,19 +585,7 @@ class ModelsCommand extends Command $code = substr($code, $begin, strrpos($code, '}') - $begin + 1); foreach ( - [ - 'hasMany' => '\Illuminate\Database\Eloquent\Relations\HasMany', - 'hasManyThrough' => '\Illuminate\Database\Eloquent\Relations\HasManyThrough', - 'hasOneThrough' => '\Illuminate\Database\Eloquent\Relations\HasOneThrough', - 'belongsToMany' => '\Illuminate\Database\Eloquent\Relations\BelongsToMany', - 'hasOne' => '\Illuminate\Database\Eloquent\Relations\HasOne', - 'belongsTo' => '\Illuminate\Database\Eloquent\Relations\BelongsTo', - 'morphOne' => '\Illuminate\Database\Eloquent\Relations\MorphOne', - 'morphTo' => '\Illuminate\Database\Eloquent\Relations\MorphTo', - 'morphMany' => '\Illuminate\Database\Eloquent\Relations\MorphMany', - 'morphToMany' => '\Illuminate\Database\Eloquent\Relations\MorphToMany', - 'morphedByMany' => '\Illuminate\Database\Eloquent\Relations\MorphToMany', - ] as $relation => $impl + $this->getRelationTypes() as $relation => $impl ) { $search = '$this->' . $relation . '('; if (stripos($code, $search) || ltrim($impl, '\\') === ltrim((string)$type, '\\')) { @@ -600,14 +612,6 @@ class ModelsCommand extends Command get_class($relationObj->getRelated()) ); - $relations = [ - 'hasManyThrough', - 'belongsToMany', - 'hasMany', - 'morphMany', - 'morphToMany', - 'morphedByMany', - ]; if (strpos(get_class($relationObj), 'Many') !== false) { //Collection or array of models (because Collection is Arrayable) $relatedClass = '\\' . get_class($relationObj->getRelated()); @@ -929,6 +933,15 @@ class ModelsCommand extends Command return '\\' . get_class($model->newCollection()); } + /** + * Returns the available relation types + */ + protected function getRelationTypes(): array + { + $configuredRelations = $this->laravel['config']->get('ide-helper.additional_relation_types', []); + return array_merge(self::RELATION_TYPES, $configuredRelations); + } + /** * @return bool */ diff --git a/tests/Console/ModelsCommand/Relations/Models/Simple.php b/tests/Console/ModelsCommand/Relations/Models/Simple.php index 7c2b5af..dc9e01e 100644 --- a/tests/Console/ModelsCommand/Relations/Models/Simple.php +++ b/tests/Console/ModelsCommand/Relations/Models/Simple.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models; use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\ModelsOtherNamespace\AnotherModel; +use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Traits\HasTestRelations; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; @@ -17,6 +18,8 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany; class Simple extends Model { + use HasTestRelations; + // Regular relations public function relationHasMany(): HasMany { @@ -84,4 +87,14 @@ class Simple extends Model { return $this->belongsTo(AnotherModel::class, __FUNCTION__); } + + public function relationSampleToManyRelationType() + { + return $this->testToOneRelation(Simple::class); + } + + public function relationSampleRelationType() + { + return $this->testToManyRelation(Simple::class); + } } diff --git a/tests/Console/ModelsCommand/Relations/Test.php b/tests/Console/ModelsCommand/Relations/Test.php index 251c936..2d1456a 100644 --- a/tests/Console/ModelsCommand/Relations/Test.php +++ b/tests/Console/ModelsCommand/Relations/Test.php @@ -6,9 +6,22 @@ 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\SampleToManyRelationType; +use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToOneRelationType; +use Illuminate\Support\Facades\Config; class Test extends AbstractModelsCommand { + protected function setUp(): void + { + parent::setUp(); + + Config::set('ide-helper.additional_relation_types', [ + 'testToOneRelation' => SampleToOneRelationType::class, + 'testToManyRelation' => SampleToManyRelationType::class, + ]); + } + public function test(): void { $command = $this->app->make(ModelsCommand::class); diff --git a/tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php b/tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php new file mode 100644 index 0000000..d82d60c --- /dev/null +++ b/tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php @@ -0,0 +1,23 @@ +newRelatedInstance($related); + return new SampleToOneRelationType($instance->newQuery(), $this); + } + + public function testToManyRelation($related) + { + $instance = $this->newRelatedInstance($related); + return new SampleToManyRelationType($instance->newQuery(), $this); + } +} diff --git a/tests/Console/ModelsCommand/Relations/Types/SampleToManyRelationType.php b/tests/Console/ModelsCommand/Relations/Types/SampleToManyRelationType.php new file mode 100644 index 0000000..1225e08 --- /dev/null +++ b/tests/Console/ModelsCommand/Relations/Types/SampleToManyRelationType.php @@ -0,0 +1,36 @@ +belongsTo(AnotherModel::class, __FUNCTION__); } + + public function relationSampleToManyRelationType() + { + return $this->testToOneRelation(Simple::class); + } + + public function relationSampleRelationType() + { + return $this->testToManyRelation(Simple::class); + } }