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 namespace Anomaly\Streams\Platform\Model; |
||
2 | |||
3 | use Anomaly\Streams\Platform\Collection\CacheCollection; |
||
4 | use Anomaly\Streams\Platform\Traits\Hookable; |
||
5 | use Illuminate\Contracts\Support\Arrayable; |
||
6 | use Illuminate\Database\Eloquent\Builder; |
||
7 | use Illuminate\Database\Eloquent\Collection; |
||
8 | use Illuminate\Database\Eloquent\Model; |
||
9 | use Illuminate\Foundation\Bus\DispatchesJobs; |
||
10 | use Robbo\Presenter\PresentableInterface; |
||
11 | |||
12 | /** |
||
13 | * Class EloquentModel |
||
14 | * |
||
15 | * @link http://pyrocms.com/ |
||
16 | * @author PyroCMS, Inc. <[email protected]> |
||
17 | * @author Ryan Thompson <[email protected]> |
||
18 | */ |
||
19 | class EloquentModel extends Model implements Arrayable, PresentableInterface |
||
20 | { |
||
21 | |||
22 | use Hookable; |
||
23 | use DispatchesJobs; |
||
24 | |||
25 | /** |
||
26 | * Disable timestamps for this model. |
||
27 | * |
||
28 | * @var bool |
||
29 | */ |
||
30 | public $timestamps = false; |
||
31 | |||
32 | /** |
||
33 | * Translatable attributes. |
||
34 | * |
||
35 | * @var array |
||
36 | */ |
||
37 | protected $translatedAttributes = []; |
||
38 | |||
39 | /** |
||
40 | * The number of minutes to cache query results. |
||
41 | * |
||
42 | * @var null|false|int |
||
43 | */ |
||
44 | protected $ttl = false; |
||
45 | |||
46 | /** |
||
47 | * The attributes that are |
||
48 | * not mass assignable. Let upper |
||
49 | * models handle this themselves. |
||
50 | * |
||
51 | * @var array |
||
52 | */ |
||
53 | protected $guarded = []; |
||
54 | |||
55 | /** |
||
56 | * The title key. |
||
57 | * |
||
58 | * @var string |
||
59 | */ |
||
60 | protected $titleKey = 'id'; |
||
61 | |||
62 | /** |
||
63 | * Observable model events. |
||
64 | * |
||
65 | * @var array |
||
66 | */ |
||
67 | protected $observables = [ |
||
68 | 'updatingMultiple', |
||
69 | 'updatedMultiple', |
||
70 | 'deletingMultiple', |
||
71 | 'deletedMultiple', |
||
72 | ]; |
||
73 | |||
74 | /** |
||
75 | * The cascading delete-able relations. |
||
76 | * |
||
77 | * @var array |
||
78 | */ |
||
79 | protected $cascades = []; |
||
80 | |||
81 | /** |
||
82 | * Runtime cache. |
||
83 | * |
||
84 | * @var array |
||
85 | */ |
||
86 | protected $cache = []; |
||
87 | |||
88 | /** |
||
89 | * Get the ID. |
||
90 | * |
||
91 | * @return integer |
||
92 | */ |
||
93 | public function getId() |
||
94 | { |
||
95 | return $this->id; |
||
0 ignored issues
–
show
|
|||
96 | } |
||
97 | |||
98 | /** |
||
99 | * Return the object's ETag fingerprint. |
||
100 | * |
||
101 | * @return string |
||
102 | */ |
||
103 | public function etag() |
||
104 | { |
||
105 | return md5(get_class($this) . json_encode($this->toArray())); |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * Cache a value in the |
||
110 | * model's cache collection. |
||
111 | * |
||
112 | * @param $key |
||
113 | * @param $ttl |
||
114 | * @param $value |
||
115 | * @return mixed |
||
116 | */ |
||
117 | public function cache($key, $ttl, $value) |
||
118 | { |
||
119 | (new CacheCollection()) |
||
120 | ->make([$key]) |
||
121 | ->setKey($this->getCacheCollectionKey()) |
||
122 | ->index(); |
||
123 | |||
124 | return app('cache')->remember( |
||
125 | $key, |
||
126 | $ttl ?: $this->getTtl(), |
||
127 | $value |
||
128 | ); |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * Fire a model event. |
||
133 | * |
||
134 | * @param $event |
||
135 | * @return mixed |
||
136 | */ |
||
137 | public function fireEvent($event) |
||
138 | { |
||
139 | return $this->fireModelEvent($event); |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * Return the entry presenter. |
||
144 | * |
||
145 | * This is against standards but required |
||
146 | * by the presentable interface. |
||
147 | * |
||
148 | * @return EloquentPresenter |
||
149 | */ |
||
150 | View Code Duplication | public function getPresenter() |
|
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. ![]() |
|||
151 | { |
||
152 | $presenter = substr(get_class($this), 0, -5) . 'Presenter'; |
||
153 | |||
154 | if (class_exists($presenter)) { |
||
155 | return app()->make($presenter, ['object' => $this]); |
||
156 | } |
||
157 | |||
158 | return new EloquentPresenter($this); |
||
0 ignored issues
–
show
The return type of
return new \Anomaly\Stre...oquentPresenter($this); (Anomaly\Streams\Platform\Model\EloquentPresenter ) is incompatible with the return type declared by the interface Robbo\Presenter\PresentableInterface::getPresenter of type Robbo\Presenter\Robbo\Presenter\Presenter .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
159 | } |
||
160 | |||
161 | /** |
||
162 | * Return a new collection class with our models. |
||
163 | * |
||
164 | * @param array $items |
||
165 | * @return Collection |
||
166 | */ |
||
167 | View Code Duplication | public function newCollection(array $items = []) |
|
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. ![]() |
|||
168 | { |
||
169 | $collection = substr(get_class($this), 0, -5) . 'Collection'; |
||
170 | |||
171 | if (class_exists($collection)) { |
||
172 | return new $collection($items); |
||
173 | } |
||
174 | |||
175 | return new EloquentCollection($items); |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Return the translatable flag. |
||
180 | * |
||
181 | * @return bool |
||
182 | */ |
||
183 | public function isTranslatable() |
||
184 | { |
||
185 | return isset($this->translationModel); |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * Set the translatable flag. |
||
190 | * |
||
191 | * @param $translatable |
||
192 | * @return $this |
||
193 | */ |
||
194 | public function setTranslatable($translatable) |
||
195 | { |
||
196 | $this->translatable = $translatable; |
||
0 ignored issues
–
show
The property
translatable does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
197 | |||
198 | return $this; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Set the ttl. |
||
203 | * |
||
204 | * @param $ttl |
||
205 | * @return $this |
||
206 | */ |
||
207 | public function setTtl($ttl) |
||
208 | { |
||
209 | $this->ttl = $ttl; |
||
210 | |||
211 | return $this; |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Get the ttl. |
||
216 | * |
||
217 | * @return int|mixed |
||
218 | */ |
||
219 | public function getTtl() |
||
220 | { |
||
221 | return $this->ttl; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Get cache collection key. |
||
226 | * |
||
227 | * @return string |
||
228 | */ |
||
229 | public function getCacheCollectionKey() |
||
230 | { |
||
231 | return get_called_class(); |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Get the model title. |
||
236 | * |
||
237 | * @return mixed |
||
238 | */ |
||
239 | public function getTitle() |
||
240 | { |
||
241 | return $this->{$this->getTitleName()}; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Get the title key. |
||
246 | * |
||
247 | * @return string |
||
248 | */ |
||
249 | public function getTitleName() |
||
250 | { |
||
251 | return $this->titleName ?: 'id'; |
||
0 ignored issues
–
show
The property
titleName does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Return if a row is deletable or not. |
||
256 | * |
||
257 | * @return bool |
||
258 | */ |
||
259 | public function isDeletable() |
||
260 | { |
||
261 | return true; |
||
262 | } |
||
263 | |||
264 | /** |
||
265 | * Return if the model is restorable or not. |
||
266 | * |
||
267 | * @return bool |
||
268 | */ |
||
269 | public function isRestorable() |
||
270 | { |
||
271 | return true; |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * Return whether the model is being |
||
276 | * force deleted or not. |
||
277 | * |
||
278 | * @return bool |
||
279 | */ |
||
280 | public function isForceDeleting() |
||
281 | { |
||
282 | return isset($this->forceDeleting) && $this->forceDeleting === true; |
||
0 ignored issues
–
show
The property
forceDeleting does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
283 | } |
||
284 | |||
285 | /** |
||
286 | * Flush the model's cache. |
||
287 | * |
||
288 | * @return $this |
||
289 | */ |
||
290 | public function flushCache() |
||
291 | { |
||
292 | (new CacheCollection())->setKey($key = $this->getCacheCollectionKey())->flush(); |
||
293 | |||
294 | EloquentQueryBuilder::dropRuntimeCache($key); |
||
295 | |||
296 | return $this; |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * Create a new Eloquent query builder for the model. |
||
301 | * |
||
302 | * @param \Illuminate\Database\Query\Builder $query |
||
303 | * @return \Illuminate\Database\Eloquent\Builder |
||
304 | */ |
||
305 | View Code Duplication | public function newEloquentBuilder($query) |
|
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. ![]() |
|||
306 | { |
||
307 | $builder = substr(get_class($this), 0, -5) . 'QueryBuilder'; |
||
308 | |||
309 | if (class_exists($builder)) { |
||
310 | return new $builder($query); |
||
311 | } |
||
312 | |||
313 | return new EloquentQueryBuilder($query); |
||
314 | } |
||
315 | |||
316 | /* |
||
317 | * Alias for getTranslation() |
||
318 | */ |
||
319 | public function translate($locale = null, $withFallback = false) |
||
320 | { |
||
321 | return $this->getTranslation($locale, $withFallback); |
||
322 | } |
||
323 | |||
324 | /* |
||
325 | * Alias for getTranslation() |
||
326 | */ |
||
327 | public function translateOrDefault($locale) |
||
328 | { |
||
329 | return $this->getTranslation($locale, true) ?: $this; |
||
330 | } |
||
331 | |||
332 | /* |
||
333 | * Alias for getTranslationOrNew() |
||
334 | */ |
||
335 | public function translateOrNew($locale) |
||
336 | { |
||
337 | return $this->getTranslationOrNew($locale); |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * Get related translations. |
||
342 | * |
||
343 | * @return EloquentCollection |
||
344 | */ |
||
345 | public function getTranslations() |
||
346 | { |
||
347 | foreach ($translations = $this->translations()->get() as $translation) { |
||
348 | $translation->setRelation('parent', $this); |
||
349 | } |
||
350 | |||
351 | return $translations; |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * @param null $locale |
||
356 | * @param bool|null $withFallback |
||
357 | * @return Model|null |
||
358 | */ |
||
359 | public function getTranslation($locale = null, $withFallback = true) |
||
360 | { |
||
361 | |||
362 | /** |
||
363 | * If we have a desired locale and |
||
364 | * it exists then just use that locale. |
||
365 | */ |
||
366 | if ($locale && $translation = $this->getTranslationByLocaleKey($locale)) { |
||
367 | return $translation; |
||
368 | } |
||
369 | |||
370 | /** |
||
371 | * If we don't have a locale or it doesn't exist |
||
372 | * then go ahead and try using a fallback in using |
||
373 | * the system's designated DEFAULT (not active) locale. |
||
374 | */ |
||
375 | if ($withFallback |
||
376 | && $translation = $this->getTranslationByLocaleKey($this->getDefaultLocale()) |
||
377 | ) { |
||
378 | return $translation; |
||
379 | } |
||
380 | |||
381 | /** |
||
382 | * If we still don't have a translation then |
||
383 | * try looking up the FALLBACK translation. |
||
384 | */ |
||
385 | if ($withFallback |
||
386 | && $this->getFallbackLocale() |
||
387 | && $this->getTranslationByLocaleKey($this->getFallbackLocale()) |
||
388 | && $translation = $this->getTranslationByLocaleKey($this->getFallbackLocale()) |
||
389 | ) { |
||
390 | return $translation; |
||
391 | } |
||
392 | |||
393 | return null; |
||
394 | } |
||
395 | |||
396 | public function hasTranslation($locale = null) |
||
397 | { |
||
398 | $locale = $locale ?: $this->getFallbackLocale(); |
||
399 | |||
400 | View Code Duplication | foreach ($this->translations as $translation) { |
|
0 ignored issues
–
show
The property
translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() This code seems to be duplicated across 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. ![]() |
|||
401 | $translation->setRelation('parent', $this); |
||
402 | |||
403 | if ($translation->getAttribute($this->getLocaleKey()) == $locale) { |
||
404 | return true; |
||
405 | } |
||
406 | } |
||
407 | |||
408 | return false; |
||
409 | } |
||
410 | |||
411 | /** |
||
412 | * Get the translation model. |
||
413 | * |
||
414 | * @return EloquentModel |
||
415 | */ |
||
416 | public function getTranslationModel() |
||
417 | { |
||
418 | return new $this->translationModel; |
||
0 ignored issues
–
show
The property
translationModel does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
419 | } |
||
420 | |||
421 | /** |
||
422 | * Get the translation model name. |
||
423 | * |
||
424 | * @return string |
||
425 | */ |
||
426 | public function getTranslationModelName() |
||
427 | { |
||
428 | return $this->translationModel; |
||
0 ignored issues
–
show
The property
translationModel does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
429 | } |
||
430 | |||
431 | /** |
||
432 | * Get the translation table name. |
||
433 | * |
||
434 | * @return string |
||
435 | */ |
||
436 | public function getTranslationTableName() |
||
437 | { |
||
438 | $model = $this->getTranslationModel(); |
||
439 | |||
440 | return $model->getTableName(); |
||
441 | } |
||
442 | |||
443 | public function getTranslationModelNameDefault() |
||
444 | { |
||
445 | return get_class($this) . 'Translation'; |
||
446 | } |
||
447 | |||
448 | /** |
||
449 | * Return translated attributes. |
||
450 | * |
||
451 | * @return array |
||
452 | */ |
||
453 | public function getTranslatedAttributes() |
||
454 | { |
||
455 | return $this->translatedAttributes; |
||
456 | } |
||
457 | |||
458 | public function getRelationKey() |
||
459 | { |
||
460 | return $this->translationForeignKey ?: $this->getForeignKey(); |
||
0 ignored issues
–
show
The property
translationForeignKey does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
461 | } |
||
462 | |||
463 | public function getLocaleKey() |
||
464 | { |
||
465 | return $this->localeKey ?: 'locale'; |
||
0 ignored issues
–
show
The property
localeKey does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
466 | } |
||
467 | |||
468 | public function translations() |
||
469 | { |
||
470 | return $this->hasMany($this->getTranslationModelName(), $this->getRelationKey()); |
||
471 | } |
||
472 | |||
473 | public function getAttribute($key) |
||
474 | { |
||
475 | if ($this->isTranslatedAttribute($key)) { |
||
476 | |||
477 | if (($translation = $this->getTranslation()) === null) { |
||
478 | return null; |
||
479 | } |
||
480 | |||
481 | $translation->setRelation('parent', $this); |
||
482 | |||
483 | return $translation->$key; |
||
484 | } |
||
485 | |||
486 | return parent::getAttribute($key); |
||
487 | } |
||
488 | |||
489 | /** |
||
490 | * Set an attribute. |
||
491 | * |
||
492 | * @param string $key |
||
493 | * @param mixed $value |
||
494 | * @return $this |
||
495 | */ |
||
496 | public function setAttribute($key, $value) |
||
497 | { |
||
498 | if (in_array($key, $this->translatedAttributes)) { |
||
499 | $this->getTranslationOrNew(config('app.locale'))->$key = $value; |
||
500 | } else { |
||
501 | parent::setAttribute($key, $value); |
||
502 | } |
||
503 | |||
504 | return $this; |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * Save the model. |
||
509 | * |
||
510 | * We have some customization here to |
||
511 | * accommodate translations. First sa |
||
512 | * then save translations is translatable. |
||
513 | * |
||
514 | * @param array $options |
||
515 | * @return bool |
||
516 | */ |
||
517 | public function save(array $options = []) |
||
518 | { |
||
519 | if (!$this->getTranslationModelName()) { |
||
520 | return $this->saveModel($options); |
||
521 | } |
||
522 | |||
523 | if ($this->exists) { |
||
524 | if (count($this->getDirty()) > 0) { |
||
525 | |||
526 | // If $this->exists and dirty, $this->saveModel() has to return true. If not, |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
42% 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. ![]() |
|||
527 | // an error has occurred. Therefore we shouldn't save the translations. |
||
528 | if ($this->saveModel($options)) { |
||
529 | return $this->saveTranslations(); |
||
530 | } |
||
531 | |||
532 | return false; |
||
533 | } else { |
||
534 | |||
535 | // If $this->exists and not dirty, $this->saveModel() skips saving and returns |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
38% 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. ![]() |
|||
536 | // false. So we have to save the translations |
||
537 | return $this->saveTranslations(); |
||
538 | } |
||
539 | } elseif ($this->saveModel($options)) { |
||
540 | |||
541 | // We save the translations only if the instance is saved in the database. |
||
542 | return $this->saveTranslations(); |
||
543 | } |
||
544 | |||
545 | return false; |
||
546 | } |
||
547 | |||
548 | /** |
||
549 | * Save the model to the database. |
||
550 | * |
||
551 | * This is a direct port from Eloquent |
||
552 | * with the only exception being that if |
||
553 | * the model is translatable it will NOT |
||
554 | * fire the saved event. The saveTranslations |
||
555 | * method will do that instead. |
||
556 | * |
||
557 | * @param array $options |
||
558 | * @return bool |
||
559 | */ |
||
560 | public function saveModel(array $options = []) |
||
561 | { |
||
562 | $query = $this->newQueryWithoutScopes(); |
||
563 | |||
564 | // If the "saving" event returns false we'll bail out of the save and return |
||
565 | // false, indicating that the save failed. This provides a chance for any |
||
566 | // listeners to cancel save operations if validations fail or whatever. |
||
567 | if ($this->fireModelEvent('saving') === false) { |
||
568 | return false; |
||
569 | } |
||
570 | |||
571 | // If the model already exists in the database we can just update our record |
||
572 | // that is already in this database using the current IDs in this "where" |
||
573 | // clause to only update this model. Otherwise, we'll just insert them. |
||
574 | if ($this->exists) { |
||
575 | $saved = $this->performUpdate($query, $options); |
||
0 ignored issues
–
show
It seems like
$query defined by $this->newQueryWithoutScopes() on line 562 can also be of type object<Illuminate\Database\Eloquent\Model> ; however, Illuminate\Database\Eloq...\Model::performUpdate() does only seem to accept object<Illuminate\Database\Eloquent\Builder> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() The call to
EloquentModel::performUpdate() has too many arguments starting with $options .
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 ![]() |
|||
576 | } |
||
577 | |||
578 | // If the model is brand new, we'll insert it into our database and set the |
||
579 | // ID attribute on the model to the value of the newly inserted row's ID |
||
580 | // which is typically an auto-increment value managed by the database. |
||
581 | else { |
||
582 | $saved = $this->performInsert($query, $options); |
||
0 ignored issues
–
show
It seems like
$query defined by $this->newQueryWithoutScopes() on line 562 can also be of type object<Illuminate\Database\Eloquent\Model> ; however, Illuminate\Database\Eloq...\Model::performInsert() does only seem to accept object<Illuminate\Database\Eloquent\Builder> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() The call to
EloquentModel::performInsert() has too many arguments starting with $options .
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 ![]() |
|||
583 | } |
||
584 | |||
585 | if ($saved && !$this->isTranslatable()) { |
||
586 | $this->finishSave($options); |
||
587 | } |
||
588 | |||
589 | return $saved; |
||
590 | } |
||
591 | |||
592 | /** |
||
593 | * Save translations to the database. |
||
594 | * |
||
595 | * @return bool |
||
596 | */ |
||
597 | protected function saveTranslations() |
||
598 | { |
||
599 | $saved = true; |
||
600 | |||
601 | foreach ($this->translations as $translation) { |
||
0 ignored issues
–
show
The property
translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
602 | $translation->setRelation('parent', $this); |
||
603 | |||
604 | /* @var EloquentModel $translation */ |
||
605 | if ($saved && $this->isTranslationDirty($translation)) { |
||
606 | $translation->setAttribute($this->getRelationKey(), $this->getKey()); |
||
607 | |||
608 | $saved = $translation->save(); |
||
609 | } |
||
610 | } |
||
611 | |||
612 | if ($this->translations->isEmpty()) { |
||
0 ignored issues
–
show
The property
translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
613 | $translation = $this->translateOrNew(config('streams::locales.default')); |
||
614 | |||
615 | $translation->save(); |
||
616 | } |
||
617 | |||
618 | $this->finishSave([]); |
||
619 | |||
620 | return $saved; |
||
621 | } |
||
622 | |||
623 | protected function getTranslationOrNew($locale) |
||
624 | { |
||
625 | if (($translation = $this->getTranslation($locale, false)) === null) { |
||
626 | $translation = $this->getNewTranslation($locale); |
||
627 | } |
||
628 | |||
629 | return $translation; |
||
630 | } |
||
631 | |||
632 | public function fill(array $attributes) |
||
633 | { |
||
634 | foreach ($attributes as $key => $values) { |
||
635 | if (is_array($values) && $this->isKeyALocale($key)) { |
||
636 | foreach ($values as $translationAttribute => $translationValue) { |
||
637 | if ($this->alwaysFillable() || $this->isFillable($translationAttribute)) { |
||
638 | $this->getTranslationOrNew($key)->$translationAttribute = $translationValue; |
||
639 | } |
||
640 | } |
||
641 | unset($attributes[$key]); |
||
642 | } |
||
643 | } |
||
644 | |||
645 | return parent::fill($attributes); |
||
646 | } |
||
647 | |||
648 | private function getTranslationByLocaleKey($key) |
||
649 | { |
||
650 | View Code Duplication | foreach ($this->translations as $translation) { |
|
0 ignored issues
–
show
The property
translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() This code seems to be duplicated across 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. ![]() |
|||
651 | $translation->setRelation('parent', $this); |
||
652 | |||
653 | if ($translation->getAttribute($this->getLocaleKey()) == $key) { |
||
654 | return $translation; |
||
655 | } |
||
656 | } |
||
657 | |||
658 | return null; |
||
659 | } |
||
660 | |||
661 | public function isTranslatedAttribute($key) |
||
662 | { |
||
663 | return in_array($key, $this->translatedAttributes); |
||
664 | } |
||
665 | |||
666 | protected function isTranslationAttribute($key) |
||
667 | { |
||
668 | return in_array($key, $this->translatedAttributes); |
||
669 | } |
||
670 | |||
671 | protected function isKeyALocale($key) |
||
672 | { |
||
673 | return config('streams::locales.supported.' . $key) !== null; |
||
674 | } |
||
675 | |||
676 | protected function isTranslationDirty(Model $translation) |
||
677 | { |
||
678 | $dirtyAttributes = $translation->getDirty(); |
||
679 | unset($dirtyAttributes[$this->getLocaleKey()]); |
||
680 | |||
681 | return count($dirtyAttributes) > 0; |
||
682 | } |
||
683 | |||
684 | public function getNewTranslation($locale) |
||
685 | { |
||
686 | $modelName = $this->getTranslationModelName(); |
||
687 | |||
688 | /* @var EloquentModel $translation */ |
||
689 | $translation = new $modelName; |
||
690 | |||
691 | $translation->setRelation('parent', $this); |
||
692 | |||
693 | $translation->setAttribute($this->getLocaleKey(), $locale); |
||
694 | $translation->setAttribute($this->getRelationKey(), $this->getKey()); |
||
695 | |||
696 | $this->translations->add($translation); |
||
0 ignored issues
–
show
The property
translations does not exist on object<Anomaly\Streams\P...rm\Model\EloquentModel> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
697 | |||
698 | return $translation; |
||
699 | } |
||
700 | |||
701 | public function scopeTranslatedIn(Builder $query, $locale) |
||
702 | { |
||
703 | return $query->whereHas( |
||
704 | 'translations', |
||
705 | function (Builder $q) use ($locale) { |
||
706 | $q->where($this->getLocaleKey(), '=', $locale); |
||
707 | } |
||
708 | ); |
||
709 | } |
||
710 | |||
711 | public function scopeTranslated(Builder $query) |
||
712 | { |
||
713 | return $query->has('translations'); |
||
714 | } |
||
715 | |||
716 | /** |
||
717 | * Return unguarded attributes. |
||
718 | * |
||
719 | * @return array |
||
720 | */ |
||
721 | public function getUnguardedAttributes() |
||
722 | { |
||
723 | foreach ($attributes = $this->getAttributes() as $attribute => $value) { |
||
724 | $attributes[$attribute] = $value; |
||
725 | } |
||
726 | |||
727 | return array_diff_key($attributes, array_flip($this->getGuarded())); |
||
728 | } |
||
729 | |||
730 | /** |
||
731 | * Get the default locale. |
||
732 | * |
||
733 | * @return string |
||
734 | */ |
||
735 | protected function getDefaultLocale() |
||
736 | { |
||
737 | if (isset($this->cache['default_locale'])) { |
||
738 | return $this->cache['default_locale']; |
||
739 | } |
||
740 | |||
741 | return $this->cache['default_locale'] = config('streams::locales.default'); |
||
742 | } |
||
743 | |||
744 | /** |
||
745 | * Get the fallback locale. |
||
746 | * |
||
747 | * @return string |
||
748 | */ |
||
749 | protected function getFallbackLocale() |
||
750 | { |
||
751 | if (isset($this->cache['fallback_locale'])) { |
||
752 | return $this->cache['fallback_locale']; |
||
753 | } |
||
754 | |||
755 | return $this->cache['fallback_locale'] = config('app.fallback_locale'); |
||
756 | } |
||
757 | |||
758 | /** |
||
759 | * This is to keep consistency with the |
||
760 | * entry interface above us. |
||
761 | * |
||
762 | * @return string |
||
763 | */ |
||
764 | public function getTableName() |
||
765 | { |
||
766 | return $this->getTable(); |
||
767 | } |
||
768 | |||
769 | /** |
||
770 | * Return if the entry is trashed or not. |
||
771 | * |
||
772 | * @return bool |
||
773 | */ |
||
774 | public function trashed() |
||
775 | { |
||
776 | return parent::trashed(); |
||
777 | } |
||
778 | |||
779 | public function toArray() |
||
780 | { |
||
781 | $attributes = $this->attributesToArray(); |
||
782 | |||
783 | foreach ($this->translatedAttributes as $field) { |
||
784 | if ($translation = $this->getTranslation()) { |
||
0 ignored issues
–
show
Are you sure the assignment to
$translation is correct as $this->getTranslation() (which targets Anomaly\Streams\Platform...Model::getTranslation() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
785 | $attributes[$field] = $translation->$field; |
||
786 | } |
||
787 | } |
||
788 | |||
789 | return $attributes; |
||
790 | } |
||
791 | |||
792 | /** |
||
793 | * Return the routable array information. |
||
794 | * |
||
795 | * @return array |
||
796 | */ |
||
797 | public function toRoutableArray() |
||
798 | { |
||
799 | return $this->toArray(); |
||
800 | } |
||
801 | |||
802 | private function alwaysFillable() |
||
803 | { |
||
804 | return false; |
||
805 | } |
||
806 | |||
807 | /** |
||
808 | * Determine if the given attribute exists. |
||
809 | * Make sure to skip where there could be an |
||
810 | * issue with relational "looking" properties. |
||
811 | * |
||
812 | * @param mixed $offset |
||
813 | * @return bool |
||
814 | */ |
||
815 | public function offsetExists($offset) |
||
816 | { |
||
817 | return !method_exists($this, $offset) && isset($this->$offset); |
||
818 | } |
||
819 | |||
820 | /** |
||
821 | * Get the criteria class. |
||
822 | * |
||
823 | * @return string |
||
824 | */ |
||
825 | public function getCriteriaName() |
||
826 | { |
||
827 | $criteria = substr(get_class($this), 0, -5) . 'Criteria'; |
||
828 | |||
829 | return class_exists($criteria) ? $criteria : EloquentCriteria::class; |
||
830 | } |
||
831 | |||
832 | /** |
||
833 | * Get the cascading actions. |
||
834 | * |
||
835 | * @return array |
||
836 | */ |
||
837 | public function getCascades() |
||
838 | { |
||
839 | return $this->cascades; |
||
840 | } |
||
841 | |||
842 | public function __get($key) |
||
843 | { |
||
844 | if ($this->hasHook($hook = 'get_' . $key)) { |
||
845 | return $this->call($hook, []); |
||
846 | } |
||
847 | |||
848 | return parent::__get($key); |
||
849 | } |
||
850 | |||
851 | public function __call($method, $parameters) |
||
852 | { |
||
853 | if ($this->hasHook($hook = snake_case($method))) { |
||
854 | return $this->call($hook, $parameters); |
||
855 | } |
||
856 | |||
857 | return parent::__call($method, $parameters); |
||
858 | } |
||
859 | |||
860 | /** |
||
861 | * Check if an attribute exists. |
||
862 | * |
||
863 | * @param string $key |
||
864 | * @return bool |
||
865 | */ |
||
866 | public function __isset($key) |
||
867 | { |
||
868 | return (in_array($key, $this->translatedAttributes) || parent::__isset($key)); |
||
869 | } |
||
870 | |||
871 | /** |
||
872 | * Return the string form of the model. |
||
873 | * |
||
874 | * @return string |
||
875 | */ |
||
876 | public function __toString() |
||
877 | { |
||
878 | return json_encode($this->toArray()); |
||
879 | } |
||
880 | |||
881 | /** |
||
882 | * Remove volatile cache from |
||
883 | * objects before serialization. |
||
884 | * |
||
885 | * @return array |
||
886 | */ |
||
887 | public function __sleep() |
||
888 | { |
||
889 | return array_diff(array_keys(get_object_vars($this)), ['cache']); |
||
890 | } |
||
891 | } |
||
892 |
Since your code implements the magic getter
_get
, this function will be called for any read access on an undefined variable. You can add the@property
annotation to your class or interface to document the existence of this variable.If the property has read access only, you can use the @property-read annotation instead.
Of course, you may also just have mistyped another name, in which case you should fix the error.
See also the PhpDoc documentation for @property.