Job   F
last analyzed

Complexity

Total Complexity 113

Size/Duplication

Total Lines 1121
Duplicated Lines 0 %

Test Coverage

Coverage 86.15%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 113
eloc 231
dl 0
loc 1121
ccs 224
cts 260
cp 0.8615
rs 2
c 1
b 1
f 0

73 Methods

Rating   Name   Duplication   Size   Complexity  
A setContactEmail() 0 4 1
A makeSnapshot() 0 4 1
A setCompany() 0 4 1
A getSnapshotGenerator() 0 8 1
A setPortals() 0 4 1
A getTemplate() 0 7 2
A setDatePublishStart() 0 10 4
A getApplications() 0 3 1
A isDraft() 0 3 1
A setStatus() 0 6 2
A setSalary() 0 5 1
A setPermissions() 0 4 1
A getTitle() 0 3 1
A setAtsEnabled() 0 4 1
A getUriApply() 0 3 1
A getReference() 0 3 1
A unsetOrganization() 0 9 3
A getPublisher() 0 14 4
A getOrganization() 0 3 1
A setUriApply() 0 4 1
A setApplications() 0 4 1
A getLogoRef() 0 9 3
A setHistory() 0 4 1
A setLocations() 0 4 1
A setLink() 0 4 1
A setLocation() 0 4 1
A setApplyId() 0 4 1
A getAtsMode() 0 7 2
A changeStatus() 0 9 1
A setTitle() 0 4 1
A setOrganization() 0 11 2
A getDatePublishStart() 0 3 1
A delete() 0 5 1
A getCompany() 0 7 3
A getContactEmail() 0 11 4
A setDatePublishEnd() 0 10 3
A getHistory() 0 6 2
A setClassifications() 0 5 1
A getAtsEnabled() 0 3 1
A getLocation() 0 12 4
A unsetUser() 0 10 3
A getLocations() 0 6 2
A setUriPublisher() 0 4 1
A setAtsMode() 0 5 1
A getUnreadApplications() 0 3 1
A setPublisherReference() 0 5 1
A getTemplateValues() 0 6 2
A getDatePublishEnd() 0 3 1
A setReference() 0 4 1
A getUriPublisher() 0 3 1
A getTermsAccepted() 0 3 1
A isDeleted() 0 3 1
A setTermsAccepted() 0 4 1
A getLatestSnapshot() 0 3 1
A hasSnapshotDraft() 0 4 2
A getLink() 0 3 1
A isActive() 0 3 3
A setIsDraft() 0 4 1
A getLanguage() 0 3 1
A setTemplate() 0 4 1
A getSalary() 0 7 2
A setUser() 0 8 2
A getClassifications() 0 7 2
A getPermissions() 0 11 3
A setLanguage() 0 4 1
A getResourceId() 0 3 1
A getUser() 0 3 1
A setLogoRef() 0 4 1
A setTemplateValues() 0 7 2
A getPortals() 0 3 1
A getApplyId() 0 7 2
A getStatus() 0 7 2
A getSnapshots() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Job 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 Job, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @copyright https://yawik.org/COPYRIGHT.php
6
 * @license   MIT
7
 */
8
9
namespace Jobs\Entity;
10
11
use Core\Entity\AbstractIdentifiableModificationDateAwareEntity as BaseEntity;
12
use Core\Entity\ClonePropertiesTrait;
13
use Core\Entity\AttachableEntityTrait;
14
use Core\Entity\EntityInterface;
15
use Core\Entity\MetaDataProviderTrait;
16
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
17
use Doctrine\Common\Collections\Collection;
18
use Auth\Entity\UserInterface;
19
use Core\Entity\Permissions;
20
use Core\Entity\PermissionsInterface;
21
use Organizations\Entity\Organization;
22
use Organizations\Entity\OrganizationInterface;
23
use Core\Entity\DraftableEntityInterface;
24
use Core\Entity\Collection\ArrayCollection;
25
use Core\Entity\SnapshotGeneratorProviderInterface;
26
use Laminas\I18n\Validator\DateTime;
27
28
/**
29
 * The job model
30
 *
31
 * @ODM\Document(collection="jobs", repositoryClass="Jobs\Repository\Job")
32
 * @ODM\Indexes({
33
 *     @ODM\Index(keys={"datePublishStart.date"="asc"})
34
 * })
35
 *
36
 * @author Mathias Gelhausen <[email protected]>
37
 * @author Mathias Weitz <[email protected]>
38
 * @author Carsten Bleek <[email protected]>
39
 * @since 0.29 add temporary isDeleted flag and corresponding delete() method.
40
 */
41
class Job extends BaseEntity implements
42
    JobInterface,
43
                                        DraftableEntityInterface,
44
                                        SnapshotGeneratorProviderInterface
45
{
46
    use AttachableEntityTrait, MetaDataProviderTrait, ClonePropertiesTrait;
47
48
49
    private $cloneProperties = [
0 ignored issues
show
introduced by
The private property $cloneProperties is not used, and could be removed.
Loading history...
50
        'classifications', 'atsMode', 'salary',
51
    ];
52
53
    /**
54
     * unique ID of a job posting used by applications to reference
55
     * a job
56
     *
57
     * @var String
58
     * @ODM\Field(type="string") @ODM\Index
59
     **/
60
    protected $applyId;
61
62
    /**
63
     * title of a job posting
64
     *
65
     * @var String
66
     * @ODM\Field(type="string")
67
     */
68
    protected $title;
69
70
71
    /**
72
     * name of the publishing company
73
     *
74
     * @var String
75
     * @ODM\Field(type="string")
76
     */
77
    protected $company;
78
79
    /**
80
     * publishing company
81
     *
82
     * @var OrganizationInterface
83
     * @ODM\ReferenceOne (targetDocument="\Organizations\Entity\Organization", storeAs="id", inversedBy="jobs")
84
     * @ODM\Index
85
     */
86
    protected $organization;
87
88
89
    /**
90
     * Email Address, which is used to send notifications about e.g. new applications.
91
     *
92
     * @var String
93
     * @ODM\Field(type="string")
94
     **/
95
    protected $contactEmail;
96
97
    /**
98
     * the owner of a Job Posting
99
     *
100
     * @var UserInterface $user
101
     * @ODM\ReferenceOne(targetDocument="\Auth\Entity\User", storeAs="id")
102
     * @ODM\Index
103
     */
104
    protected $user;
105
106
    /**
107
     * all applications of a certain jobad
108
     *
109
     * @var Collection
110
     * @ODM\ReferenceMany(targetDocument="Applications\Entity\Application", storeAs="id", mappedBy="job",
111
     *                    repositoryMethod="loadApplicationsForJob")
112
     */
113
    protected $applications;
114
115
    /**
116
     * new applications
117
     *
118
     * @ODM\ReferenceMany(targetDocument="Applications\Entity\Application",
119
     *                    repositoryMethod="loadUnreadApplicationsForJob", mappedBy="job")
120
     * @var Int
121
     */
122
    protected $unreadApplications;
123
124
    /**
125
     * language of the job posting. Languages are ISO 639-1 coded
126
     *
127
     * @var String
128
     * @ODM\Field(type="string")
129
     */
130
    protected $language;
131
132
    /**
133
     * location of the job posting. This is a plain text, which describes the location in
134
     * search e.g. results.
135
     *
136
     * @var String
137
     * @ODM\Field(type="string")
138
     */
139
    protected $location;
140
141
    /**
142
     * locations of the job posting. This collection contains structured coordinates,
143
     * postal codes, city, region, and country names
144
     *
145
     * @var Collection
146
     * @ODM\EmbedMany(targetDocument="Jobs\Entity\Location")
147
     */
148
    protected $locations;
149
150
    /**
151
     * Link which points to the job posting
152
     *
153
     * @var String
154
     * @ODM\Field(type="string")
155
     **/
156
    protected $link;
157
158
    /**
159
     * publishing date of a job posting
160
     *
161
     * @var String
162
     * @ODM\Field(type="tz_date")
163
     */
164
    protected $datePublishStart;
165
166
    /**
167
     * end date of a job posting
168
     *
169
     * @var String
170
     * @ODM\Field(type="tz_date")
171
     */
172
    protected $datePublishEnd;
173
174
    /**
175
     * Status of the job posting
176
     *
177
     * @var Status
178
     * @ODM\EmbedOne(targetDocument="Jobs\Entity\Status")
179
     * @ODM\Index
180
     */
181
    protected $status;
182
183
    /**
184
     * History on an job posting
185
     *
186
     * @var Collection
187
     * @ODM\EmbedMany(targetDocument="Jobs\Entity\History")
188
     */
189
    protected $history;
190
191
    /**
192
     * Flag, privacy policy is accepted or not.
193
     *
194
     * @var bool
195
     * @ODM\Field(type="bool")
196
     */
197
    protected $termsAccepted;
198
199
    /**
200
     * Reference of a job opening, on which an applicant can refer to.
201
     *
202
     * @var String
203
     * @ODM\Field(type="string")
204
     */
205
    protected $reference;
206
207
    /**
208
     * Unified Resource Locator to the company-Logo
209
     *
210
     * @var String
211
     * @ODM\Field(type="string")
212
     */
213
    protected $logoRef;
214
215
    /**
216
     * Template-Name
217
     *
218
     * @var String
219
     * @ODM\Field(type="string")
220
     */
221
    protected $template;
222
223
    /**
224
     * Application link.
225
     *
226
     * @var String
227
     * @ODM\Field(type="string")
228
     */
229
    protected $uriApply;
230
231
    /**
232
     * Unified Resource Locator the Yawik, which handled this job first - so
233
     * does know who is the one who has commited this job.
234
     *
235
     * @var String
236
     * @ODM\Field(type="string")
237
     */
238
    protected $uriPublisher;
239
240
    /**
241
     * @var
242
     * @ODM\EmbedMany(targetDocument="Jobs\Entity\Publisher")
243
     */
244
    protected $publisher;
245
246
    /**
247
     * The ATS mode entity.
248
     *
249
     * @var AtsMode
250
     * @ODM\EmbedOne(targetDocument="Jobs\Entity\AtsMode")
251
     */
252
    protected $atsMode;
253
254
    /**
255
     * this must be enabled to use applications forms etc. for this job or
256
     * to see number of applications in the list of applications
257
     *
258
     * @var Boolean
259
     *
260
     * @ODM\Field(type="bool")
261
     */
262
    protected $atsEnabled;
263
264
    /**
265
     * The Salary entity.
266
     *
267
     * @var Salary
268
     * @ODM\EmbedOne(targetDocument="Jobs\Entity\Salary")
269
     */
270
    protected $salary;
271
272
    /**
273
     * Permissions
274
     *
275
     * @var PermissionsInterface
276
     * @ODM\EmbedOne(targetDocument="\Core\Entity\Permissions")
277
     */
278
    protected $permissions;
279
280
    /**
281
     * The actual name of the organization.
282
     *
283
     * @var TemplateValues
284
     * @ODM\EmbedOne(targetDocument="\Jobs\Entity\TemplateValues")
285
     */
286
    protected $templateValues;
287
288
289
    /**
290
     * Can contain various Portals
291
     *
292
     * @var array
293
     * @ODM\Field(type="collection")
294
     */
295
    protected $portals = array();
296
297
    /**
298
     * Flag indicating draft state of this job.
299
     *
300
     * @var bool
301
     * @ODM\Field(type="bool")
302
     */
303
    protected $isDraft = false;
304
305
    /**
306
     * Classifications
307
     *
308
     * @ODM\EmbedOne(targetDocument="\Jobs\Entity\Classifications")
309
     * @var Classifications
310
     * @since 0.29
311
     */
312
    protected $classifications;
313
314
    /**
315
     * Delete flag.
316
     *
317
     * @internal
318
     *      This is meant as a temporary flag, until
319
     *      SoftDelete is implemented.
320
     *
321
     * @ODM\Field(type="bool")
322
     * @var bool
323
     * @since 0.29
324
     */
325
    protected $isDeleted = false;
326
327
    /**
328
     *
329
     * @ODM\ReferenceMany(targetDocument="\Jobs\Entity\JobSnapshot", mappedBy="snapshotEntity", sort={"snapshotMeta.dateCreated"="desc"})
330
     * @var JobSnapshot[]
331
     */
332
    protected $snapshots;
333
334
    /**
335
     * @ODM\ReferenceOne(targetDocument="\Jobs\Entity\JobSnapshot", mappedBy="snapshotEntity", sort={"snapshotMeta.dateCreated"="desc"})
336
     *
337
     * @var JobSnapshot
338
     */
339
    protected $latestSnapshot;
340
341
342
    public function getSnapshots()
343
    {
344
        return $this->snapshots;
345
    }
346
347
    public function getLatestSnapshot()
348
    {
349
        return $this->latestSnapshot;
350
    }
351
352
    public function hasSnapshotDraft()
353
    {
354
        $snapshot = $this->getLatestSnapshot();
355
        return $snapshot && $snapshot->getSnapshotMeta()->hasStatus(JobSnapshotStatus::ACTIVE);
356
    }
357
358
    /**
359
     * @return string
360 1
     */
361
    public function getResourceId()
362 1
    {
363
        return 'Entity/Jobs/Job';
364
    }
365
366
    /**
367
     * @see \Jobs\Entity\JobInterface::setApplyId()
368
     * @param String $applyId
369
     * @return \Jobs\Entity\JobInterface
370 1
     */
371
    public function setApplyId($applyId)
372 1
    {
373 1
        $this->applyId = (string) $applyId;
374
        return $this;
375
    }
376
    /**
377
     * @see \Jobs\Entity\JobInterface::getApplyId()
378
     * @return String
379 3
     */
380
    public function getApplyId()
381 3
    {
382
        if (!isset($this->applyId)) {
383 2
            // take the entity-id as a default
384
            $this->applyId = $this->id;
385 3
        }
386
        return $this->applyId;
387
    }
388
389
    /**
390
     * Gets the title of a job posting
391
     *
392
     * @return string
393 4
     */
394
    public function getTitle()
395 4
    {
396
        return $this->title;
397
    }
398
399
    /**
400
     * Sets the title of a job posting
401
     *
402
     * @see \Jobs\Entity\JobInterface::setTitle()
403
     * @param String $title
404
     * @return \Jobs\Entity\JobInterface
405 4
     */
406
    public function setTitle($title)
407 4
    {
408 4
        $this->title = (string) $title;
409
        return $this;
410
    }
411
412
    /**
413
     * Gets the name oof the company. If there is an organization assigned to the
414
     * job posting. Take the name of the organization.
415
     *
416
     * @param bool $useOrganizationEntity Get the name from the organization entity, if it is available.
417
     * @see \Jobs\Entity\JobInterface::getCompany()
418
     * @return string
419 4
     */
420
    public function getCompany($useOrganizationEntity = true)
421 4
    {
422 1
        if ($this->organization && $useOrganizationEntity) {
423
            return $this->organization->getOrganizationName()->getName();
424
        }
425 3
426
        return $this->company;
427
    }
428
429
    /**
430
     * (non-PHPdoc)
431
     * @see \Jobs\Entity\JobInterface::setCompany()
432 3
     */
433
    public function setCompany($company)
434 3
    {
435 3
        $this->company = $company;
436
        return $this;
437
    }
438
439
    /**
440
    * (non-PHPdoc)
441
    * @see \Jobs\Entity\JobInterface::getOrganization()
442 4
    */
443
    public function getOrganization()
444 4
    {
445
        return $this->organization;
446
    }
447
448
    /**
449
     * @inheritdoc
450 3
     */
451
    public function setOrganization(OrganizationInterface $organization = null)
452 3
    {
453
        $permissions = $this->getPermissions();
454 3
455
        if ($this->organization) {
456
            $permissions->revoke($this->organization, null, false);
457 3
        }
458 3
        $this->organization = $organization;
459
        $permissions->grant($organization);
460 3
461
        return $this;
462
    }
463
464
465
466
    /**
467
     * (non-PHPdoc)
468
     * @see \Jobs\Entity\JobInterface::getContactEmail()
469 3
     */
470
    public function getContactEmail()
471 3
    {
472 2
        if (false !== $this->contactEmail && !$this->contactEmail) {
473 2
            $user = $this->getUser();
474 2
            $email = false;
475 1
            if (isset($user)) {
476
                $email = $user->getInfo()->getEmail();
477 2
            }
478
            $this->setContactEmail($email);
479 3
        }
480
        return $this->contactEmail;
481
    }
482
483
    /**
484
     * (non-PHPdoc)
485
     * @see \Jobs\Entity\JobInterface::setContactEmail()
486 3
     */
487
    public function setContactEmail($email)
488 3
    {
489 3
        $this->contactEmail = (string) $email;
490
        return $this;
491
    }
492
493
    /**
494
     * (non-PHPdoc)
495
     * @see \Jobs\Entity\JobInterface::setLanguage()
496 1
     */
497
    public function setLanguage($language)
498 1
    {
499 1
        $this->language = $language;
500
        return $this;
501
    }
502
    /**
503
     * (non-PHPdoc)
504
     * @see \Jobs\Entity\JobInterface::getLanguage()
505 2
     */
506
    public function getLanguage()
507 2
    {
508
        return $this->language;
509
    }
510
    /**
511
     * (non-PHPdoc)
512
     * @see \Jobs\Entity\JobInterface::setLocation()
513 1
     */
514
    public function setLocation($location)
515 1
    {
516 1
        $this->location = $location;
517
        return $this;
518
    }
519
    /**
520
     * (non-PHPdoc)
521
     * @see \Jobs\Entity\JobInterface::getLocation()
522 2
     */
523
    public function getLocation()
524 2
    {
525 1
        if (null === $this->location) {
526 1
            $array=[];
527
            if (null != $this->locations) {
528
                foreach ($this->locations as $location) { /* @var \Core\Entity\LocationInterface $location */
529
                    $array[]=(string) $location;
530
                }
531
                return implode(', ', $array);
532
            }
533 2
        }
534
        return $this->location;
535
    }
536
    /**
537
     * (non-PHPdoc)
538
     * @see \Jobs\Entity\JobInterface::setLocations()
539 3
     */
540
    public function setLocations($locations)
541 3
    {
542 3
        $this->locations = $locations;
543
        return $this;
544
    }
545
    /**
546
     * (non-PHPdoc)
547
     * @see \Jobs\Entity\JobInterface::getLocations()
548 3
     */
549
    public function getLocations()
550 3
    {
551 2
        if (!$this->locations) {
552
            $this->setLocations(new ArrayCollection());
553 3
        }
554
        return $this->locations;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->locations returns the type Doctrine\Common\Collections\Collection which is incompatible with the return type mandated by Jobs\Entity\JobInterface::getLocations() of string.

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...
555
    }
556
    /**
557
     * (non-PHPdoc)
558
     * @see \Jobs\Entity\JobInterface::setUser()
559 6
     */
560
    public function setUser(UserInterface $user)
561 6
    {
562 1
        if ($this->user) {
563
            $this->getPermissions()->revoke($this->user, Permissions::PERMISSION_ALL, false);
564 6
        }
565 6
        $this->user = $user;
566 6
        $this->getPermissions()->grant($user, Permissions::PERMISSION_ALL);
567
        return $this;
568
    }
569
    /**
570
     * (non-PHPdoc)
571
     * @see \Jobs\Entity\JobInterface::getUser()
572 7
     */
573
    public function getUser()
574 7
    {
575
        return $this->user;
576
    }
577 1
578
    public function unsetUser($removePermissions = true)
579 1
    {
580 1
        if ($this->user) {
581 1
            if ($removePermissions) {
582
                $this->getPermissions()->revoke($this->user, Permissions::PERMISSION_ALL);
583 1
            }
584
            $this->user=null;
585
        }
586 1
587
        return $this;
588
    }
589 1
590
    public function unsetOrganization($removePermissions = true)
591 1
    {
592 1
        if ($this->organization && $removePermissions) {
593
            $this->getPermissions()->revoke($this->organization, Permissions::PERMISSION_ALL);
594
        }
595 1
596
        $this->organization = null;
597 1
598
        return $this;
599
    }
600
601
    /**
602
     * (non-PHPdoc)
603
     * @see \Jobs\Entity\JobInterface::setApplications()
604 1
     */
605
    public function setApplications(Collection $applications)
606 1
    {
607 1
        $this->applications = $applications;
608
        return $this;
609
    }
610
611
    /**
612
     * (non-PHPdoc)
613
     * @see \Jobs\Entity\JobInterface::getApplications()
614 2
     */
615
    public function getApplications()
616 2
    {
617
        return $this->applications;
618
    }
619
620
    /**
621
     * Gets the number of unread applications
622
     * @return Collection
623
     */
624
    public function getUnreadApplications()
625
    {
626
        return $this->unreadApplications;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->unreadApplications returns the type integer which is incompatible with the documented return type Doctrine\Common\Collections\Collection.
Loading history...
627
    }
628
    /**
629
     * (non-PHPdoc)
630
     * @see \Jobs\Entity\JobInterface::getLink()
631 2
     */
632
    public function getLink()
633 2
    {
634
        return $this->link;
635
    }
636
    /**
637
     * (non-PHPdoc)
638
     * @see \Jobs\Entity\JobInterface::setLink()
639 1
     */
640
    public function setLink($link)
641 1
    {
642 1
        $this->link = $link;
643
        return $this;
644
    }
645
    /**
646
     * (non-PHPdoc)
647
     * @see \Jobs\Entity\JobInterface::getDatePublishStart()
648 4
     */
649
    public function getDatePublishStart()
650 4
    {
651
        return $this->datePublishStart;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->datePublishStart returns the type string which is incompatible with the return type mandated by Jobs\Entity\JobInterface::getDatePublishStart() of DateTime.

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...
652
    }
653
    /**
654
     * (non-PHPdoc)
655
     * @param string $datePublishStart
656
     * @see \Jobs\Entity\JobInterface::setDatePublishStart()
657
     * @return $this
658 2
     */
659
    public function setDatePublishStart($datePublishStart = null)
660 2
    {
661 1
        if (!isset($datePublishStart) || is_string($datePublishStart)) {
0 ignored issues
show
introduced by
The condition is_string($datePublishStart) is always true.
Loading history...
662 1
            $datePublishStart = new \DateTime($datePublishStart);
663
        } elseif (!$datePublishStart instanceof \DateTime) {
664
            throw new \InvalidArgumentException('Expected object of type \DateTime');
665
        }
666 2
667 2
        $this->datePublishStart = $datePublishStart;
0 ignored issues
show
Documentation Bug introduced by
It seems like $datePublishStart of type DateTime is incompatible with the declared type string of property $datePublishStart.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
668
        return $this;
669
    }
670
671
    /**
672
     * (non-PHPdoc)
673
     * @see \Jobs\Entity\JobInterface::getDatePublishStart()
674 4
     */
675
    public function getDatePublishEnd()
676 4
    {
677
        return $this->datePublishEnd;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->datePublishEnd returns the type string which is incompatible with the return type mandated by Jobs\Entity\JobInterface::getDatePublishEnd() of DateTime.

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...
678
    }
679
    /**
680
     * (non-PHPdoc)
681
     * @param string $datePublishEnd
682
     * @see \Jobs\Entity\JobInterface::setDatePublishEnd()
683
     * @return $this
684 2
     */
685
    public function setDatePublishEnd($datePublishEnd = null)
686 2
    {
687 1
        if (is_string($datePublishEnd)) {
688 1
            $datePublishEnd = new \DateTime($datePublishEnd);
689
        } elseif (!$datePublishEnd instanceof \DateTime) {
690
            throw new \InvalidArgumentException('Expected object of type \DateTime');
691
        }
692 2
693 2
        $this->datePublishEnd = $datePublishEnd;
0 ignored issues
show
Documentation Bug introduced by
It seems like $datePublishEnd of type DateTime is incompatible with the declared type string of property $datePublishEnd.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
694
        return $this;
695
    }
696
697
    /**
698
     * Modifies the state of an application.
699
     *
700
     * Creates a history entry.
701
     *
702
     * @param StatusInterface|string $status
703
     * @param string $message
704
     * @return Job
705 6
     */
706
    public function changeStatus($status, $message = '[System]')
707 6
    {
708 6
        $this->setStatus($status);
709
        $status = $this->getStatus(); // ensure StatusEntity
710 6
711
        $history = new History($status, $message);
712 6
713 6
        $this->getHistory()->add($history);
714
        return $this;
715
    }
716
717
    /**
718
     * (non-PHPdoc)
719
     * @see \Jobs\Entity\JobInterface::getStatus()
720 13
     */
721
    public function getStatus()
722 13
    {
723 1
        if (!$this->status) {
724
            $this->setStatus(StatusInterface::CREATED);
725
        }
726 13
727
        return $this->status;
728
    }
729
    /**
730
     * (non-PHPdoc)
731
     * @see \Jobs\Entity\JobInterface::setStatus()
732 17
     */
733
    public function setStatus($status)
734 17
    {
735 11
        if (!$status instanceof Status) {
736
            $status = new Status($status);
737 17
        }
738
        $this->status = $status;
739
    }
740
741
    /**
742
     * {@inheritDoc}
743
     * @see JobInterface::setHistory()
744
     * @return Job
745 8
     */
746
    public function setHistory(Collection $history)
747 8
    {
748 8
        $this->history = $history;
749
        return $this;
750
    }
751
752
    /**
753
     * {@inheritDoc}
754
     * @see JobInterface::getHistory()
755 8
     */
756
    public function getHistory()
757 8
    {
758 7
        if (null == $this->history) {
759
            $this->setHistory(new ArrayCollection());
760 8
        }
761
        return $this->history;
762
    }
763
764
    /**
765
     * {@inheritDoc}
766
     * @see JobInterface::setTermsAccepted()
767
     * @return self
768 3
     */
769
    public function setTermsAccepted($termsAccepted)
770 3
    {
771 3
        $this->termsAccepted = $termsAccepted;
772
        return $this;
773
    }
774
775
    /**
776
     * {qinheritDoc}
777
     * @see JobInterface::getTermsAccepted()
778 4
     */
779
    public function getTermsAccepted()
780 4
    {
781
        return $this->termsAccepted;
782
    }
783
784
    /**
785
     * (non-PHPdoc)
786
     * @see JobInterface::getReference()
787 2
     */
788
    public function getReference()
789 2
    {
790
        return $this->reference;
791
    }
792
    /**
793
     * (non-PHPdoc)
794
     * @see JobInterface::setReference()
795 1
     */
796
    public function setReference($reference)
797 1
    {
798 1
        $this->reference = $reference;
799
        return $this;
800
    }
801 6
802
    public function setAtsMode(AtsMode $mode)
803 6
    {
804
        $this->atsMode = $mode;
805 6
806
        return $this;
807
    }
808 6
809
    public function getAtsMode()
810 6
    {
811 2
        if (!$this->atsMode) {
812
            $this->setAtsMode(new AtsMode(AtsMode::MODE_INTERN));
813
        }
814 6
815
        return $this->atsMode;
816
    }
817
818
819
    /**
820
     * checks, weather a job is enabled for getting applications
821
     * @return boolean
822 3
     */
823
    public function getAtsEnabled()
824 3
    {
825
        return $this->atsEnabled;
826
    }
827
    /**
828
     * enables a job add to receive applications
829
     *
830
     * @param boolean $atsEnabled
831
     * @return \Jobs\Entity\Job
832 2
     */
833
    public function setAtsEnabled($atsEnabled)
834 2
    {
835 2
        $this->atsEnabled = $atsEnabled;
836
        return $this;
837
    }
838
839
    /**
840
     * @param \Jobs\Entity\Salary $salary
841
     *
842
     * @return self
843 1
     */
844
    public function setSalary(Salary $salary)
845 1
    {
846
        $this->salary = $salary;
847 1
848
        return $this;
849
    }
850
851
    /**
852
     * @return \Jobs\Entity\Salary
853 1
     */
854
    public function getSalary()
855 1
    {
856 1
        if (!$this->salary) {
857
            $this->setSalary(new Salary());
858
        }
859 1
860
        return $this->salary;
861
    }
862
863
    /**
864
     * returns an uri to the organization logo.
865
     *
866
     * @return string
867 2
     */
868
    public function getLogoRef()
869
    {
870 2
        /** @var $organization Organization */
871 2
        $organization = $this->organization;
872
        if (is_object($organization) && $organization->getImage()) {
873
            $organizationImage = $organization->getImage();
874
            return "/file/Organizations.OrganizationImage/" . $organizationImage->getId();
875 2
        }
876
        return $this->logoRef;
877
    }
878
    /**
879
     * Set the uri to the organisations logo
880
     *
881
     * @param string $logoRef
882
     * @return \Jobs\Entity\Job
883 1
     */
884
    public function setLogoRef($logoRef)
885 1
    {
886 1
        $this->logoRef = $logoRef;
887
        return $this;
888
    }
889
890
    /**
891
     *
892
     *
893
     * @return string
894 3
     */
895
    public function getTemplate()
896 3
    {
897 3
        $template = $this->template;
898 2
        if (empty($template)) {
899
            $template = 'default';
900 3
        }
901
        return $template;
902
    }
903
    /**
904
     *
905
     *
906
     * @param string $template name of the Template
907
     * @return \Jobs\Entity\Job
908 3
     */
909
    public function setTemplate($template)
910 3
    {
911 3
        $this->template = $template;
912
        return $this;
913
    }
914
915
916
917
    /**
918
     * Gets the uri of an application link
919
     *
920
     * @return String
921 2
     */
922
    public function getUriApply()
923 2
    {
924
        return $this->uriApply;
925
    }
926
927
    /**
928
     * Sets the uri of an application link
929
     *
930
     * @param String $uriApply
931
     * @return \Jobs\Entity\Job
932 1
     */
933
    public function setUriApply($uriApply)
934 1
    {
935 1
        $this->uriApply = $uriApply;
936
        return $this;
937
    }
938
939
    /**
940
     * Gets the uri of a publisher
941
     *
942
     * @return String
943 2
     */
944
    public function getUriPublisher()
945 2
    {
946
        return $this->uriPublisher;
947
    }
948
    /**
949
     *
950
     * @param String $uriPublisher
951
     * @return \Jobs\Entity\Job
952 1
     */
953
    public function setUriPublisher($uriPublisher)
954 1
    {
955 1
        $this->uriPublisher = $uriPublisher;
956
        return $this;
957
    }
958
959
    /**
960
     * @param $key
961
     * @return mixed
962
     */
963
    public function getPublisher($key)
964
    {
965
        $result = null;
966
        foreach ($this->publisher as $publisher) {
967
            if ($publisher->host == $key) {
968
                $result = $publisher;
969
            }
970
        }
971
        if (!isset($result)) {
972
            $result = new Publisher();
973
            $result->host = $key;
0 ignored issues
show
Bug Best Practice introduced by
The property $host is declared protected in Jobs\Entity\Publisher. Since you implement __set, consider adding a @property or @property-write.
Loading history...
974
            $this->publisher[] = $result;
975
        }
976
        return $result;
977
    }
978
979
    public function setPublisherReference($key, $reference)
980
    {
981
        $publisher = $this->getPublisher($key);
982
        $publisher->reference;
983
        return $this;
984
    }
985
986
987
    /**
988
     * (non-PHPdoc)
989
     * @see \Core\Entity\PermissionsAwareInterface::getPermissions()
990 10
     */
991
    public function getPermissions()
992 10
    {
993 10
        if (!$this->permissions) {
994 10
            $permissions = new Permissions('Job/Permissions');
995 6
            if ($this->user) {
996
                $permissions->grant($this->user, Permissions::PERMISSION_ALL);
997 10
            }
998
            $this->setPermissions($permissions);
999
        }
1000 10
1001
        return $this->permissions;
1002
    }
1003
1004
    /**
1005
     * (non-PHPdoc)
1006
     * @see \Core\Entity\PermissionsAwareInterface::setPermissions()
1007 10
     */
1008
    public function setPermissions(PermissionsInterface $permissions)
1009 10
    {
1010 10
        $this->permissions = $permissions;
1011
        return $this;
1012
    }
1013
1014
    /**
1015
     * Gets the Values of a job template
1016
     *
1017
     * @return TemplateValues
1018 6
     */
1019
    public function getTemplateValues()
1020 6
    {
1021 2
        if (!$this->templateValues instanceof TemplateValues) {
0 ignored issues
show
introduced by
$this->templateValues is always a sub-type of Jobs\Entity\TemplateValues.
Loading history...
1022
            $this->templateValues = new TemplateValues();
1023 6
        }
1024
        return $this->templateValues;
1025
    }
1026
1027
    /**
1028
     * @param EntityInterface $templateValues
1029
     *
1030
     * @return $this
1031 5
     */
1032
    public function setTemplateValues(EntityInterface $templateValues = null)
1033 5
    {
1034 2
        if (!$templateValues instanceof TemplateValues) {
1035
            $templateValues = new TemplateValues($templateValues);
0 ignored issues
show
Unused Code introduced by
The call to Jobs\Entity\TemplateValues::__construct() has too many arguments starting with $templateValues. ( Ignorable by Annotation )

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

1035
            $templateValues = /** @scrutinizer ignore-call */ new TemplateValues($templateValues);

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. Please note the @ignore annotation hint above.

Loading history...
1036 5
        }
1037 5
        $this->templateValues = $templateValues;
1038
        return $this;
1039
    }
1040
1041
    /**
1042
     * Sets the list of channels where a job opening should be published
1043
     *
1044
     * @param Array
1045
     * {@inheritdoc}
1046 1
     */
1047
    public function setPortals(array $portals)
1048 1
    {
1049 1
        $this->portals = $portals;
1050
        return $this;
1051
    }
1052
1053
    /**
1054
     * Gets the list of channels where the job opening should be published
1055
     *
1056
     * {@inheritdoc}
1057
     * @return array
1058 2
     */
1059
    public function getPortals()
1060 2
    {
1061
        return $this->portals;
1062
    }
1063
1064
    /**
1065
     * Gets the flag indicating the draft state.
1066
     *
1067
     * @return bool
1068 2
     */
1069
    public function isDraft()
1070 2
    {
1071
        return $this->isDraft;
1072
    }
1073
1074
    /**
1075
     * Sets the flag indicating the draft state.
1076
     *
1077
     * @param boolean $flag
1078
     * @return DraftableEntityInterface
1079 6
     */
1080
    public function setIsDraft($flag)
1081 6
    {
1082 6
        $this->isDraft = (bool) $flag;
1083
        return $this;
1084
    }
1085
1086
    /**
1087
     * Gets the status and checks it against 'active'
1088
     *
1089
     * @return bool
1090 4
     */
1091
    public function isActive()
1092 4
    {
1093
        return !$this->isDraft && is_object($this->status) && $this->status->getName() == 'active';
0 ignored issues
show
Deprecated Code introduced by
The function Jobs\Entity\Status::getName() has been deprecated: since 0,29, use __toString() ( Ignorable by Annotation )

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

1093
        return !$this->isDraft && is_object($this->status) && /** @scrutinizer ignore-deprecated */ $this->status->getName() == 'active';

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1094
    }
1095
1096
    /**
1097
     * @return Job
1098 1
     */
1099
    public function makeSnapshot()
1100 1
    {
1101 1
        $snapshot = new JobSnapshot($this);
1102
        return $snapshot;
1103
    }
1104
1105
    /**
1106
     * @return array|mixed
1107 1
     */
1108
    public function getSnapshotGenerator()
1109
    {
1110 1
        $generator = array(
1111
            'hydrator' => '',
1112
            'target' => 'Jobs\Entity\JobSnapshot',
1113
            'exclude' => array('permissions', 'history')
1114 1
        );
1115
        return $generator;
1116
    }
1117
1118
    /**
1119
     * @param \Jobs\Entity\Classifications $classifications
1120
     *
1121
     * @return self
1122 2
     */
1123
    public function setClassifications($classifications)
1124 2
    {
1125
        $this->classifications = $classifications;
1126 2
1127
        return $this;
1128
    }
1129
1130
    /**
1131
     * @return \Jobs\Entity\Classifications
1132 2
     */
1133
    public function getClassifications()
1134 2
    {
1135 2
        if (!$this->classifications) {
1136
            $this->setClassifications(new Classifications());
1137
        }
1138 2
1139
        return $this->classifications;
1140
    }
1141
1142
    /**
1143
     * Mark this job as deleted.
1144
     *
1145
     * @internal
1146
     *      This is meant as temporary solution, until
1147
     *      SoftDelete is implemented.
1148
     *
1149
     * @return self
1150
     * @since 0.29
1151
     */
1152
    public function delete()
1153
    {
1154
        $this->isDeleted = true;
1155
1156
        return $this;
1157
    }
1158
1159
    public function isDeleted()
1160
    {
1161
        return $this->isDeleted;
1162
    }
1163
}
1164