Passed
Push — feature/screening-plan-v2 ( ebc189...f2744e )
by Tristan
10:49 queued 05:49
created

JobController::destroy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use Illuminate\Support\Facades\Lang;
6
use Illuminate\Support\Facades\Auth;
7
use Illuminate\Support\Facades\Log;
8
use Illuminate\Support\Facades\Mail;
9
use Illuminate\Http\RedirectResponse;
10
use Illuminate\Http\Request;
11
use Illuminate\Http\Response;
12
use Illuminate\View\View;
13
use App\Http\Controllers\Controller;
14
15
use Carbon\Carbon;
16
17
use App\Mail\JobPosterReviewRequested;
18
19
use App\Models\Criteria;
20
use App\Models\JobPoster;
21
use App\Models\JobPosterKeyTask;
22
use App\Models\JobPosterQuestion;
23
use App\Models\Lookup\JobTerm;
24
use App\Models\Lookup\Province;
25
use App\Models\Lookup\SecurityClearance;
26
use App\Models\Lookup\LanguageRequirement;
27
use App\Models\Lookup\Department;
28
use App\Models\Lookup\SkillLevel;
29
use App\Models\Lookup\CriteriaType;
30
use App\Models\Skill;
31
use App\Models\Manager;
32
33
use App\Services\Validation\JobPosterValidator;
34
use Jenssegers\Date\Date;
35
use App\Models\AssessmentPlanNotification;
36
37
class JobController extends Controller
38
{
39
    /**
40
     * Display a listing of JobPosters.
41
     *
42
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
43
     */
44
    public function index()
45
    {
46
        $now = Carbon::now();
47
48
        // Find published jobs that are currently open for applications.
49
        // Eager load required relationships: Department, Province, JobTerm.
50
        // Eager load the count of submitted applications, to prevent the relationship
51
        // from being actually loaded and firing off events.
52
        $jobs = JobPoster::where('open_date_time', '<=', $now)
53
            ->where('close_date_time', '>=', $now)
54
            ->where('published', true)
55
            ->with([
56
                'department',
57
                'province',
58
                'job_term',
59
            ])
60
            ->withCount([
61
                'submitted_applications',
62
            ])
63
            ->get();
64
        return view('applicant/job_index', [
65
            'job_index' => Lang::get('applicant/job_index'),
66
            'jobs' => $jobs
67
        ]);
68
    }
69
70
    /**
71
     * Display a listing of a manager's JobPosters.
72
     *
73
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
74 1
     */
75
    public function managerIndex()
76 1
    {
77 1
        $manager = Auth::user()->manager;
0 ignored issues
show
Bug introduced by
Accessing manager on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
78 1
        $jobs = JobPoster::where('manager_id', $manager->id)
79 1
            ->withCount('submitted_applications')
80
            ->get();
81 1
82
        return view('manager/job_index', [
83 1
            /*Localization Strings*/
84
            'jobs_l10n' => Lang::get('manager/job_index'),
85
86 1
            /* Data */
87
            'jobs' => $jobs,
88
        ]);
89
    }
90
91
    /**
92
     * Submit the Job Poster for review.
93
     *
94
     * @param \Illuminate\Http\Request $request   Incoming request object.
95
     * @param \App\Models\JobPoster    $jobPoster Job Poster object.
96
     *
97
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
98 1
     */
99
    public function submitForReview(Request $request, JobPoster $jobPoster)
100
    {
101 1
        // Update review request timestamp
102 1
        $jobPoster->review_requested_at = new Date();
103
        $jobPoster->save();
104
105 1
        // Refresh model instance with updated DB values.
106
        $jobPoster = JobPoster::withCount('submitted_applications')->where('id', $jobPoster->id)->first();
107
108 1
        // Send email
109 1
        $reviewer_email = config('mail.reviewer_email');
110 1
        if (isset($reviewer_email)) {
111
            Mail::to($reviewer_email)->send(new JobPosterReviewRequested($jobPoster, Auth::user()));
0 ignored issues
show
Bug introduced by
It seems like Illuminate\Support\Facades\Auth::user() can also be of type null; however, parameter $manager of App\Mail\JobPosterReviewRequested::__construct() does only seem to accept App\Models\User, maybe add an additional type check? ( Ignorable by Annotation )

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

111
            Mail::to($reviewer_email)->send(new JobPosterReviewRequested($jobPoster, /** @scrutinizer ignore-type */ Auth::user()));
Loading history...
112
        } else {
113
            Log::error('The reviewer email environment variable is not set.');
114
        }
115 1
116
        return view('manager/job_index/job', [
117 1
            /*Localization Strings*/
118 1
            'jobs_l10n' => Lang::get('manager/job_index'),
119
            'job' => $jobPoster
120
        ]);
121
    }
122
123
    /**
124
     * Delete a draft Job Poster.
125
     *
126
     * @param \Illuminate\Http\Request $request   Incoming request object.
127
     * @param \App\Models\JobPoster    $jobPoster Job Poster object.
128
     *
129
     * @return void
130
     */
131
    public function destroy(Request $request, JobPoster $jobPoster) : void
132
    {
133
        $jobPoster->delete();
134
    }
135
136
    /**
137
     * Display the specified job poster.
138
     *
139
     * @param \Illuminate\Http\Request $request   Incoming request object.
140
     * @param \App\Models\JobPoster    $jobPoster Job Poster object.
141
     *
142
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
143 4
     */
144
    public function show(Request $request, JobPoster $jobPoster)
145 4
    {
146 4
        $jobPoster->load([
147
            'department',
148
            'criteria.skill.skill_type',
149
            'manager.team_culture',
150
            'manager.work_environment'
151
        ]);
152 4
153
        $user = Auth::user();
0 ignored issues
show
Unused Code introduced by
The assignment to $user is dead and can be removed.
Loading history...
154
155 4
        //TODO: Improve workplace photos, and reference them in template direction from WorkEnvironment model
156 4
        $workplacePhotos = [];
157
        foreach ($jobPoster->manager->work_environment->workplace_photo_captions as $photoCaption) {
158
            $workplacePhotos[] = [
159
                'description' => $photoCaption->description,
160
                'url' => '/images/user.png'
161
            ];
162
        }
163
164
        //TODO: replace route('manager.show',manager.id) in templates with link using slug
165
166 4
        $criteria = [
167
            'essential' => $jobPoster->criteria->filter(
168 2
                function ($value, $key) {
169 4
                    return $value->criteria_type->name == 'essential';
170
                }
171 4
            ),
172
            'asset' => $jobPoster->criteria->filter(
173 2
                function ($value, $key) {
174 4
                    return $value->criteria_type->name == 'asset';
175
                }
176
            ),
177
        ];
178 4
179
        $jobLang = Lang::get('applicant/job_post');
180 4
181 4
        $applyButton = [];
182
        if (!$jobPoster->published && $this->authorize('update', $jobPoster)) {
183 2
            $applyButton = [
184 2
                'href' => route('manager.jobs.edit', $jobPoster->id),
185 2
                'title' => $jobLang['apply']['edit_link_title'],
186
                'text' => $jobLang['apply']['edit_link_label'],
187 2
            ];
188
        } elseif (Auth::check() && $jobPoster->isOpen()) {
189 1
            $applyButton = [
190 1
                'href' => route('job.application.edit.1', $jobPoster->id),
191 1
                'title' => $jobLang['apply']['apply_link_title'],
192
                'text' => $jobLang['apply']['apply_link_label'],
193 1
            ];
194
        } elseif (Auth::guest() && $jobPoster->isOpen()) {
195 1
            $applyButton = [
196 1
                'href' => route('job.application.edit.1', $jobPoster->id),
197 1
                'title' => $jobLang['apply']['login_link_title'],
198
                'text' => $jobLang['apply']['login_link_label'],
199
            ];
200
        } else {
201
            $applyButton = [
202
                'href' => null,
203
                'title' => null,
204
                'text' => $jobLang['apply']['job_closed_label'],
205
            ];
206
        }
207 4
208 4
        return view(
209
            'applicant/job_post',
210 4
            [
211 4
                'job_post' => $jobLang,
212 4
                'manager' => $jobPoster->manager,
213 4
                'manager_profile_photo_url' => '/images/user.png', //TODO get real photo
214 4
                'team_culture' => $jobPoster->manager->team_culture,
215 4
                'work_environment' => $jobPoster->manager->work_environment,
216 4
                'workplace_photos' => $workplacePhotos,
217 4
                'job' => $jobPoster,
218 4
                'criteria' => $criteria,
219 4
                'apply_button' => $applyButton,
220
                'skill_template' => Lang::get('common/skills'),
221
            ]
222
        );
223
    }
224
225
    /**
226
     * Create a blank job poster for the specified manager
227
     *
228
     * @param Manager $manager
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
229
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory Job Create view
230 1
     */
231
    public function createAsManager(Manager $manager)
232 1
    {
233 1
        $jobPoster = new JobPoster();
234 1
        $jobPoster->manager_id = $manager->id;
235 1
        $managerEn = $manager->translate('en');
236 1
        $managerFr = $manager->translate('fr');
237 1
238
        $jobPoster->fill([
239 1
            'department_id' => $manager->department_id,
240 1
            'en' => [
241
                'branch' => $managerEn->branch,
242
                'division' => $managerEn->division,
243 1
            ],
244 1
            'fr' => [
245
                'branch' => $managerFr->branch,
246
                'division' => $managerFr->division,
247 1
            ]
248 1
        ]);
249
        $jobPoster->save();
250
251
        $defaultQuestions = $this->populateDefaultQuestions();
252
        if (!empty($defaultQuestions)) {
253
            $jobPoster->job_poster_questions()->saveMany($defaultQuestions);
254
        }
255
256
        return redirect()->route('manager.jobs.edit', $jobPoster->id);
1 ignored issue
show
Bug Best Practice introduced by
The expression return redirect()->route....edit', $jobPoster->id) returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type Illuminate\Contracts\Vie...ry|Illuminate\View\View.
Loading history...
257
    }
258
259
    /**
260
     * Display the form for creating a new Job Poster
261
     *
262
     * @param \Illuminate\Http\Request $request Incoming request object.
263
     *
264
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory Job Create view
265
     */
266
    public function create(Request $request)
267
    {
268
        return $this->populateCreateView($request);
269
    }
270
271 1
    /**
272
     * Display the form for editing an existing Job Poster
273 1
     *
274
     * @param \Illuminate\Http\Request $request   Incoming request object.
275
     * @param \App\Models\JobPoster    $jobPoster Job Poster object.
276
     *
277
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory Job Create view
278
     */
279
    public function edit(Request $request, JobPoster $jobPoster)
280
    {
281
        return $this->populateCreateView($request, $jobPoster);
282
    }
283
284 1
    /**
285
     * Get the manager from the request object and check if creating or editing
286 1
     *
287 1
     * @param \Illuminate\Http\Request $request   Incoming request object.
288 1
     * @param \App\Models\JobPoster    $jobPoster Optional Job Poster object.
289 1
     *
290 1
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory Job Create view
291
     */
292
    public function populateCreateView(Request $request, JobPoster $jobPoster = null)
293
    {
294
        if ($jobPoster == null || $jobPoster->manager == null) {
295
            $manager = $request->user() ? $request->user()->manager : null;
296
        } else {
297
            $manager = $jobPoster->manager;
298
        }
299
300
        if (isset($jobPoster)) {
301 1
            $job = $jobPoster;
302
            $route = ['manager.jobs.update', $jobPoster];
303 1
            $jobHeading = 'manager/job_edit';
304 1
        } else {
305
            $job = [];
306 1
            $defaultQuestions = $this->populateDefaultQuestions();
307 1
            if (!empty($defaultQuestions)) {
308 1
                $job['job_poster_questions'] = $defaultQuestions;
309 1
            }
310
            $route = ['manager.jobs.store'];
311
            $jobHeading = 'manager/job_create';
312 1
        }
313
314 1
        $skillLangs = Lang::get('common/skills');
315
316 1
        $softSkills = Skill::whereHas(
317
            'skill_type',
318 1
            function ($query) : void {
319 1
                $query->where('name', '=', 'soft');
320
            }
321 1
        )->get()
322 1
            ->mapWithKeys(
323 1
                function ($skill) {
324 1
                    return [
325
                        $skill->id => $skill->name
326
                    ];
327 1
                }
328
            )
329 1
            ->all();
330
331 1
        $hardSkills = Skill::whereHas(
332
            'skill_type',
333 1
            function ($query) : void {
334 1
                $query->where('name', '=', 'hard');
335
            }
336
        )->get()
337
            ->mapWithKeys(
338 1
                function ($skill) {
339 1
                    return [
340
                        $skill->id => $skill->name
341
                    ];
342 1
                }
343 1
            )
344
            ->all();
345
346
        asort($softSkills, SORT_LOCALE_STRING);
347 1
        asort($hardSkills, SORT_LOCALE_STRING);
348
349 1
        $skills = [
350
            'essential' => [
351 1
                'hard' => $hardSkills,
352
                'soft' => $softSkills
353 1
            ],
354 1
            'asset' => [
355 1
                'hard' => $hardSkills,
356
                'soft' => $softSkills
357 1
            ]
358
        ];
359 1
360 1
        $skillLevelCollection = SkillLevel::all();
361 1
362
        $skillLevels = array();
363 1
364 1
        $skillLevels['hard'] = $skillLevelCollection->mapWithKeys(
365
            function ($skillLevel) use ($skillLangs) {
366
                return [$skillLevel->id => $skillLangs['skill_levels']['hard'][$skillLevel->name]];
367 1
            }
368
        )->all();
369
370 1
        $skillLevels['soft'] = $skillLevelCollection->mapWithKeys(
371 1
            function ($skillLevel) use ($skillLangs) {
372 1
                return [$skillLevel->id => $skillLangs['skill_levels']['soft'][$skillLevel->name]];
373 1
            }
374 1
        )->all();
375 1
376 1
        return view(
377 1
            'manager/job_create',
378 1
            [
379 1
                /*Localization Strings*/
380 1
                'job_l10n' => Lang::get('manager/job_create'),
381
382
                /* Data */
383
                'job' => Lang::get($jobHeading),
384
                'manager' => $manager,
385
                'provinces' => Province::all(),
386
                'departments' => Department::all(),
387
                'language_requirments' => LanguageRequirement::all(),
388
                'security_clearances' => SecurityClearance::all(),
389
                'job' => $job,
390
                'form_action_url' => route(/** @scrutinizer ignore-type */ ...$route), // phpcs:ignore
0 ignored issues
show
Bug introduced by
$route is expanded, but the parameter $name of route() does not expect variable arguments. ( Ignorable by Annotation )

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

390
                'form_action_url' => route(/** @scrutinizer ignore-type */ /** @scrutinizer ignore-type */ ...$route), // phpcs:ignore
Loading history...
391
                'skills' => $skills,
392
                'skill_levels' => $skillLevels,
393 2
                'skill_template' => $skillLangs,
394
            ]
395
        );
396
    }
397 2
398 2
    /**
399 2
     * Create a new resource in storage
400
     *
401
     * @param \Illuminate\Http\Request $request   Incoming request object.
402
     * @param \App\Models\JobPoster    $jobPoster Optional Job Poster object.
403
     *
404 2
     * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse A redirect to the Job Index
405
     */
406 2
    public function store(Request $request, JobPoster $jobPoster = null)
407
    {
408 2
        // Don't allow edits for published Job Posters
409
        // Also check auth while we're at it
410 2
        if (isset($jobPoster)) {
411
            $this->authorize('update', $jobPoster);
412 2
            JobPosterValidator::validateUnpublished($jobPoster);
413
        } else {
414 2
            $this->authorize('create', JobPoster::class);
415
        }
416 2
417
        $input = $request->input();
418 2
419
        $job = (isset($jobPoster) ? $jobPoster : new JobPoster());
420
421
        if ($job->manager_id == null) {
422
            $job->manager_id = $request->user()->manager->id;
423
            $job->save();
424
        }
425
426
        $this->fillAndSaveJobPoster($input, $job);
427
428
        $this->fillAndSaveJobPosterTasks($input, $job, isset($jobPoster));
429 2
430
        $this->fillAndSaveJobPosterQuestions($input, $job, isset($jobPoster));
431 2
432 2
        $this->fillAndSaveJobPosterCriteria($input, $job, isset($jobPoster));
0 ignored issues
show
Unused Code introduced by
The call to App\Http\Controllers\Job...SaveJobPosterCriteria() has too many arguments starting with IssetNode. ( Ignorable by Annotation )

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

432
        $this->/** @scrutinizer ignore-call */ 
433
               fillAndSaveJobPosterCriteria($input, $job, isset($jobPoster));

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...
433 2
434
        return redirect(route('manager.jobs.show', $job->id));
435 2
    }
436
437 2
    /**
438 2
     * Fill Job Poster model's properties and save
439 2
     *
440 2
     * @param mixed[]               $input     Field values.
441 2
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
442 2
     *
443 2
     * @return void
444 2
     */
445 2
    protected function fillAndSaveJobPoster(array $input, JobPoster $jobPoster) : void
446 2
    {
447 2
        $jobPoster->fill(
448 2
            [
449 2
                'job_term_id' => JobTerm::where('name', 'month')->firstOrFail()->id,
450 2
                'term_qty' => $input['term_qty'],
451
                'open_date_time' => ptDayStartToUtcTime($input['open_date']),
452 2
                'close_date_time' => ptDayEndToUtcTime($input['close_date']),
453 2
                'start_date_time' => ptDayStartToUtcTime($input['start_date']),
454 2
                'department_id' => $input['department'],
455 2
                'province_id' => $input['province'],
456 2
                'salary_min' => $input['salary_min'],
457 2
                'salary_max' => $input['salary_max'],
458
                'noc' => $input['noc'],
459
                'classification' => $input['classification'],
460 2
                'security_clearance_id' => $input['security_clearance'],
461 2
                'language_requirement_id' => $input['language_requirement'],
462 2
                'remote_work_allowed' => (isset($input['remote_work_allowed']) ? $input['remote_work_allowed'] : false),
463 2
                'en' => [
464 2
                    'city' => $input['city'],
465 2
                    'title' => $input['title']['en'],
466
                    'impact' => $input['impact']['en'],
467
                    'branch' => $input['branch']['en'],
468
                    'division' => $input['division']['en'],
469 2
                    'education' => $input['education']['en'],
470 2
                ],
471
                'fr' => [
472
                    'city' => $input['city'],
473
                    'title' => $input['title']['fr'],
474
                    'impact' => $input['impact']['fr'],
475
                    'branch' => $input['branch']['fr'],
476
                    'division' => $input['division']['fr'],
477
                    'education' => $input['education']['fr'],
478
                ],
479
            ]
480
        );
481 2
        $jobPoster->save();
482
    }
483 2
484 2
    /**
485
     * Fill Job Poster's tasks and save
486
     *
487 2
     * @param mixed[]               $input     Field values.
488 2
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
489
     * @param boolean               $replace   Remove existing relationships.
490
     *
491
     * @return void
492
     */
493
    protected function fillAndSaveJobPosterTasks(array $input, JobPoster $jobPoster, bool $replace) : void
494
    {
495
        if ($replace) {
496
            $jobPoster->job_poster_key_tasks()->delete();
497
        }
498
499
        if (!array_key_exists('task', $input) || !is_array($input['task'])) {
500
            return;
501
        }
502
503
        foreach ($input['task'] as $task) {
504
            $jobPosterTask = new JobPosterKeyTask();
505
            $jobPosterTask->job_poster_id = $jobPoster->id;
506
            $jobPosterTask->fill(
507
                [
508
                    'en' => [
509
                        'description' => $task['en']
510
                    ],
511
                    'fr' => [
512
                        'description' => $task['fr']
513
                    ]
514
                ]
515
            );
516
            $jobPosterTask->save();
517 2
        }
518
    }
519 2
520 2
    /**
521
     * Fill Job Poster's questions and save
522
     *
523 2
     * @param mixed[]               $input     Field values.
524 2
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
525
     * @param boolean               $replace   Remove existing relationships.
526
     *
527
     * @return void
528
     */
529
    protected function fillAndSaveJobPosterQuestions(array $input, JobPoster $jobPoster, bool $replace) : void
530
    {
531
        if ($replace) {
532
            $jobPoster->job_poster_questions()->delete();
533
        }
534
535
        if (!array_key_exists('question', $input) || !is_array($input['question'])) {
536
            return;
537
        }
538
539
        foreach ($input['question'] as $question) {
540
            $jobQuestion = new JobPosterQuestion();
541
            $jobQuestion->job_poster_id = $jobPoster->id;
542
            $jobQuestion->fill(
543
                [
544
                    'en' => [
545
                        'question' => $question['question']['en'],
546
                        'description' => $question['description']['en']
547
                    ],
548
                    'fr' => [
549
                        'question' => $question['question']['fr'],
550
                        'description' => $question['description']['fr']
551
                    ]
552
                ]
553
            );
554
            $jobQuestion->save();
555 2
        }
556
    }
557 2
558 2
    /**
559
     * Fill Job Poster's criteria and save
560
     *
561 2
     * @param mixed[]               $input     Field values.
562 2
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
563
     *
564
     * @return void
565
     */
566
    protected function fillAndSaveJobPosterCriteria(array $input, JobPoster $jobPoster) : void
567
    {
568
        $criteria = $input['criteria'];
569
570
        $affectedCriteriaIds = [];
571
        // Old criteria must be updated, using the criteriaId that comes from the form element names.
572
        if (!empty($criteria['old'])) {
573
            foreach ($criteria['old'] as $criteriaType => $criteriaTypeInput) {
574
                foreach ($criteriaTypeInput as $skillTypeInput) {
575
                    foreach ($skillTypeInput as $criteriaId => $criteriaInput) {
576
                        $updatedCriteria = $this->processCriteriaForm($jobPoster, $criteriaType, $criteriaInput, $criteriaId);
577
                        $affectedCriteriaIds[] = $updatedCriteria->id;
578
                    }
579
                }
580
            }
581
        }
582
        // New criteria must be created from scratch, and the id in the form element name can be disregarded.
583
        if (!empty($criteria['new'])) {
584
            foreach ($criteria['new'] as $criteriaType => $criteriaTypeInput) {
585
                foreach ($criteriaTypeInput as $skillTypeInput) {
586
                    foreach ($skillTypeInput as $criteriaInput) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
587
588
                        $newCriteria = $this->processCriteriaForm($jobPoster, $criteriaType, $criteriaInput, null);
589
                        $affectedCriteriaIds[] = $newCriteria->id;
590
                    }
591
                }
592
            }
593
        }
594
        // Existing criteria which were not resubmitted must be deleted.
595
        $deleteCriteria = $jobPoster->criteria()->whereNotIn('id', $affectedCriteriaIds)->get();
596
        foreach ($deleteCriteria as $criteria) {
597
            $this->deleteCriteria($criteria);
598
        }
599
    }
600
601
    /**
602
     * Process intput representing a single criteria from Job Poster form.
603
     *
604
     * @param JobPoster $jobPoster
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
605
     * @param string $criteriaType
2 ignored issues
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
606
     * @param array $criteriaInput
2 ignored issues
show
introduced by
@param annotation of method \App\Http\Controllers\JobController::processCriteriaForm() does not specify type hint for items of its traversable parameter $criteriaInput.
Loading history...
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
607
     * @param int|null $criteriaId
2 ignored issues
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "integer|null" but found "int|null" for parameter type
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
608
     * @return Criteria
609
     */
610
    protected function processCriteriaForm($jobPoster, $criteriaType, $criteriaInput, $criteriaId)
3 ignored issues
show
introduced by
Method \App\Http\Controllers\JobController::processCriteriaForm() does not have parameter type hint for its parameter $jobPoster but it should be possible to add it based on @param annotation "JobPoster".
Loading history...
introduced by
Method \App\Http\Controllers\JobController::processCriteriaForm() does not have parameter type hint for its parameter $criteriaType but it should be possible to add it based on @param annotation "string".
Loading history...
introduced by
Method \App\Http\Controllers\JobController::processCriteriaForm() does not have parameter type hint for its parameter $criteriaInput but it should be possible to add it based on @param annotation "array".
Loading history...
introduced by
Method \App\Http\Controllers\JobController::processCriteriaForm() does not have parameter type hint for its parameter $criteriaId but it should be possible to add it based on @param annotation "int|null".
Loading history...
introduced by
Method \App\Http\Controllers\JobController::processCriteriaForm() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Criteria".
Loading history...
Coding Style introduced by
Type hint "JobPoster" missing for $jobPoster
Loading history...
Coding Style introduced by
Type hint "string" missing for $criteriaType
Loading history...
Coding Style introduced by
Type hint "array" missing for $criteriaInput
Loading history...
611
    {
612
        $skillId = $criteriaInput['skill_id'];
613
614
        //If no description was provided, use the default skill description
615
        $descriptionEn = $criteriaInput['description']['en'] ?
616
            $criteriaInput['description']['en'] : Skill::find($skillId)->getTranslation('description', 'en');
617
        $descriptionFr = $criteriaInput['description']['fr'] ?
618
            $criteriaInput['description']['fr'] : Skill::find($criteriaInput['skill_id'])->getTranslation('description', 'fr');
619
        $data = [
620
            'criteria_type_id' => CriteriaType::where('name', $criteriaType)->firstOrFail()->id,
621
            'skill_level_id' => $criteriaInput['skill_level_id'],
622
            'en' => [
623
                'description' => $descriptionEn,
624
            ],
625
            'fr' => [
626
                'description' => $descriptionFr,
627
            ],
628
        ];
629
630
        if ($criteriaId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $criteriaId of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
631
            $existingCriteria = Criteria::find($criteriaId);
632
            $this->updateCriteria($existingCriteria, $data);
633
            return $existingCriteria;
634
        } else {
635
            $newCriteria = $this->createCriteria($jobPoster, $skillId, $data);
636
            return $newCriteria;
637
        }
638
    }
639
640
    /**
641
     * Create a Job Criteria
642
     *
643
     * @param JobPoster $jobPoster
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
644
     * @param integer $skillId
2 ignored issues
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
645
     * @param array $data
2 ignored issues
show
introduced by
@param annotation of method \App\Http\Controllers\JobController::createCriteria() does not specify type hint for items of its traversable parameter $data.
Loading history...
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
646
     * @return Criteria
647
     */
648
    protected function createCriteria(JobPoster $jobPoster,int $skillId,array $data)
0 ignored issues
show
introduced by
Method \App\Http\Controllers\JobController::createCriteria() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Criteria".
Loading history...
Coding Style introduced by
Expected 1 space between comma and type hint "int"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space between comma and type hint "array"; 0 found
Loading history...
649
    {
650
        $criteria = new Criteria();
651
        $criteria->job_poster_id = $jobPoster->id;
652
        $criteria->skill_id = $skillId;
653
        $criteria->fill($data);
654
        $criteria->save();
655
656
        $notification = new AssessmentPlanNotification();
657
        $notification->job_poster_id = $criteria->job_poster_id;
658
        $notification->notification = [
659
            'type' => 'CREATE',
660
            'skillId' => $criteria->skill_id,
661
            'criteriaTypeId' => $criteria->criteria_type_id
662
        ];
663
        $notification->save();
664
665
        return $criteria;
666
    }
667
668
    /**
669
     * Update an existing Job Criteria
670
     *
671
     * @param Criteria $criteria
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
672
     * @param array $data
2 ignored issues
show
introduced by
@param annotation of method \App\Http\Controllers\JobController::updateCriteria() does not specify type hint for items of its traversable parameter $data.
Loading history...
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
673
     * @return void
674
     */
675
    protected function updateCriteria(Criteria $criteria, $data)
1 ignored issue
show
introduced by
Method \App\Http\Controllers\JobController::updateCriteria() does not have parameter type hint for its parameter $data but it should be possible to add it based on @param annotation "array".
Loading history...
introduced by
Method \App\Http\Controllers\JobController::updateCriteria() does not have return type hint for its return value but it should be possible to add it based on @return annotation "void".
Loading history...
Coding Style introduced by
Type hint "array" missing for $data
Loading history...
676
    {
677
        if ($criteria->skill_level_id != $data['skill_level_id']) {
678
            $notification = new AssessmentPlanNotification();
679
            $notification->job_poster_id = $criteria->job_poster_id;
680
            $notification->notification = [
681
                'type' => 'UPDATE',
682
                'skillId' => $criteria->skill_id,
683
                'criteriaTypeId' => $criteria->criteria_type_id,
684
                'oldSkillLevelId' => $criteria->skill_level_id,
685
                'newSkillLevelId' => $data['skill_level_id'],
686
            ];
687
            $notification->save();
688
        }
689
690
        $criteria->fill($data);
691
        $criteria->save();
692
    }
693
694
    /**
695
     * Delete existing Job Criteria
696
     *
697
     * @param Criteria $criteria
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
698
     * @return void
699
     */
700
    protected function deleteCriteria(Criteria $criteria)
0 ignored issues
show
introduced by
Method \App\Http\Controllers\JobController::deleteCriteria() does not have return type hint for its return value but it should be possible to add it based on @return annotation "void".
Loading history...
701
    {
702
        $notification = new AssessmentPlanNotification();
703
        $notification->job_poster_id = $criteria->job_poster_id;
704
        $notification->notification = [
705
            'type' => 'DELETE',
706
            'skillId' => $criteria->skill_id,
707
            'criteriaTypeId' => $criteria->criteria_type_id
708
        ];
709
        $notification->save();
710
711
        $criteria->delete();
712
    }
713
714
    /**
715
     * Get the localized default questions and add them to an array.
716
     *
717
     * @return mixed[]|void
718
     */
719
    protected function populateDefaultQuestions()
720
    {
721
        $defaultQuestions = [
722
            'en' => array_values(Lang::get('manager/job_create', [], 'en')['questions']),
723
            'fr' => array_values(Lang::get('manager/job_create', [], 'fr')['questions']),
724
        ];
725
726
        if (count($defaultQuestions['en']) !== count($defaultQuestions['fr'])) {
727
            Log::warning('There must be the same number of French and English default questions for a Job Poster.');
728
            return;
729
        }
730
731
        $jobQuestions = [];
732
733
        for ($i = 0; $i < count($defaultQuestions['en']); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
734
            $jobQuestion = new JobPosterQuestion();
735
            $jobQuestion->fill(
736
                [
737
                    'en' => [
738
                        'question' => $defaultQuestions['en'][$i],
739
                    ],
740
                    'fr' => [
741
                        'question' => $defaultQuestions['fr'][$i],
742
                    ]
743
                ]
744
            );
745
            $jobQuestions[] = $jobQuestion;
746
        }
747
748
        return $jobQuestions;
749
    }
750
}
751