PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.5
Independent Analytics – WordPress Analytics Plugin v2.15.5
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / illuminate / database / Eloquent / Relations / MorphTo.php
independent-analytics / vendor / illuminate / database / Eloquent / Relations Last commit date
Concerns 1 month ago BelongsTo.php 2 years ago BelongsToMany.php 1 month ago HasMany.php 2 years ago HasManyThrough.php 1 month ago HasOne.php 1 month ago HasOneOrMany.php 1 month ago HasOneThrough.php 2 years ago MorphMany.php 2 years ago MorphOne.php 1 month ago MorphOneOrMany.php 2 years ago MorphPivot.php 1 month ago MorphTo.php 6 months ago MorphToMany.php 2 years ago Pivot.php 2 years ago Relation.php 1 month ago
MorphTo.php
319 lines
1 <?php
2
3 namespace IAWPSCOPED\Illuminate\Database\Eloquent\Relations;
4
5 use BadMethodCallException;
6 use IAWPSCOPED\Illuminate\Database\Eloquent\Builder;
7 use IAWPSCOPED\Illuminate\Database\Eloquent\Collection;
8 use IAWPSCOPED\Illuminate\Database\Eloquent\Model;
9 use IAWPSCOPED\Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithDictionary;
10 /** @internal */
11 class MorphTo extends BelongsTo
12 {
13 use InteractsWithDictionary;
14 /**
15 * The type of the polymorphic relation.
16 *
17 * @var string
18 */
19 protected $morphType;
20 /**
21 * The models whose relations are being eager loaded.
22 *
23 * @var \Illuminate\Database\Eloquent\Collection
24 */
25 protected $models;
26 /**
27 * All of the models keyed by ID.
28 *
29 * @var array
30 */
31 protected $dictionary = [];
32 /**
33 * A buffer of dynamic calls to query macros.
34 *
35 * @var array
36 */
37 protected $macroBuffer = [];
38 /**
39 * A map of relations to load for each individual morph type.
40 *
41 * @var array
42 */
43 protected $morphableEagerLoads = [];
44 /**
45 * A map of relationship counts to load for each individual morph type.
46 *
47 * @var array
48 */
49 protected $morphableEagerLoadCounts = [];
50 /**
51 * A map of constraints to apply for each individual morph type.
52 *
53 * @var array
54 */
55 protected $morphableConstraints = [];
56 /**
57 * Create a new morph to relationship instance.
58 *
59 * @param \Illuminate\Database\Eloquent\Builder $query
60 * @param \Illuminate\Database\Eloquent\Model $parent
61 * @param string $foreignKey
62 * @param string $ownerKey
63 * @param string $type
64 * @param string $relation
65 * @return void
66 */
67 public function __construct(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)
68 {
69 $this->morphType = $type;
70 parent::__construct($query, $parent, $foreignKey, $ownerKey, $relation);
71 }
72 /**
73 * Set the constraints for an eager load of the relation.
74 *
75 * @param array $models
76 * @return void
77 */
78 public function addEagerConstraints(array $models)
79 {
80 $this->buildDictionary($this->models = Collection::make($models));
81 }
82 /**
83 * Build a dictionary with the models.
84 *
85 * @param \Illuminate\Database\Eloquent\Collection $models
86 * @return void
87 */
88 protected function buildDictionary(Collection $models)
89 {
90 foreach ($models as $model) {
91 if ($model->{$this->morphType}) {
92 $morphTypeKey = $this->getDictionaryKey($model->{$this->morphType});
93 $foreignKeyKey = $this->getDictionaryKey($model->{$this->foreignKey});
94 $this->dictionary[$morphTypeKey][$foreignKeyKey][] = $model;
95 }
96 }
97 }
98 /**
99 * Get the results of the relationship.
100 *
101 * Called via eager load method of Eloquent query builder.
102 *
103 * @return mixed
104 */
105 public function getEager()
106 {
107 foreach (\array_keys($this->dictionary) as $type) {
108 $this->matchToMorphParents($type, $this->getResultsByType($type));
109 }
110 return $this->models;
111 }
112 /**
113 * Get all of the relation results for a type.
114 *
115 * @param string $type
116 * @return \Illuminate\Database\Eloquent\Collection
117 */
118 protected function getResultsByType($type)
119 {
120 $instance = $this->createModelByType($type);
121 $ownerKey = $this->ownerKey ?? $instance->getKeyName();
122 $query = $this->replayMacros($instance->newQuery())->mergeConstraintsFrom($this->getQuery())->with(\array_merge($this->getQuery()->getEagerLoads(), (array) ($this->morphableEagerLoads[\get_class($instance)] ?? [])))->withCount((array) ($this->morphableEagerLoadCounts[\get_class($instance)] ?? []));
123 if ($callback = $this->morphableConstraints[\get_class($instance)] ?? null) {
124 $callback($query);
125 }
126 $whereIn = $this->whereInMethod($instance, $ownerKey);
127 return $query->{$whereIn}($instance->getTable() . '.' . $ownerKey, $this->gatherKeysByType($type, $instance->getKeyType()))->get();
128 }
129 /**
130 * Gather all of the foreign keys for a given type.
131 *
132 * @param string $type
133 * @param string $keyType
134 * @return array
135 */
136 protected function gatherKeysByType($type, $keyType)
137 {
138 return $keyType !== 'string' ? \array_keys($this->dictionary[$type]) : \array_map(function ($modelId) {
139 return (string) $modelId;
140 }, \array_filter(\array_keys($this->dictionary[$type])));
141 }
142 /**
143 * Create a new model instance by type.
144 *
145 * @param string $type
146 * @return \Illuminate\Database\Eloquent\Model
147 */
148 public function createModelByType($type)
149 {
150 $class = Model::getActualClassNameForMorph($type);
151 return \IAWPSCOPED\tap(new $class(), function ($instance) {
152 if (!$instance->getConnectionName()) {
153 $instance->setConnection($this->getConnection()->getName());
154 }
155 });
156 }
157 /**
158 * Match the eagerly loaded results to their parents.
159 *
160 * @param array $models
161 * @param \Illuminate\Database\Eloquent\Collection $results
162 * @param string $relation
163 * @return array
164 */
165 public function match(array $models, Collection $results, $relation)
166 {
167 return $models;
168 }
169 /**
170 * Match the results for a given type to their parents.
171 *
172 * @param string $type
173 * @param \Illuminate\Database\Eloquent\Collection $results
174 * @return void
175 */
176 protected function matchToMorphParents($type, Collection $results)
177 {
178 foreach ($results as $result) {
179 $ownerKey = !\is_null($this->ownerKey) ? $this->getDictionaryKey($result->{$this->ownerKey}) : $result->getKey();
180 if (isset($this->dictionary[$type][$ownerKey])) {
181 foreach ($this->dictionary[$type][$ownerKey] as $model) {
182 $model->setRelation($this->relationName, $result);
183 }
184 }
185 }
186 }
187 /**
188 * Associate the model instance to the given parent.
189 *
190 * @param \Illuminate\Database\Eloquent\Model $model
191 * @return \Illuminate\Database\Eloquent\Model
192 */
193 public function associate($model)
194 {
195 if ($model instanceof Model) {
196 $foreignKey = $this->ownerKey && $model->{$this->ownerKey} ? $this->ownerKey : $model->getKeyName();
197 }
198 $this->parent->setAttribute($this->foreignKey, $model instanceof Model ? $model->{$foreignKey} : null);
199 $this->parent->setAttribute($this->morphType, $model instanceof Model ? $model->getMorphClass() : null);
200 return $this->parent->setRelation($this->relationName, $model);
201 }
202 /**
203 * Dissociate previously associated model from the given parent.
204 *
205 * @return \Illuminate\Database\Eloquent\Model
206 */
207 public function dissociate()
208 {
209 $this->parent->setAttribute($this->foreignKey, null);
210 $this->parent->setAttribute($this->morphType, null);
211 return $this->parent->setRelation($this->relationName, null);
212 }
213 /**
214 * Touch all of the related models for the relationship.
215 *
216 * @return void
217 */
218 public function touch()
219 {
220 if (!\is_null($this->child->{$this->foreignKey})) {
221 parent::touch();
222 }
223 }
224 /**
225 * Make a new related instance for the given model.
226 *
227 * @param \Illuminate\Database\Eloquent\Model $parent
228 * @return \Illuminate\Database\Eloquent\Model
229 */
230 protected function newRelatedInstanceFor(Model $parent)
231 {
232 return $parent->{$this->getRelationName()}()->getRelated()->newInstance();
233 }
234 /**
235 * Get the foreign key "type" name.
236 *
237 * @return string
238 */
239 public function getMorphType()
240 {
241 return $this->morphType;
242 }
243 /**
244 * Get the dictionary used by the relationship.
245 *
246 * @return array
247 */
248 public function getDictionary()
249 {
250 return $this->dictionary;
251 }
252 /**
253 * Specify which relations to load for a given morph type.
254 *
255 * @param array $with
256 * @return \Illuminate\Database\Eloquent\Relations\MorphTo
257 */
258 public function morphWith(array $with)
259 {
260 $this->morphableEagerLoads = \array_merge($this->morphableEagerLoads, $with);
261 return $this;
262 }
263 /**
264 * Specify which relationship counts to load for a given morph type.
265 *
266 * @param array $withCount
267 * @return \Illuminate\Database\Eloquent\Relations\MorphTo
268 */
269 public function morphWithCount(array $withCount)
270 {
271 $this->morphableEagerLoadCounts = \array_merge($this->morphableEagerLoadCounts, $withCount);
272 return $this;
273 }
274 /**
275 * Specify constraints on the query for a given morph type.
276 *
277 * @param array $callbacks
278 * @return \Illuminate\Database\Eloquent\Relations\MorphTo
279 */
280 public function constrain(array $callbacks)
281 {
282 $this->morphableConstraints = \array_merge($this->morphableConstraints, $callbacks);
283 return $this;
284 }
285 /**
286 * Replay stored macro calls on the actual related instance.
287 *
288 * @param \Illuminate\Database\Eloquent\Builder $query
289 * @return \Illuminate\Database\Eloquent\Builder
290 */
291 protected function replayMacros(Builder $query)
292 {
293 foreach ($this->macroBuffer as $macro) {
294 $query->{$macro['method']}(...$macro['parameters']);
295 }
296 return $query;
297 }
298 /**
299 * Handle dynamic method calls to the relationship.
300 *
301 * @param string $method
302 * @param array $parameters
303 * @return mixed
304 */
305 public function __call($method, $parameters)
306 {
307 try {
308 $result = parent::__call($method, $parameters);
309 if (\in_array($method, ['select', 'selectRaw', 'selectSub', 'addSelect', 'withoutGlobalScopes'])) {
310 $this->macroBuffer[] = \compact('method', 'parameters');
311 }
312 return $result;
313 } catch (BadMethodCallException $e) {
314 $this->macroBuffer[] = \compact('method', 'parameters');
315 return $this;
316 }
317 }
318 }
319