-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3963511
commit b7689e2
Showing
35 changed files
with
873 additions
and
486 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Database\Relations; | ||
|
||
use Illuminate\Database\Eloquent\Collection; | ||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Database\Eloquent\Relations\Concerns\SupportsDefaultModels; | ||
use Illuminate\Database\Eloquent\Relations\MorphToMany; | ||
use Illuminate\Support\Arr; | ||
use Override; | ||
|
||
/** | ||
* @template TRelatedModel of Model | ||
* | ||
* @extends MorphToMany<TRelatedModel> | ||
*/ | ||
final class OneOfMorphToMany extends MorphToMany | ||
{ | ||
use SupportsDefaultModels; | ||
|
||
/** | ||
* Match the eagerly loaded results to their parents. | ||
* This method is used when `with` or `load` methods are called. | ||
*/ | ||
#[Override] | ||
public function match(array $models, Collection $results, $relation): array | ||
{ | ||
$dictionary = $this->buildDictionary($results); | ||
|
||
foreach ($models as $model) { | ||
$key = $this->getDictionaryKey($model->{$this->parentKey}); | ||
|
||
// If there are related entries to model, we need to take only first one and set it | ||
if (isset($dictionary[$key])) { | ||
$model->setRelation($relation, Arr::first($dictionary[$key])); | ||
continue; | ||
} | ||
|
||
// If there were no related entries - set default one | ||
$model->setRelation($relation, $this->getDefaultFor($model)); | ||
} | ||
|
||
return $models; | ||
} | ||
|
||
/** | ||
* Get results of the relationship. In the case of `OneOfMorphToMany` it will only get one result. | ||
*/ | ||
#[Override] | ||
public function getResults() | ||
{ | ||
return $this->query->first() ?: $this->getDefaultFor($this->parent); | ||
} | ||
|
||
/** | ||
* Make a new related instance for the given model. | ||
*/ | ||
#[Override] | ||
protected function newRelatedInstanceFor(Model $parent): Model | ||
{ | ||
return $this->related->newInstance() | ||
->setAttribute($this->getForeignPivotKeyName(), $parent->getKey()) | ||
->setAttribute($this->getMorphType(), $this->morphClass); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Models\Concerns; | ||
|
||
use App\Database\Relations\OneOfMorphToMany; | ||
use App\Models\Image; | ||
use Illuminate\Database\Eloquent\Model; | ||
|
||
/** | ||
* @mixin Model | ||
* @property-read Image $image | ||
* @infection-ignore-all | ||
* @codeCoverageIgnore | ||
*/ | ||
trait HasImage | ||
{ | ||
use HasOneOfMorphToManyRelation; | ||
|
||
public function image(): OneOfMorphToMany | ||
{ | ||
return $this->oneOfMorphToMany(Image::class, 'model', 'has_images')->withTimestamps()->withDefault([ | ||
'path' => config('cloudinary.default_image'), | ||
]); | ||
} | ||
|
||
public function attachImage(Image $image): void | ||
{ | ||
$this->detachImage(); | ||
$this->image()->attach($image); | ||
} | ||
|
||
public function detachImage(): void | ||
{ | ||
if ($this->image->is_default) { | ||
return; | ||
} | ||
|
||
$this->image()->detach(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Models\Concerns; | ||
|
||
use App\Database\Relations\OneOfMorphToMany; | ||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Support\Str; | ||
|
||
/** | ||
* @mixin Model | ||
* @infection-ignore-all | ||
* @codeCoverageIgnore | ||
*/ | ||
trait HasOneOfMorphToManyRelation | ||
{ | ||
/** | ||
* Define a polymorphic many-to-many relationship that return only one result. | ||
* Modified version of `morphToMany` method. | ||
* | ||
* @template TRelatedModel of Model | ||
* | ||
* @param class-string<TRelatedModel> $related | ||
* @param string $name | ||
* @param string|null $table | ||
* @param string|null $foreignPivotKey | ||
* @param string|null $relatedPivotKey | ||
* @param string|null $parentKey | ||
* @param string|null $relatedKey | ||
* @param string|null $relation | ||
* @param bool $inverse | ||
* @return OneOfMorphToMany | ||
*/ | ||
public function oneOfMorphToMany( | ||
$related, | ||
string $name, | ||
?string $table = null, | ||
?string $foreignPivotKey = null, | ||
?string $relatedPivotKey = null, | ||
?string $parentKey = null, | ||
?string $relatedKey = null, | ||
?string $relation = null, | ||
bool $inverse = false | ||
): OneOfMorphToMany { | ||
$relation = $relation ?: $this->guessBelongsToManyRelation(); | ||
|
||
$instance = $this->newRelatedInstance($related); | ||
|
||
$foreignPivotKey = $foreignPivotKey ?: $name . '_id'; | ||
|
||
$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey(); | ||
|
||
if (!$table) { | ||
$words = preg_split('/(_)/u', $name, -1, PREG_SPLIT_DELIM_CAPTURE); | ||
|
||
$lastWord = array_pop($words); | ||
|
||
$table = implode('', $words) . Str::plural($lastWord); | ||
} | ||
|
||
return new OneOfMorphToMany( | ||
query : $instance->newQuery(), | ||
parent : $this, | ||
name : $name, | ||
table : $table, | ||
foreignPivotKey: $foreignPivotKey, | ||
relatedPivotKey: $relatedPivotKey, | ||
parentKey : $parentKey ?: $this->getKeyName(), | ||
relatedKey : $relatedKey ?: $instance->getKeyName(), | ||
relationName : $relation, | ||
inverse : $inverse | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.