Passed
Push — feature/screening-plan-redux ( 0bd311...0bd311 )
by Tristan
09:35 queued 04:34
created

JobController::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 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
    /**
41
     * Get array representation of specified job poster
42
     *
43
     * @param \Illuminate\Http\Request $request   Incoming request object.
44
     * @param \App\Models\JobPoster    $jobPoster Job Poster object.
45
     *
46
     * @return mixed[]
47
     */
48
    public function get(Request $request, JobPoster $jobPoster)
0 ignored issues
show
introduced by
Method \App\Http\Controllers\JobController::get() does not have return type hint for its return value but it should be possible to add it based on @return annotation "mixed[]".
Loading history...
49
    {
50
        $jobWithTranslations = array_merge($jobPoster->toArray(), $jobPoster->getTranslationsArray());
51
        return $jobWithTranslations;
52
    }
53
54
    /**
55
     * Display a listing of JobPosters.
56
     *
57
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
58
     */
59
    public function index()
60
    {
61
        $now = Carbon::now();
62
63
        // Find published jobs that are currently open for applications.
64
        // Eager load required relationships: Department, Province, JobTerm.
65
        // Eager load the count of submitted applications, to prevent the relationship
66
        // from being actually loaded and firing off events.
67
        $jobs = JobPoster::where('open_date_time', '<=', $now)
68
            ->where('close_date_time', '>=', $now)
69
            ->where('published', true)
70
            ->with([
71
                'department',
72
                'province',
73
                'job_term',
74
            ])
75
            ->withCount([
76
                'submitted_applications',
77
            ])
78
            ->get();
79
        return view('applicant/job_index', [
80
            'job_index' => Lang::get('applicant/job_index'),
81
            'jobs' => $jobs
82
        ]);
83
    }
84
85
    /**
86
     * Display a listing of a manager's JobPosters.
87
     *
88
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
89
     */
90
    public function managerIndex()
91
    {
92
        $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...
93
        $jobs = JobPoster::where('manager_id', $manager->id)
94
            ->withCount('submitted_applications')
95
            ->get();
96
97
        return view('manager/job_index', [
98
            /*Localization Strings*/
99
            'jobs_l10n' => Lang::get('manager/job_index'),
100
101
            /* Data */
102
            'jobs' => $jobs,
103
        ]);
104
    }
105
106
    /**
107
     * Submit the Job Poster for review.
108
     *
109
     * @param \Illuminate\Http\Request $request   Incoming request object.
110
     * @param \App\Models\JobPoster    $jobPoster Job Poster object.
111
     *
112
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
113
     */
114
    public function submitForReview(Request $request, JobPoster $jobPoster)
115
    {
116
        // Update review request timestamp
117
        $jobPoster->review_requested_at = new Date();
118
        $jobPoster->save();
119
120
        // Refresh model instance with updated DB values.
121
        $jobPoster = JobPoster::withCount('submitted_applications')->where('id', $jobPoster->id)->first();
122
123
        // Send email
124
        $reviewer_email = config('mail.reviewer_email');
125
        if (isset($reviewer_email)) {
126
            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

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

405
                'form_action_url' => route(/** @scrutinizer ignore-type */ /** @scrutinizer ignore-type */ ...$route), // phpcs:ignore
Loading history...
406
                'skills' => $skills,
407
                'skill_levels' => $skillLevels,
408
                'skill_template' => $skillLangs,
409
            ]
410
        );
411
    }
412
413
    /**
414
     * Create a new resource in storage
415
     *
416
     * @param \Illuminate\Http\Request $request   Incoming request object.
417
     * @param \App\Models\JobPoster    $jobPoster Optional Job Poster object.
418
     *
419
     * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse A redirect to the Job Index
420
     */
421
    public function store(Request $request, JobPoster $jobPoster = null)
422
    {
423
        // Don't allow edits for published Job Posters
424
        // Also check auth while we're at it
425
        if (isset($jobPoster)) {
426
            $this->authorize('update', $jobPoster);
427
            JobPosterValidator::validateUnpublished($jobPoster);
428
        } else {
429
            $this->authorize('create', JobPoster::class);
430
        }
431
432
        $input = $request->input();
433
434
        $job = (isset($jobPoster) ? $jobPoster : new JobPoster());
435
436
        if ($job->manager_id == null) {
437
            $job->manager_id = $request->user()->manager->id;
438
            $job->save();
439
        }
440
441
        $this->fillAndSaveJobPoster($input, $job);
442
443
        $this->fillAndSaveJobPosterTasks($input, $job, isset($jobPoster));
444
445
        $this->fillAndSaveJobPosterQuestions($input, $job, isset($jobPoster));
446
447
        $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

447
        $this->/** @scrutinizer ignore-call */ 
448
               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...
448
449
        return redirect(route('manager.jobs.show', $job->id));
450
    }
451
452
    /**
453
     * Fill Job Poster model's properties and save
454
     *
455
     * @param mixed[]               $input     Field values.
456
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
457
     *
458
     * @return void
459
     */
460
    protected function fillAndSaveJobPoster(array $input, JobPoster $jobPoster) : void
461
    {
462
        $jobPoster->fill(
463
            [
464
                'job_term_id' => JobTerm::where('name', 'month')->firstOrFail()->id,
465
                'term_qty' => $input['term_qty'],
466
                'open_date_time' => ptDayStartToUtcTime($input['open_date']),
467
                'close_date_time' => ptDayEndToUtcTime($input['close_date']),
468
                'start_date_time' => ptDayStartToUtcTime($input['start_date']),
469
                'department_id' => $input['department'],
470
                'province_id' => $input['province'],
471
                'salary_min' => $input['salary_min'],
472
                'salary_max' => $input['salary_max'],
473
                'noc' => $input['noc'],
474
                'classification' => $input['classification'],
475
                'security_clearance_id' => $input['security_clearance'],
476
                'language_requirement_id' => $input['language_requirement'],
477
                'remote_work_allowed' => (isset($input['remote_work_allowed']) ? $input['remote_work_allowed'] : false),
478
                'en' => [
479
                    'city' => $input['city'],
480
                    'title' => $input['title']['en'],
481
                    'impact' => $input['impact']['en'],
482
                    'branch' => $input['branch']['en'],
483
                    'division' => $input['division']['en'],
484
                    'education' => $input['education']['en'],
485
                ],
486
                'fr' => [
487
                    'city' => $input['city'],
488
                    'title' => $input['title']['fr'],
489
                    'impact' => $input['impact']['fr'],
490
                    'branch' => $input['branch']['fr'],
491
                    'division' => $input['division']['fr'],
492
                    'education' => $input['education']['fr'],
493
                ],
494
            ]
495
        );
496
        $jobPoster->save();
497
    }
498
499
    /**
500
     * Fill Job Poster's tasks and save
501
     *
502
     * @param mixed[]               $input     Field values.
503
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
504
     * @param boolean               $replace   Remove existing relationships.
505
     *
506
     * @return void
507
     */
508
    protected function fillAndSaveJobPosterTasks(array $input, JobPoster $jobPoster, bool $replace) : void
509
    {
510
        if ($replace) {
511
            $jobPoster->job_poster_key_tasks()->delete();
512
        }
513
514
        if (!array_key_exists('task', $input) || !is_array($input['task'])) {
515
            return;
516
        }
517
518
        foreach ($input['task'] as $task) {
519
            $jobPosterTask = new JobPosterKeyTask();
520
            $jobPosterTask->job_poster_id = $jobPoster->id;
521
            $jobPosterTask->fill(
522
                [
523
                    'en' => [
524
                        'description' => $task['en']
525
                    ],
526
                    'fr' => [
527
                        'description' => $task['fr']
528
                    ]
529
                ]
530
            );
531
            $jobPosterTask->save();
532
        }
533
    }
534
535
    /**
536
     * Fill Job Poster's questions and save
537
     *
538
     * @param mixed[]               $input     Field values.
539
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
540
     * @param boolean               $replace   Remove existing relationships.
541
     *
542
     * @return void
543
     */
544
    protected function fillAndSaveJobPosterQuestions(array $input, JobPoster $jobPoster, bool $replace) : void
545
    {
546
        if ($replace) {
547
            $jobPoster->job_poster_questions()->delete();
548
        }
549
550
        if (!array_key_exists('question', $input) || !is_array($input['question'])) {
551
            return;
552
        }
553
554
        foreach ($input['question'] as $question) {
555
            $jobQuestion = new JobPosterQuestion();
556
            $jobQuestion->job_poster_id = $jobPoster->id;
557
            $jobQuestion->fill(
558
                [
559
                    'en' => [
560
                        'question' => $question['question']['en'],
561
                        'description' => $question['description']['en']
562
                    ],
563
                    'fr' => [
564
                        'question' => $question['question']['fr'],
565
                        'description' => $question['description']['fr']
566
                    ]
567
                ]
568
            );
569
            $jobQuestion->save();
570
        }
571
    }
572
573
    /**
574
     * Fill Job Poster's criteria and save
575
     *
576
     * @param mixed[]               $input     Field values.
577
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
578
     *
579
     * @return void
580
     */
581
    protected function fillAndSaveJobPosterCriteria(array $input, JobPoster $jobPoster) : void
582
    {
583
        $criteria = $input['criteria'];
584
585
        $affectedCriteriaIds = [];
586
        // Old criteria must be updated, using the criteriaId that comes from the form element names.
587
        if (!empty($criteria['old'])) {
588
            foreach ($criteria['old'] as $criteriaType => $criteriaTypeInput) {
589
                foreach ($criteriaTypeInput as $skillTypeInput) {
590
                    foreach ($skillTypeInput as $criteriaId => $criteriaInput) {
591
                        $updatedCriteria = $this->processCriteriaForm($jobPoster, $criteriaType, $criteriaInput, $criteriaId);
592
                        $affectedCriteriaIds[] = $updatedCriteria->id;
593
                    }
594
                }
595
            }
596
        }
597
        // New criteria must be created from scratch, and the id in the form element name can be disregarded.
598
        if (!empty($criteria['new'])) {
599
            foreach ($criteria['new'] as $criteriaType => $criteriaTypeInput) {
600
                foreach ($criteriaTypeInput as $skillTypeInput) {
601
                    foreach ($skillTypeInput as $criteriaInput) {
602
                        $newCriteria = $this->processCriteriaForm($jobPoster, $criteriaType, $criteriaInput, null);
603
                        $affectedCriteriaIds[] = $newCriteria->id;
604
                    }
605
                }
606
            }
607
        }
608
        // Existing criteria which were not resubmitted must be deleted.
609
        $deleteCriteria = $jobPoster->criteria()->whereNotIn('id', $affectedCriteriaIds)->get();
610
        foreach ($deleteCriteria as $criteria) {
611
            $this->deleteCriteria($criteria);
612
        }
613
    }
614
615
    /**
616
     * Process intput representing a single criteria from Job Poster form.
617
     *
618
     * @param JobPoster    $jobPoster
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
619
     * @param string       $criteriaType
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
620
     * @param array        $criteriaInput
1 ignored issue
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...
621
     * @param integer|null $criteriaId
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
622
     * @return Criteria
623
     */
624
    protected function processCriteriaForm(JobPoster $jobPoster, string $criteriaType, array $criteriaInput, ?int $criteriaId): Criteria
625
    {
626
        $skillId = $criteriaInput['skill_id'];
627
628
        //If no description was provided, use the default skill description
629
        $descriptionEn = $criteriaInput['description']['en'] ?
630
            $criteriaInput['description']['en'] : Skill::find($skillId)->getTranslation('description', 'en');
631
        $descriptionFr = $criteriaInput['description']['fr'] ?
632
            $criteriaInput['description']['fr'] : Skill::find($criteriaInput['skill_id'])->getTranslation('description', 'fr');
633
        $data = [
634
            'criteria_type_id' => CriteriaType::where('name', $criteriaType)->firstOrFail()->id,
635
            'skill_level_id' => $criteriaInput['skill_level_id'],
636
            'en' => [
637
                'description' => $descriptionEn,
638
            ],
639
            'fr' => [
640
                'description' => $descriptionFr,
641
            ],
642
        ];
643
644
        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...
645
            $existingCriteria = Criteria::find($criteriaId);
646
            $this->updateCriteria($existingCriteria, $data);
647
            return $existingCriteria;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $existingCriteria could return the type null which is incompatible with the type-hinted return App\Models\Criteria. Consider adding an additional type-check to rule them out.
Loading history...
648
        } else {
649
            $newCriteria = $this->createCriteria($jobPoster, $skillId, $data);
650
            return $newCriteria;
651
        }
652
    }
653
654
    /**
655
     * Create a Job Criteria
656
     *
657
     * @param JobPoster $jobPoster
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
658
     * @param integer   $skillId
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
659
     * @param array     $data
1 ignored issue
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...
660
     * @return Criteria
661
     */
662
    protected function createCriteria(JobPoster $jobPoster, int $skillId, array $data): Criteria
663
    {
664
        $criteria = new Criteria();
665
        $criteria->job_poster_id = $jobPoster->id;
666
        $criteria->skill_id = $skillId;
667
        $criteria->fill($data);
668
        $criteria->save();
669
670
        $notification = new AssessmentPlanNotification();
671
        $notification->job_poster_id = $criteria->job_poster_id;
672
        $notification->notification = [
673
            'type' => 'CREATE',
674
            'skillId' => $criteria->skill_id,
675
            'criteriaTypeId' => $criteria->criteria_type_id
676
        ];
677
        $notification->save();
678
679
        return $criteria;
680
    }
681
682
    /**
683
     * Update an existing Job Criteria
684
     *
685
     * @param Criteria $criteria
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
686
     * @param array    $data
1 ignored issue
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...
687
     * @return void
688
     */
689
    protected function updateCriteria(Criteria $criteria, array $data): void
690
    {
691
        if ($criteria->skill_level_id != $data['skill_level_id']) {
692
            $notification = new AssessmentPlanNotification();
693
            $notification->job_poster_id = $criteria->job_poster_id;
694
            $notification->notification = [
695
                'type' => 'UPDATE',
696
                'skillId' => $criteria->skill_id,
697
                'criteriaTypeId' => $criteria->criteria_type_id,
698
                'oldSkillLevelId' => $criteria->skill_level_id,
699
                'newSkillLevelId' => $data['skill_level_id'],
700
            ];
701
            $notification->save();
702
        }
703
704
        $criteria->fill($data);
705
        $criteria->save();
706
    }
707
708
    /**
709
     * Delete existing Job Criteria
710
     *
711
     * @param Criteria $criteria
1 ignored issue
show
Coding Style Documentation introduced by
Missing parameter comment
Loading history...
712
     * @return void
713
     */
714
    protected function deleteCriteria(Criteria $criteria): void
715
    {
716
        $notification = new AssessmentPlanNotification();
717
        $notification->job_poster_id = $criteria->job_poster_id;
718
        $notification->notification = [
719
            'type' => 'DELETE',
720
            'skillId' => $criteria->skill_id,
721
            'criteriaTypeId' => $criteria->criteria_type_id
722
        ];
723
        $notification->save();
724
725
        $criteria->delete();
726
    }
727
728
    /**
729
     * Get the localized default questions and add them to an array.
730
     *
731
     * @return mixed[]|void
732
     */
733
    protected function populateDefaultQuestions()
734
    {
735
        $defaultQuestions = [
736
            'en' => array_values(Lang::get('manager/job_create', [], 'en')['questions']),
737
            'fr' => array_values(Lang::get('manager/job_create', [], 'fr')['questions']),
738
        ];
739
740
        if (count($defaultQuestions['en']) !== count($defaultQuestions['fr'])) {
741
            Log::warning('There must be the same number of French and English default questions for a Job Poster.');
742
            return;
743
        }
744
745
        $jobQuestions = [];
746
747
        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...
748
            $jobQuestion = new JobPosterQuestion();
749
            $jobQuestion->fill(
750
                [
751
                    'en' => [
752
                        'question' => $defaultQuestions['en'][$i],
753
                    ],
754
                    'fr' => [
755
                        'question' => $defaultQuestions['fr'][$i],
756
                    ]
757
                ]
758
            );
759
            $jobQuestions[] = $jobQuestion;
760
        }
761
762
        return $jobQuestions;
763
    }
764
}
765