maksimru /
composite-primary-keys
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | namespace MaksimM\CompositePrimaryKeys\Http\Traits; |
||||||
| 4 | |||||||
| 5 | use Closure; |
||||||
| 6 | use Illuminate\Database\Eloquent\Builder; |
||||||
| 7 | use Illuminate\Database\Eloquent\Model; |
||||||
| 8 | use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||||
| 9 | use Illuminate\Database\Eloquent\Relations\BelongsToMany; |
||||||
| 10 | use Illuminate\Database\Eloquent\Relations\HasMany; |
||||||
| 11 | use Illuminate\Database\Eloquent\Relations\HasManyThrough; |
||||||
| 12 | use Illuminate\Database\Eloquent\Relations\HasOne; |
||||||
| 13 | use Illuminate\Database\Eloquent\Relations\MorphMany; |
||||||
| 14 | use Illuminate\Database\Eloquent\Relations\MorphOne; |
||||||
| 15 | use Illuminate\Database\Eloquent\Relations\MorphTo; |
||||||
| 16 | use Illuminate\Database\Eloquent\Relations\MorphToMany; |
||||||
| 17 | use Illuminate\Support\Str; |
||||||
| 18 | use MaksimM\CompositePrimaryKeys\Eloquent\Relationships\CompositeBelongsTo; |
||||||
| 19 | use MaksimM\CompositePrimaryKeys\Eloquent\Relationships\CompositeBelongsToMany; |
||||||
| 20 | |||||||
| 21 | trait CompositeRelationships |
||||||
| 22 | { |
||||||
| 23 | /** |
||||||
| 24 | * @param $related |
||||||
| 25 | * @param null $foreignKey |
||||||
|
0 ignored issues
–
show
Documentation
Bug
introduced
by
Loading history...
|
|||||||
| 26 | * @param null $ownerKey |
||||||
|
0 ignored issues
–
show
|
|||||||
| 27 | * @param null $relation |
||||||
|
0 ignored issues
–
show
|
|||||||
| 28 | * |
||||||
| 29 | * @return BelongsTo |
||||||
| 30 | */ |
||||||
| 31 | public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null) |
||||||
| 32 | { |
||||||
| 33 | // If no relation name was given, we will use this debug backtrace to extract |
||||||
| 34 | // the calling method's name and use that as the relationship name as most |
||||||
| 35 | // of the time this will be what we desire to use for the relationships. |
||||||
| 36 | if (is_null($relation)) { |
||||||
|
0 ignored issues
–
show
|
|||||||
| 37 | $relation = $this->guessBelongsToRelation(); |
||||||
|
0 ignored issues
–
show
It seems like
guessBelongsToRelation() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 38 | } |
||||||
| 39 | |||||||
| 40 | /** |
||||||
| 41 | * @var Model $instance |
||||||
| 42 | */ |
||||||
| 43 | $instance = $this->newRelatedInstance($related); |
||||||
|
0 ignored issues
–
show
It seems like
newRelatedInstance() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 44 | |||||||
| 45 | // If no foreign key was supplied, we can use a backtrace to guess the proper |
||||||
| 46 | // foreign key name by using the name of the relationship function, which |
||||||
| 47 | // when combined with an "_id" should conventionally match the columns. |
||||||
| 48 | if (is_null($foreignKey)) { |
||||||
|
0 ignored issues
–
show
|
|||||||
| 49 | $foreignKey = is_array($instance->getKeyName()) ? array_map( |
||||||
|
0 ignored issues
–
show
|
|||||||
| 50 | function ($key) use ($relation) { |
||||||
| 51 | return Str::snake($relation).'_'.$key; |
||||||
| 52 | }, |
||||||
| 53 | $instance->getKeyName() |
||||||
| 54 | ) : Str::snake($relation).'_'.$instance->getKeyName(); |
||||||
| 55 | } |
||||||
| 56 | |||||||
| 57 | // Once we have the foreign key names, we'll just create a new Eloquent query |
||||||
| 58 | // for the related models and returns the relationship instance which will |
||||||
| 59 | // actually be responsible for retrieving and hydrating every relations. |
||||||
| 60 | $ownerKey = $ownerKey ?: $instance->getKeyName(); |
||||||
|
0 ignored issues
–
show
|
|||||||
| 61 | |||||||
| 62 | $relationQuery = $this->newBelongsTo( |
||||||
| 63 | $instance->newQuery(), |
||||||
| 64 | $this, |
||||||
|
0 ignored issues
–
show
$this of type MaksimM\CompositePrimary...\CompositeRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $child of MaksimM\CompositePrimary...onships::newBelongsTo().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 65 | $foreignKey, |
||||||
| 66 | $ownerKey, |
||||||
| 67 | $relation |
||||||
| 68 | ); |
||||||
| 69 | |||||||
| 70 | return $relationQuery; |
||||||
| 71 | } |
||||||
| 72 | |||||||
| 73 | protected function executeWithinOptionalBinaryTransformation(Closure $relation, ...$models) |
||||||
| 74 | { |
||||||
| 75 | foreach ($models as $model) { |
||||||
| 76 | if (method_exists($model, 'disableBinaryMutators')) { |
||||||
| 77 | $model->disableBinaryMutators(); |
||||||
| 78 | } |
||||||
| 79 | } |
||||||
| 80 | $relationResult = $relation(); |
||||||
| 81 | foreach ($models as $model) { |
||||||
| 82 | if (method_exists($model, 'enableBinaryMutators')) { |
||||||
| 83 | $model->enableBinaryMutators(); |
||||||
| 84 | } |
||||||
| 85 | } |
||||||
| 86 | |||||||
| 87 | return $relationResult; |
||||||
| 88 | } |
||||||
| 89 | |||||||
| 90 | /** |
||||||
| 91 | * Instantiate a new BelongsTo relationship. |
||||||
| 92 | * |
||||||
| 93 | * @param Builder $query |
||||||
| 94 | * @param Model $child |
||||||
| 95 | * @param string $foreignKey |
||||||
| 96 | * @param string $ownerKey |
||||||
| 97 | * @param string $relation |
||||||
| 98 | * |
||||||
| 99 | * @return BelongsTo |
||||||
| 100 | */ |
||||||
| 101 | protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation) |
||||||
| 102 | { |
||||||
| 103 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $child, $foreignKey, $ownerKey, $relation) { |
||||||
| 104 | return new CompositeBelongsTo($query, $child, $foreignKey, $ownerKey, $relation); |
||||||
| 105 | }, $query->getModel(), $child); |
||||||
| 106 | } |
||||||
| 107 | |||||||
| 108 | /** |
||||||
| 109 | * Instantiate a new HasOne relationship. |
||||||
| 110 | * |
||||||
| 111 | * @param Builder $query |
||||||
| 112 | * @param Model $parent |
||||||
| 113 | * @param string $foreignKey |
||||||
| 114 | * @param string $localKey |
||||||
| 115 | * |
||||||
| 116 | * @return HasOne |
||||||
| 117 | */ |
||||||
| 118 | protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey) |
||||||
| 119 | { |
||||||
| 120 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $localKey) { |
||||||
| 121 | return new HasOne($query, $parent, $foreignKey, $localKey); |
||||||
| 122 | }, $query->getModel(), $parent); |
||||||
| 123 | } |
||||||
| 124 | |||||||
| 125 | /** |
||||||
| 126 | * Instantiate a new MorphOne relationship. |
||||||
| 127 | * |
||||||
| 128 | * @param Builder $query |
||||||
| 129 | * @param Model $parent |
||||||
| 130 | * @param string $type |
||||||
| 131 | * @param string $id |
||||||
| 132 | * @param string $localKey |
||||||
| 133 | * |
||||||
| 134 | * @return MorphOne |
||||||
| 135 | */ |
||||||
| 136 | protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey) |
||||||
| 137 | { |
||||||
| 138 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $type, $id, $localKey) { |
||||||
| 139 | return new MorphOne($query, $parent, $type, $id, $localKey); |
||||||
| 140 | }, $query->getModel(), $parent); |
||||||
| 141 | } |
||||||
| 142 | |||||||
| 143 | /** |
||||||
| 144 | * Instantiate a new MorphTo relationship. |
||||||
| 145 | * |
||||||
| 146 | * @param Builder $query |
||||||
| 147 | * @param Model $parent |
||||||
| 148 | * @param string $foreignKey |
||||||
| 149 | * @param string $ownerKey |
||||||
| 150 | * @param string $type |
||||||
| 151 | * @param string $relation |
||||||
| 152 | * |
||||||
| 153 | * @return MorphTo |
||||||
| 154 | */ |
||||||
| 155 | protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation) |
||||||
| 156 | { |
||||||
| 157 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $ownerKey, $type, $relation) { |
||||||
| 158 | return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation); |
||||||
| 159 | }, $query->getModel(), $parent); |
||||||
| 160 | } |
||||||
| 161 | |||||||
| 162 | /** |
||||||
| 163 | * Instantiate a new HasMany relationship. |
||||||
| 164 | * |
||||||
| 165 | * @param Builder $query |
||||||
| 166 | * @param Model $parent |
||||||
| 167 | * @param string $foreignKey |
||||||
| 168 | * @param string $localKey |
||||||
| 169 | * |
||||||
| 170 | * @return HasMany |
||||||
| 171 | */ |
||||||
| 172 | protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey) |
||||||
| 173 | { |
||||||
| 174 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $localKey) { |
||||||
| 175 | return new HasMany($query, $parent, $foreignKey, $localKey); |
||||||
| 176 | }, $query->getModel(), $parent); |
||||||
| 177 | } |
||||||
| 178 | |||||||
| 179 | /** |
||||||
| 180 | * Instantiate a new HasManyThrough relationship. |
||||||
| 181 | * |
||||||
| 182 | * @param Builder $query |
||||||
| 183 | * @param Model $farParent |
||||||
| 184 | * @param Model $throughParent |
||||||
| 185 | * @param string $firstKey |
||||||
| 186 | * @param string $secondKey |
||||||
| 187 | * @param string $localKey |
||||||
| 188 | * @param string $secondLocalKey |
||||||
| 189 | * |
||||||
| 190 | * @return HasManyThrough |
||||||
| 191 | */ |
||||||
| 192 | protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey) |
||||||
| 193 | { |
||||||
| 194 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey) { |
||||||
| 195 | return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey); |
||||||
| 196 | }, $query->getModel(), $farParent); |
||||||
| 197 | } |
||||||
| 198 | |||||||
| 199 | /** |
||||||
| 200 | * Instantiate a new MorphMany relationship. |
||||||
| 201 | * |
||||||
| 202 | * @param Builder $query |
||||||
| 203 | * @param Model $parent |
||||||
| 204 | * @param string $type |
||||||
| 205 | * @param string $id |
||||||
| 206 | * @param string $localKey |
||||||
| 207 | * |
||||||
| 208 | * @return MorphMany |
||||||
| 209 | */ |
||||||
| 210 | protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey) |
||||||
| 211 | { |
||||||
| 212 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $type, $id, $localKey) { |
||||||
| 213 | return new MorphMany($query, $parent, $type, $id, $localKey); |
||||||
| 214 | }, $query->getModel(), $parent); |
||||||
| 215 | } |
||||||
| 216 | |||||||
| 217 | /** |
||||||
| 218 | * Instantiate a new BelongsToMany relationship. |
||||||
| 219 | * |
||||||
| 220 | * @param Builder $query |
||||||
| 221 | * @param Model $parent |
||||||
| 222 | * @param string $table |
||||||
| 223 | * @param string $foreignPivotKey |
||||||
| 224 | * @param string $relatedPivotKey |
||||||
| 225 | * @param string $parentKey |
||||||
| 226 | * @param string $relatedKey |
||||||
| 227 | * @param string $relationName |
||||||
| 228 | * |
||||||
| 229 | * @return BelongsToMany |
||||||
| 230 | */ |
||||||
| 231 | protected function newBelongsToMany( |
||||||
| 232 | Builder $query, |
||||||
| 233 | Model $parent, |
||||||
| 234 | $table, |
||||||
| 235 | $foreignPivotKey, |
||||||
| 236 | $relatedPivotKey, |
||||||
| 237 | $parentKey, |
||||||
| 238 | $relatedKey, |
||||||
| 239 | $relationName = null |
||||||
| 240 | ) { |
||||||
| 241 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName) { |
||||||
| 242 | return new CompositeBelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName); |
||||||
| 243 | }, $query->getModel(), $parent); |
||||||
| 244 | } |
||||||
| 245 | |||||||
| 246 | /** |
||||||
| 247 | * Instantiate a new MorphToMany relationship. |
||||||
| 248 | * |
||||||
| 249 | * @param Builder $query |
||||||
| 250 | * @param Model $parent |
||||||
| 251 | * @param string $name |
||||||
| 252 | * @param string $table |
||||||
| 253 | * @param string $foreignPivotKey |
||||||
| 254 | * @param string $relatedPivotKey |
||||||
| 255 | * @param string $parentKey |
||||||
| 256 | * @param string $relatedKey |
||||||
| 257 | * @param string $relationName |
||||||
| 258 | * @param bool $inverse |
||||||
| 259 | * |
||||||
| 260 | * @return MorphToMany |
||||||
| 261 | */ |
||||||
| 262 | protected function newMorphToMany( |
||||||
| 263 | Builder $query, |
||||||
| 264 | Model $parent, |
||||||
| 265 | $name, |
||||||
| 266 | $table, |
||||||
| 267 | $foreignPivotKey, |
||||||
| 268 | $relatedPivotKey, |
||||||
| 269 | $parentKey, |
||||||
| 270 | $relatedKey, |
||||||
| 271 | $relationName = null, |
||||||
| 272 | $inverse = false |
||||||
| 273 | ) { |
||||||
| 274 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, |
||||||
| 275 | $relationName, $inverse) { |
||||||
| 276 | return new MorphToMany( |
||||||
| 277 | $query, |
||||||
| 278 | $parent, |
||||||
| 279 | $name, |
||||||
| 280 | $table, |
||||||
| 281 | $foreignPivotKey, |
||||||
| 282 | $relatedPivotKey, |
||||||
| 283 | $parentKey, |
||||||
| 284 | $relatedKey, |
||||||
| 285 | $relationName, |
||||||
| 286 | $inverse |
||||||
| 287 | ); |
||||||
| 288 | }, $query->getModel(), $parent); |
||||||
| 289 | } |
||||||
| 290 | } |
||||||
| 291 |