Skip to content

Commit

Permalink
Created a positiblity to add custom relation type (#987)
Browse files Browse the repository at this point in the history
* Created a positiblity to add custom relation type

* Changed access modifier

Co-authored-by: Markus Podar <[email protected]>

* fixed hints from code review

* Added Test for barryvdh/laravel-ide-helper#987

* composer fix-style

* Clarify doc in config entry

* Update CHANGELOG.md

Co-authored-by: Markus Podar <[email protected]>
  • Loading branch information
fatihdirikman and mfn committed Sep 8, 2020
1 parent abd42e7 commit 115a3ec
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----------------
Expand Down
13 changes: 13 additions & 0 deletions config/ide-helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,17 @@
|
*/
'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' => [],

];
55 changes: 34 additions & 21 deletions src/Console/ModelsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
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;
Expand All @@ -36,6 +46,20 @@
*/
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
*/
Expand Down Expand Up @@ -561,19 +585,7 @@ protected function getPropertiesFromMethods($model)
$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, '\\')) {
Expand All @@ -600,14 +612,6 @@ protected function getPropertiesFromMethods($model)
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());
Expand Down Expand Up @@ -929,6 +933,15 @@ protected function getCollectionClass($className)
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
*/
Expand Down
13 changes: 13 additions & 0 deletions tests/Console/ModelsCommand/Relations/Models/Simple.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;
Expand All @@ -17,6 +18,8 @@

class Simple extends Model
{
use HasTestRelations;

// Regular relations
public function relationHasMany(): HasMany
{
Expand Down Expand Up @@ -84,4 +87,14 @@ public function relationBelongsToSameNameAsColumn(): BelongsTo
{
return $this->belongsTo(AnotherModel::class, __FUNCTION__);
}

public function relationSampleToManyRelationType()
{
return $this->testToOneRelation(Simple::class);
}

public function relationSampleRelationType()
{
return $this->testToManyRelation(Simple::class);
}
}
13 changes: 13 additions & 0 deletions tests/Console/ModelsCommand/Relations/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,22 @@

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);
Expand Down
23 changes: 23 additions & 0 deletions tests/Console/ModelsCommand/Relations/Traits/HasTestRelations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Traits;

use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToManyRelationType;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToOneRelationType;

trait HasTestRelations
{
public function testToOneRelation($related)
{
$instance = $this->newRelatedInstance($related);
return new SampleToOneRelationType($instance->newQuery(), $this);
}

public function testToManyRelation($related)
{
$instance = $this->newRelatedInstance($related);
return new SampleToManyRelationType($instance->newQuery(), $this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\Relation;

class SampleToManyRelationType extends Relation
{
public function addConstraints()
{
// Fake
}

public function addEagerConstraints(array $models)
{
// Fake
}

public function initRelation(array $models, $relation)
{
// Fake
}

public function match(array $models, Collection $results, $relation)
{
// Fake
}

public function getResults()
{
// Fake
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Concerns\SupportsDefaultModels;
use Illuminate\Database\Eloquent\Relations\Relation;

/**
* Sample for custom relation
*
* the relation is a big fake and only for testing of the docblock generation
*
* @package Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations
*/
class SampleToOneRelationType extends Relation
{
use SupportsDefaultModels;

public function addConstraints()
{
// Fake
}

public function addEagerConstraints(array $models)
{
// Fake
}

public function initRelation(array $models, $relation)
{
// Fake
}

public function match(array $models, Collection $results, $relation)
{
// Fake
}

public function getResults()
{
// Fake
}

protected function newRelatedInstanceFor(Model $parent)
{
// Fake
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;
Expand Down Expand Up @@ -38,6 +39,9 @@
* @property-read Model|\Eloquent $relationMorphTo
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationMorphedByMany
* @property-read int|null $relation_morphed_by_many_count
* @property-read \Illuminate\Database\Eloquent\Collection|Simple[] $relationSampleRelationType
* @property-read int|null $relation_sample_relation_type_count
* @property-read Simple $relationSampleToManyRelationType
* @method static \Illuminate\Database\Eloquent\Builder|Simple newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Simple query()
Expand All @@ -46,6 +50,8 @@
*/
class Simple extends Model
{
use HasTestRelations;

// Regular relations
public function relationHasMany(): HasMany
{
Expand Down Expand Up @@ -113,4 +119,14 @@ public function relationBelongsToSameNameAsColumn(): BelongsTo
{
return $this->belongsTo(AnotherModel::class, __FUNCTION__);
}

public function relationSampleToManyRelationType()
{
return $this->testToOneRelation(Simple::class);
}

public function relationSampleRelationType()
{
return $this->testToManyRelation(Simple::class);
}
}

0 comments on commit 115a3ec

Please sign in to comment.