This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Analogue\ORM\Relationships; |
||
4 | |||
5 | use Analogue\ORM\Mappable; |
||
6 | use Analogue\ORM\System\Query; |
||
7 | use Analogue\ORM\System\Mapper; |
||
8 | use Analogue\ORM\EntityCollection; |
||
9 | use Illuminate\Database\Query\Expression; |
||
10 | |||
11 | class BelongsTo extends Relationship |
||
12 | { |
||
13 | /** |
||
14 | * The foreign key of the parent model. |
||
15 | * |
||
16 | * @var string |
||
17 | */ |
||
18 | protected $foreignKey; |
||
19 | |||
20 | /** |
||
21 | * The associated key on the parent model. |
||
22 | * |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $otherKey; |
||
26 | |||
27 | /** |
||
28 | * The name of the relationship. |
||
29 | * |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $relation; |
||
33 | |||
34 | /** |
||
35 | * Indicate if the parent entity hold the key for the relation. |
||
36 | * |
||
37 | * @var boolean |
||
38 | */ |
||
39 | protected static $ownForeignKey = true; |
||
40 | |||
41 | /** |
||
42 | * Create a new belongs to relationship instance. |
||
43 | * |
||
44 | * @param Mapper $mapper |
||
45 | * @param Mappable $parent |
||
46 | * @param string $foreignKey |
||
47 | * @param string $otherKey |
||
48 | * @param string $relation |
||
49 | */ |
||
50 | public function __construct(Mapper $mapper, $parent, $foreignKey, $otherKey, $relation) |
||
51 | { |
||
52 | $this->otherKey = $otherKey; |
||
53 | $this->relation = $relation; |
||
54 | $this->foreignKey = $foreignKey; |
||
55 | |||
56 | parent::__construct($mapper, $parent); |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * @param $related |
||
61 | * @return mixed |
||
62 | */ |
||
63 | public function attachTo($related) |
||
64 | { |
||
65 | $this->associate($related); |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * @param $related |
||
70 | * @return Mappable |
||
71 | */ |
||
72 | public function detachFrom($related) |
||
73 | { |
||
74 | return $this->dissociate($related); //todo |
||
0 ignored issues
–
show
|
|||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Get the results of the relationship. |
||
79 | * |
||
80 | * @param $relation |
||
81 | * |
||
82 | * @return \Analogue\ORM\Entity |
||
83 | */ |
||
84 | public function getResults($relation) |
||
85 | { |
||
86 | $result = $this->query->first(); |
||
87 | |||
88 | $this->cacheRelation($result, $relation); |
||
89 | |||
90 | return $result; |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * Set the base constraints on the relation query. |
||
95 | * |
||
96 | * @return void |
||
97 | */ |
||
98 | public function addConstraints() |
||
99 | { |
||
100 | if (static::$constraints) { |
||
101 | // For belongs to relationships, which are essentially the inverse of has one |
||
102 | // or has many relationships, we need to actually query on the primary key |
||
103 | // of the related models matching on the foreign key that's on a parent. |
||
104 | $table = $this->relatedMap->getTable(); |
||
105 | |||
106 | $this->query->where($table . '.' . $this->otherKey, '=', $this->parent->getEntityAttribute($this->foreignKey)); |
||
107 | } |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Add the constraints for a relationship count query. |
||
112 | * |
||
113 | * @param Query $query |
||
114 | * @param Query $parent |
||
115 | * @return Query |
||
116 | */ |
||
117 | public function getRelationCountQuery(Query $query, Query $parent) |
||
118 | { |
||
119 | $query->select(new Expression('count(*)')); |
||
0 ignored issues
–
show
The method
select does not exist on object<Analogue\ORM\System\Query> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
120 | |||
121 | $otherKey = $this->wrap($query->getTable() . '.' . $this->otherKey); |
||
122 | |||
123 | return $query->where($this->getQualifiedForeignKey(), '=', new Expression($otherKey)); |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * Set the constraints for an eager load of the relation. |
||
128 | * |
||
129 | * @param array $entities |
||
130 | * @return void |
||
131 | */ |
||
132 | public function addEagerConstraints(array $entities) |
||
133 | { |
||
134 | // We'll grab the primary key name of the related models since it could be set to |
||
135 | // a non-standard name and not "id". We will then construct the constraint for |
||
136 | // our eagerly loading query so it returns the proper models from execution. |
||
137 | $key = $this->relatedMap->getTable() . '.' . $this->otherKey; |
||
138 | |||
139 | $this->query->whereIn($key, $this->getEagerModelKeys($entities)); |
||
0 ignored issues
–
show
The method
whereIn does not exist on object<Analogue\ORM\System\Query> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
140 | } |
||
141 | |||
142 | /** |
||
143 | * Gather the keys from an array of related models. |
||
144 | * |
||
145 | * @param array $entities |
||
146 | * @return array |
||
147 | */ |
||
148 | protected function getEagerModelKeys(array $entities) |
||
149 | { |
||
150 | $keys = []; |
||
151 | |||
152 | // First we need to gather all of the keys from the parent models so we know what |
||
153 | // to query for via the eager loading query. We will add them to an array then |
||
154 | // execute a "where in" statement to gather up all of those related records. |
||
155 | foreach ($entities as $entity) { |
||
156 | $entity = $this->factory->make($entity); |
||
157 | |||
158 | if (!is_null($value = $entity->getEntityAttribute($this->foreignKey))) { |
||
159 | $keys[] = $value; |
||
160 | } |
||
161 | } |
||
162 | |||
163 | // If there are no keys that were not null we will just return an array with 0 in |
||
164 | // it so the query doesn't fail, but will not return any results, which should |
||
165 | // be what this developer is expecting in a case where this happens to them. |
||
166 | if (count($keys) == 0) { |
||
167 | return [0]; |
||
168 | } |
||
169 | |||
170 | return array_values(array_unique($keys)); |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Initialize the relation on a set of models. |
||
175 | * |
||
176 | * @param array $entities |
||
177 | * @param string $relation |
||
178 | * @return array |
||
179 | */ |
||
180 | public function initRelation(array $entities, $relation) |
||
181 | { |
||
182 | foreach ($entities as $entity) { |
||
183 | $entity = $this->factory->make($entity); |
||
184 | $entity->setEntityAttribute($relation, null); |
||
185 | } |
||
186 | |||
187 | return $entities; |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Match the eagerly loaded results to their parents. |
||
192 | * |
||
193 | * @param array $entities |
||
194 | * @param EntityCollection $results |
||
195 | * @param string $relation |
||
196 | * @return array |
||
197 | */ |
||
198 | public function match(array $entities, EntityCollection $results, $relation) |
||
199 | { |
||
200 | $foreign = $this->foreignKey; |
||
201 | |||
202 | $other = $this->otherKey; |
||
203 | |||
204 | // First we will get to build a dictionary of the child models by their primary |
||
205 | // key of the relationship, then we can easily match the children back onto |
||
206 | // the parents using that dictionary and the primary key of the children. |
||
207 | $dictionary = []; |
||
208 | |||
209 | foreach ($results as $result) { |
||
210 | $result = $this->factory->make($result); |
||
211 | $dictionary[$result->getEntityAttribute($other)] = $result->getObject(); |
||
212 | } |
||
213 | |||
214 | // Once we have the dictionary constructed, we can loop through all the parents |
||
215 | // and match back onto their children using these keys of the dictionary and |
||
216 | // the primary key of the children to map them onto the correct instances. |
||
217 | foreach ($entities as $entity) { |
||
218 | $entity = $this->factory->make($entity); |
||
219 | |||
220 | if (isset($dictionary[$entity->getEntityAttribute($foreign)])) { |
||
221 | $entity->setEntityAttribute($relation, $dictionary[$entity->getEntityAttribute($foreign)]); |
||
222 | } |
||
223 | } |
||
224 | |||
225 | return $entities; |
||
226 | } |
||
227 | |||
228 | public function sync(array $entities) |
||
229 | { |
||
230 | if (count($entities) > 1) { |
||
231 | throw new MappingException("Single Relationship shouldn't be synced with more than one entity"); |
||
232 | } |
||
233 | |||
234 | if (count($entities) == 1) { |
||
235 | return $this->associate($entities[0]); |
||
236 | } |
||
237 | |||
238 | return false; |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * Associate the model instance to the given parent. |
||
243 | * |
||
244 | * @param mixed $entity |
||
245 | * @return void |
||
246 | */ |
||
247 | public function associate($entity) |
||
248 | { |
||
249 | $this->parent->setEntityAttribute($this->foreignKey, $entity->getEntityAttribute($this->otherKey)); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Dissociate previously associated model from the given parent. |
||
254 | * |
||
255 | * @return Mappable |
||
256 | */ |
||
257 | public function dissociate() |
||
258 | { |
||
259 | // The Mapper will retrieve this association within the object model, we won't be using |
||
260 | // the foreign key attribute inside the parent Entity. |
||
261 | // |
||
262 | //$this->parent->setEntityAttribute($this->foreignKey, null); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
72% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
263 | |||
264 | $this->parent->setEntityAttribute($this->relation, null); |
||
265 | } |
||
266 | |||
267 | /** |
||
268 | * Get the foreign key of the relationship. |
||
269 | * |
||
270 | * @return string |
||
271 | */ |
||
272 | public function getForeignKey() |
||
273 | { |
||
274 | return $this->foreignKey; |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * Get the foreign key value pair for a related object |
||
279 | * |
||
280 | * @param mixed $related |
||
281 | * |
||
282 | * @return array |
||
283 | */ |
||
284 | View Code Duplication | public function getForeignKeyValuePair($related) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
285 | { |
||
286 | $foreignKey = $this->getForeignKey(); |
||
287 | |||
288 | if ($related) { |
||
289 | $wrapper = $this->factory->make($related); |
||
290 | |||
291 | $relatedKey = $this->relatedMap->getKeyName(); |
||
292 | |||
293 | return [$foreignKey => $wrapper->getEntityAttribute($relatedKey)]; |
||
294 | } else { |
||
295 | return [$foreignKey => null]; |
||
296 | } |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * Get the fully qualified foreign key of the relationship. |
||
301 | * |
||
302 | * @return string |
||
303 | */ |
||
304 | public function getQualifiedForeignKey() |
||
305 | { |
||
306 | return $this->parentMap->getTable() . '.' . $this->foreignKey; |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * Get the associated key of the relationship. |
||
311 | * |
||
312 | * @return string |
||
313 | */ |
||
314 | public function getOtherKey() |
||
315 | { |
||
316 | return $this->otherKey; |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * Get the fully qualified associated key of the relationship. |
||
321 | * |
||
322 | * @return string |
||
323 | */ |
||
324 | public function getQualifiedOtherKeyName() |
||
325 | { |
||
326 | return $this->relatedMap->getTable() . '.' . $this->otherKey; |
||
327 | } |
||
328 | } |
||
329 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.