Application   F
last analyzed

Complexity

Total Complexity 78

Size/Duplication

Total Lines 738
Duplicated Lines 0 %

Test Coverage

Coverage 72.5%

Importance

Changes 0
Metric Value
wmc 78
eloc 154
dl 0
loc 738
ccs 116
cts 160
cp 0.725
rs 2.16
c 0
b 0
f 0

47 Methods

Rating   Name   Duplication   Size   Complexity  
A addReadBy() 0 9 3
A getSubscriber() 0 3 1
A getPermissions() 0 10 3
A getAttachments() 0 6 2
A prependPersistingAnonymousUser() 0 5 2
A getStatus() 0 3 1
A getComments() 0 6 2
A isDraft() 0 3 1
A isReadBy() 0 7 2
A setProfiles() 0 4 1
A isUnreadBy() 0 3 1
A setKeywords() 0 4 1
A getProfiles() 0 6 2
A changeStatus() 0 9 1
A setCv() 0 4 1
A getRating() 0 12 5
A setPermissions() 0 4 1
A setContact() 0 7 2
A setUser() 0 15 4
A getUser() 0 7 3
A getJob() 0 3 1
A setJob() 0 7 1
A recalculateRatings() 0 15 4
A getCommentsMessage() 0 9 3
A setStatus() 0 7 2
A setSubscriber() 0 4 1
A getAttributes() 0 6 2
A getKeywords() 0 3 1
A setReadBy() 0 4 1
A getRefs() 0 6 2
A setFacts() 0 5 1
A setAttachments() 0 4 1
A setSummary() 0 4 1
A getSearchableProperties() 0 3 1
A getResourceId() 0 3 1
A getCv() 0 6 2
A setIsDraft() 0 4 1
A getFacts() 0 7 2
A getContact() 0 3 1
A setHistory() 0 4 1
A getReadBy() 0 3 1
A clearKeywords() 0 4 1
A getSummary() 0 3 1
A setComments() 0 4 1
A setAttributes() 0 4 1
A restoreAnonymousUser() 0 5 2
A getHistory() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like Application often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Application, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package Applications
4
 */
5
namespace Applications\Entity;
6
7
use Core\Entity\EntityInterface;
8
use Laminas\Permissions\Acl\Resource\ResourceInterface;
9
use Auth\Entity\UserInterface;
10
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
11
use Jobs\Entity\JobInterface;
12
use Doctrine\Common\Collections\Collection;
13
use Core\Entity\Collection\ArrayCollection;
14
use Core\Entity\Permissions;
15
use Core\Entity\PermissionsInterface;
16
use Core\Entity\AbstractIdentifiableModificationDateAwareEntity;
17
use Auth\Entity\InfoInterface;
18
use Cv\Entity\CvInterface;
19
use Core\Entity\DraftableEntityInterface;
20
use Auth\Entity\AnonymousUser;
21
22
/**
23
 * The application. This document holds the complete application. It references all attached data like
24
 * attachments, ratings, status changes. etc.
25
 *
26
 * @author mathias
27
 *
28
 * @ODM\Document(collection="applications", repositoryClass="Applications\Repository\Application")
29
 * @ODM\HasLifecycleCallbacks
30
 */
31
class Application extends AbstractIdentifiableModificationDateAwareEntity implements
32
    ApplicationInterface,
33
    ResourceInterface,
34
    DraftableEntityInterface
35
{
36
37
    /**
38
     * Refering job
39
     *
40
     * @var JobInterface
41
     * @ODM\ReferenceOne(targetDocument="Jobs\Entity\Job", storeAs="id", inversedBy="applications")
42
     * @ODM\Index
43
     */
44
    protected $job;
45
46
    /**
47
     * User, who owns the application
48
     *
49
     * @var UserInterface
50
     * @ODM\ReferenceOne(targetDocument="Auth\Entity\User", storeAs="id")
51
     * @ODM\Index
52
     */
53
    protected $user;
54
55
    protected $__anonymousUser__;
56
57
    /**
58
     * Token of the anonymous user created this application
59
     * if available
60
     * @ODM\Field(type="string", nullable="true")
61
     * @var string
62
     */
63
    protected $userToken;
64
65
    /**
66
     * Status of an application.
67
     *
68
     * @var StatusInterface
69
     * @ODM\EmbedOne(targetDocument="Applications\Entity\Status")
70
     */
71
    protected $status;
72
73
    /**
74
     * personal informations, contains firstname, lastname, email,
75
     * phone etc.
76
     *
77
     * @ODM\EmbedOne(targetDocument="Applications\Entity\Contact")
78
     */
79
    protected $contact;
80
81
    /**
82
     * The cover letter of an application
83
     *
84
     * @var String
85
     * @ODM\Field(type="string")
86
     */
87
    protected $summary;
88
89
    /**
90
     * The facts of this application.
91
     *
92
     * @ODM\EmbedOne(targetDocument="Applications\Entity\Facts")
93
     * @var FactsInterface
94
     */
95
    protected $facts;
96
97
    /**
98
     * Resume, containing employments, educations and skills
99
     *
100
     * @var CvInterface
101
     * @ODM\EmbedOne(targetDocument="Applications\Entity\Cv")
102
     */
103
    protected $cv;
104
105
    /**
106
     * multiple Attachments of an application
107
     *
108
     * @ODM\ReferenceMany(targetDocument="Applications\Entity\Attachment", storeAs="id", cascade={"persist", "remove"})
109
     */
110
    protected $attachments;
111
112
    /**
113
     * Searchable keywords.
114
     *
115
     * @var array
116
     * @ODM\Field(type="collection")
117
     */
118
    protected $keywords;
119
120
    /**
121
     * History on an application
122
     *
123
     * @var Collection
124
     * @ODM\EmbedMany(targetDocument="Applications\Entity\History")
125
     */
126
    protected $history;
127
128
    /**
129
     * Who has opened the detail view of the application. Contains an array of user ids, which has read this
130
     * application.
131
     *
132
     * @var array
133
     * @ODM\Field(type="collection")
134
     */
135
    protected $readBy = array();
136
137
    /**
138
     * Refering subscriber (Where did the application origin from).
139
     *
140
     * @ODM\ReferenceOne(targetDocument="Applications\Entity\Subscriber", cascade={"persist"}, storeAs="id")
141
     */
142
    protected $subscriber;
143
144
145
    /**
146
     * Recruiters can comment an application.
147
     *
148
     * @var Collection
149
     * @ODM\EmbedMany(targetDocument="Applications\Entity\Comment")
150
     */
151
    protected $comments;
152
153
    /**
154
     * Average rating from all comments.
155
     *
156
     * @var int
157
     * @ODM\Field(type="int")
158
     */
159
    protected $rating;
160
161
    /**
162
     * Assigned permissions.
163
     *
164
     * @var PermissionsInterface
165
     * @ODM\EmbedOne(targetDocument="Core\Entity\Permissions")
166
     */
167
    protected $permissions;
168
169
    /**
170
     * Internal references (DB denaturalism)
171
     *
172
     * @var InternalReferences
173
     * @ODM\EmbedOne(targetDocument="Applications\Entity\InternalReferences")
174
     */
175
    protected $refs;
176
177
    /**
178
     * Collection of social network profiles.
179
     *
180
     * @var Collection
181
     * @see \Auth\Entity\SocialProfiles\ProfileInterface
182
     * @ODM\EmbedMany(discriminatorField="_entity")
183
     */
184
    protected $profiles;
185
186
187
    /**
188
     * Flag indicating draft state of this application.
189
     *
190
     * @var bool
191
     * @ODM\Field(type="bool")
192
     */
193
    protected $isDraft = false;
194
195
    /**
196
     * Attributes like "privacy policy accepted" or "send by data as an CC".
197
     *
198
     * @var \Applications\Entity\Attributes
199
     * @ODM\EmbedOne(targetDocument="Applications\Entity\Attributes")
200
     */
201
    protected $attributes;
202
203
    /**
204
     * {@inheritDoc}
205
     * @ODM\PreUpdate
206
     * @ODM\PrePersist
207
     */
208
    public function recalculateRatings()
209
    {
210
        // Compute rating value.
211
        // @todo Need to know weather comments has changed or not.
212
        // Unfortunately, persistent collection gets no dirty flag,
213
        // if existing entries are changed....
214
        // We limit recalculates to the cases where comments gets loaded from
215
        // the database (which still does not neccessarly mean, there are changes...
216
217
        $comments = $this->getComments();
218
        if ($comments instanceof ArrayCollection // new Comments
219
            || $comments->isInitialized() // Comments were loaded and eventually changed (we do not know)
0 ignored issues
show
Bug introduced by
The method isInitialized() does not exist on Doctrine\Common\Collections\Collection. It seems like you code against a sub-type of Doctrine\Common\Collections\Collection such as Doctrine\Common\Collections\AbstractLazyCollection or Doctrine\ODM\MongoDB\Per...tentCollectionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

219
            || $comments->/** @scrutinizer ignore-call */ isInitialized() // Comments were loaded and eventually changed (we do not know)
Loading history...
220
            || $comments->isDirty() // new Comments added w/o initializing
0 ignored issues
show
Bug introduced by
The method isDirty() does not exist on Doctrine\Common\Collections\Collection. It seems like you code against a sub-type of Doctrine\Common\Collections\Collection such as Doctrine\ODM\MongoDB\Per...tentCollectionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

220
            || $comments->/** @scrutinizer ignore-call */ isDirty() // new Comments added w/o initializing
Loading history...
221
        ) {
222 1
            $this->getRating(/*recalculate*/ true);
223
        }
224 1
    }
225
226
    /**
227
     * {@inheritDoc}
228
     * @see \Laminas\Permissions\Acl\Resource\ResourceInterface::getResourceId()
229
     */
230
    public function getResourceId()
231
    {
232 2
        return 'Entity/Application';
233
    }
234 2
235
    /**
236
     * {@inheritDoc}
237
     *
238
     * @see \Core\Entity\DraftableEntityInterface::isDraft()
239
     */
240
    public function isDraft()
241 2
    {
242
        return $this->isDraft;
243 2
    }
244 2
245
    /**
246
     * {@inheritDoc}
247
     * @return \Applications\Entity\Application
248
     */
249
    public function setIsDraft($flag)
250
    {
251
        $this->isDraft = (bool) $flag;
252 4
        return $this;
253
    }
254 4
255
    /**
256
     * {@inheritDoc}
257
     *
258
     * @see \Applications\Entity\ApplicationInterface::getJob()
259
     */
260
    public function getJob()
261
    {
262 4
        return $this->job;
263
    }
264 4
265
    /**
266 4
     * {@inheritDoc}
267
     *
268 4
     * @return \Applications\Entity\Application
269
     */
270
    public function setJob(JobInterface $job)
271
    {
272
        $this->job = $job;
273
274
        $this->getRefs()->setJob($job);
275
276
        return $this;
277 1
    }
278
279 1
    /**
280
     * {@inheritDoc}
281
     *
282 1
     * @return Application
283 1
     * @see \Applications\Entity\ApplicationInterface::setUser()
284 1
     */
285
    public function setUser(UserInterface $user)
286
    {
287
        if ($this->user) {
288
            $this->getPermissions()->revoke($this->user, Permissions::PERMISSION_ALL, false);
289
        }
290
        $this->getPermissions()->grant($user, Permissions::PERMISSION_ALL);
291
        $this->user = $user;
292 4
293
        if ($user instanceof AnonymousUser) {
294 4
            $this->userToken = $user->getToken();
295
        } elseif ($this->userToken) {
296
            $this->userToken = null;
297
        }
298
299
        return $this;
300
    }
301
302
    /**
303
     * {@inheritDoc}
304
     *
305
     * @see \Applications\Entity\ApplicationInterface::getUser()
306
     */
307
    public function getUser()
308
    {
309
        if (!$this->user && $this->userToken) {
310
            $this->user = new AnonymousUser($this->userToken);
311
        }
312
313
        return $this->user;
314
    }
315
316
    /**
317
     *
318
     * @ODM\PrePersist
319
     * @ODM\PreUpdate
320
     * @ODM\PreFlush
321
     */
322
    public function prependPersistingAnonymousUser()
323
    {
324
        if ($this->user instanceof AnonymousUser) {
325
            $this->__anonymousUser__ = $this->user;
326
            $this->user = null;
327
        }
328
    }
329 5
330
    /**
331 5
     *
332 4
     * @ODM\PostPersist
333
     * @ODM\PostUpdate
334 5
     */
335 5
    public function restoreAnonymousUser()
336
    {
337
        if ($this->__anonymousUser__) {
338
            $this->user = $this->__anonymousUser__;
339
            $this->__anonymousUser__ = null;
340
        }
341
    }
342
343
    /**
344
     * {@inheritDoc
345
     * @return Application
346
     * @see \Applications\Entity\ApplicationInterface::setStatus()
347
     */
348
    public function setStatus($status)
349
    {
350
        if (!$status instanceof Status) {
351
            $status = new Status($status);
352
        }
353
        $this->status = $status;
354
        return $this;
355
    }
356
357
    /**
358
     * Modifies the state of an application.
359
     *
360
     * Creates a history entry.
361
     *
362 5
     * @param StatusInterface|string $status
363
     * @param string $message
364 5
     * @return Application
365
     */
366
    public function changeStatus($status, $message = '[System]')
367
    {
368
        $this->setStatus($status);
369
        $status = $this->getStatus(); // ensure StatusEntity
370
371
        $history = new History($status, $message);
372 3
373
        $this->getHistory()->add($history);
374 3
        return $this;
375
    }
376
377
    /**
378
     * {@inheritDoc}
379
     * @see \Applications\Entity\ApplicationInterface::getStatus()
380
     */
381
    public function getStatus()
382 2
    {
383
        return $this->status;
384 2
    }
385 1
386
    /**
387 2
     * {@inheritDoc}
388 2
     * @see \Applications\Entity\ApplicationInterface::getContact()
389
     * @return Contact
390
     */
391
    public function getContact()
392
    {
393
        return $this->contact;
394
    }
395
396 1
    /**
397
     * {@inheritDoc}
398 1
     * @see ApplicationInterface::setContact()
399 1
     * @return Application
400
     */
401
    public function setContact(InfoInterface $contact)
402
    {
403
        if (!$contact instanceof Contact) {
404
            $contact = new Contact($contact);
405
        }
406
        $this->contact = $contact;
407 1
        return $this;
408
    }
409 1
410
    /**
411
     * {@inheritDoc}
412 2
     * @see \Applications\Entity\ApplicationInterface::setSummary()
413
     * @return Application
414 2
     */
415
    public function setSummary($summary)
416 2
    {
417
        $this->summary = (string) $summary;
418
        return $this;
419 2
    }
420
421 2
    /**
422 1
     * {@inheritDoc}
423
     * @see \Applications\Entity\ApplicationInterface::getSummary()
424
     * @return Application
425 2
     */
426
    public function getSummary()
427
    {
428
        return $this->summary;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->summary returns the type string which is incompatible with the documented return type Applications\Entity\Application.
Loading history...
429
    }
430
431
    public function setFacts(FactsInterface $facts)
432
    {
433
        $this->facts = $facts;
434 1
435
        return $this;
436 1
    }
437 1
438
    public function getFacts()
439
    {
440
        if (!$this->facts) {
441
            $this->setFacts(new Facts());
442
        }
443
444 2
        return $this->facts;
445
    }
446 2
447 1
448
    /**
449 2
     * {@inheritDoc}
450
     * @see \Applications\Entity\ApplicationInterface::setCv()
451
     * @return Application
452
     */
453
    public function setCv(CvInterface $cv)
454
    {
455
        $this->cv = $cv;
456
        return $this;
457 4
    }
458
459 4
    /**
460 4
     * {@inheritDoc}
461
     * @see \Applications\Entity\ApplicationInterface::getCv()
462
     */
463
    public function getCv()
464
    {
465
        if (is_null($this->cv)) {
466
            $this->cv= new Cv();
467 4
        }
468
        return $this->cv;
469 4
    }
470 3
471
    /**
472 4
     * {@inheritDoc}
473
     * @see \Applications\Entity\ApplicationInterface::setAttachments()
474
     * @return Application
475
     */
476
    public function setAttachments(Collection $attachments)
477
    {
478
        $this->attachments = $attachments;
479
        return $this;
480
    }
481
482
    /**
483
     * {@inheritDoc}
484
     * @see \Applications\Entity\ApplicationInterface::getAttachments()
485
     */
486
    public function getAttachments()
487
    {
488
        if (!$this->attachments) {
489
            $this->setAttachments(new ArrayCollection());
490
        }
491
        return $this->attachments;
492
    }
493
494
    /**
495
     * {@inheritDoc}
496
     * @see \Applications\Entity\ApplicationInterface::setProfiles()
497
     * @return Application
498
     */
499
    public function setProfiles(Collection $profiles)
500
    {
501
        $this->profiles = $profiles;
502
        return $this;
503 2
    }
504
505 2
    /**
506 2
     * {@inheritDoc}
507
     * @see \Applications\Entity\ApplicationInterface::getProfiles()
508
     */
509
    public function getProfiles()
510
    {
511
        if (!$this->profiles) {
512
            $this->setProfiles(new ArrayCollection());
513 2
        }
514
        return $this->profiles;
515 2
    }
516 1
517
    /**
518 2
     * {@inheritDoc}
519
     * @see \Applications\Entity\ApplicationInterface::setHistory()
520
     * @return Application
521
     */
522
    public function setHistory(Collection $history)
523
    {
524
        $this->history = $history;
525
        return $this;
526 3
    }
527
528 3
    /**
529 3
     * {@inheritDoc}
530
     * @see \Applications\Entity\ApplicationInterface::getHistory()
531
     */
532
    public function getHistory()
533
    {
534
        if (null == $this->history) {
535
            $this->setHistory(new ArrayCollection());
536 1
        }
537
        return $this->history;
538 1
    }
539
540
    /**
541
     * {@inheritDoc}
542
     * @see \Applications\Entity\ApplicationInterface::setReadBy()
543
     * @return Application
544
     */
545
    public function setReadBy(array $userIds)
546 1
    {
547
        $this->readBy = $userIds;
548 1
        return $this;
549 1
    }
550
551 1
    /**
552 1
     * {@inheritDoc}
553
     * @see \Applications\Entity\ApplicationInterface::getReadBy()
554 1
     */
555
    public function getReadBy()
556
    {
557
        return $this->readBy;
558
    }
559
560
    /**
561 2
     * {@inheritDoc}
562
     * @see \Applications\Entity\ApplicationInterface::addReadBy()
563 2
     * @return Application
564
     */
565
    public function addReadBy($userOrId)
566
    {
567
        if ($userOrId instanceof UserInterface) {
568
            $userOrId = $userOrId->getId();
569
        }
570 3
        if (!in_array($userOrId, $this->readBy)) {
571
            $this->readBy[] = $userOrId;
572 3
        }
573 3
        return $this;
574
    }
575
576 3
    /**
577
     * {@inheritDoc}
578
     * @see \Applications\Entity\ApplicationInterface::isUnreadBy()
579
     */
580
    public function isUnreadBy($userOrId)
581
    {
582
        return !$this->isReadBy($userOrId);
583
    }
584 1
585
    /**
586 1
     * {@inheritDoc}
587
     * @see \Applications\Entity\ApplicationInterface::isReadBy()
588
     */
589
    public function isReadBy($userOrId)
590
    {
591
        if ($userOrId instanceof UserInterface) {
592
            $userOrId = $userOrId->getId();
593
        }
594 1
595
        return in_array($userOrId, $this->readBy);
596 1
    }
597 1
598
    /**
599
     * {@inheritDoc}
600
     * @see \Applications\Entity\ApplicationInterface::getSubscriber()
601
     * @return \Applications\Entity\SubscriberInterface
602
     */
603
    public function getSubscriber()
604 4
    {
605
        return $this->subscriber;
606 4
    }
607 4
608 4
    /**
609
     * {@inheritDoc}
610
     * @see \Applications\Entity\ApplicationInterface::setSubscriber()
611 4
     * @return Application
612
     */
613 4
    public function setSubscriber(EntityInterface $subscriber)
614
    {
615
        $this->subscriber = $subscriber;
616
        return $this;
617
    }
618
619
    /**
620
     * {@inheritDoc}
621 4
     * @see \Core\Entity\PermissionsAwareInterface::getPermissions()
622
     */
623 4
    public function getPermissions()
624 4
    {
625
        if (!$this->permissions) {
626
            $permissions = new Permissions('Application');
627
            if ($this->user) {
628
                $permissions->grant($this->user, Permissions::PERMISSION_ALL);
629
            }
630
            $this->setPermissions($permissions);
631 4
        }
632
        return $this->permissions;
633 4
    }
634 4
635
    /**
636 4
     * {@inheritDoc}
637
     * @see \Core\Entity\PermissionsAwareInterface::setPermissions()
638
     * @return Application
639
     */
640
    public function setPermissions(PermissionsInterface $permissions)
641
    {
642
        $this->permissions = $permissions;
643
        return $this;
644
    }
645
646
    /**
647
     * {@inheritDoc}
648
     * @see \Applications\Entity\ApplicationInterface::getRefs()
649
     */
650
    public function getRefs()
651
    {
652
        if (!$this->refs) {
653
            $this->refs = new InternalReferences();
654
        }
655
        return $this->refs;
656
    }
657
658
    /**
659
     * {@inheritDoc}
660
     * @deprecated
661
     * @see \Core\Entity\SearchableEntityInterface::getSearchableProperties()
662
     */
663
    public function getSearchableProperties()
664
    {
665
        return array('summary', 'commentsMessage');
666
    }
667
668
    /**
669
     * {@inheritDoc}
670
     * @deprecated
671
     * @see \Core\Entity\SearchableEntityInterface::setKeywords()
672
     * @return Application
673
     */
674
    public function setKeywords(array $keywords)
675
    {
676
        $this->keywords = $keywords;
677
        return $this;
678
    }
679
680
    /**
681
     * {@inheritDoc}
682
     * @deprecated
683
     * @see \Core\Entity\SearchableEntityInterface::getKeywords()
684
     */
685
    public function getKeywords()
686
    {
687 2
        return $this->keywords;
688
    }
689 2
690 1
    /**
691
     * {@inheritDoc}
692 2
     * @deprecated
693
     * @see \Core\Entity\SearchableEntityInterface::clearKeywords()
694
     * @return Application
695
     */
696
    public function clearKeywords()
697
    {
698
        $this->keywords = array();
699
        return $this;
700 2
    }
701
702 2
    /**
703 2
     * {@inheritDoc}
704
     * @see \Applications\Entity\ApplicationInterface::getComments()
705
     */
706
    public function getComments()
707
    {
708
        if (!$this->comments) {
709
            $this->setComments(new ArrayCollection());
710
        }
711
        return $this->comments;
712
    }
713
714
    /**
715
     * {@inheritDoc}
716
     * @see \Applications\Entity\ApplicationInterface::setComments()
717
     * @return Application
718
     */
719
    public function setComments(ArrayCollection $comments)
720
    {
721
        $this->comments = $comments;
722
        return $this;
723
    }
724
725
    /**
726
     * @return array
727
     */
728
    public function getCommentsMessage()
729
    {
730
        $comments = array();
731
        if ($this->comments) {
732
            foreach ($this->getComments() as $comment) {
733
                $comments[] = $comment->getMessage();
734
            }
735
        }
736
        return $comments;
737
    }
738 2
739
    /**
740 2
     * {@inheritDoc}
741 2
     * @see \Applications\Entity\ApplicationInterface::getRating()
742
     */
743
    public function getRating($recalculate = false)
744 2
    {
745
        if ($recalculate || null === $this->rating) {
746 2
            $sum = 0;
747 1
            $count = 0;
748
            foreach ($this->getComments() as $comment) {
749 2
                $sum += $comment->getRating()->getAverage();
750
                $count += 1;
751
            }
752
            $this->rating = 0 == $count ? 0 : round($sum / $count);
0 ignored issues
show
introduced by
The condition 0 == $count is always true.
Loading history...
753
        }
754
        return $this->rating;
755
    }
756
757
    public function setAttributes(Attributes $attributes)
758
    {
759
        $this->attributes = $attributes;
760
        return $this;
761
    }
762
763
    public function getAttributes()
764
    {
765
        if (!$this->attributes) {
766
            $this->setAttributes(new Attributes());
767
        }
768
        return $this->attributes;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->attributes returns the type Applications\Entity\Attributes which is incompatible with the return type mandated by Applications\Entity\Appl...erface::getAttributes() of Core\Entity\Collection\ArrayCollection.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
769
    }
770
}
771