Passed
Push — feature/admin-only-job-create ( 4243e9...e9cbd9 )
by Tristan
13:05 queued 07:52
created

JobController::managerIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 13
ccs 8
cts 8
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
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\JobPoster;
20
use App\Models\JobPosterQuestion;
21
use App\Models\Lookup\JobTerm;
22
use App\Models\Lookup\Province;
23
use App\Models\Lookup\SecurityClearance;
24
use App\Models\Lookup\LanguageRequirement;
25
use App\Models\Lookup\Department;
26
use App\Models\Lookup\SkillLevel;
27
use App\Models\Lookup\CriteriaType;
28
use App\Models\Skill;
29
use App\Models\Manager;
30
use App\Models\JobPosterKeyTask;
31
32
use App\Services\Validation\JobPosterValidator;
33
use Jenssegers\Date\Date;
34
35
class JobController extends Controller
36
{
37
    /**
38
     * Display a listing of JobPosters.
39
     *
40
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
41
     */
42
    public function index()
43
    {
44
        $now = Carbon::now();
45
46
        // Find published jobs that are currently open for applications.
47
        // Eager load required relationships: Department, Province, JobTerm.
48
        // Eager load the count of submitted applications, to prevent the relationship
49
        // from being actually loaded and firing off events.
50
        $jobs = JobPoster::where('open_date_time', '<=', $now)
51
            ->where('close_date_time', '>=', $now)
52
            ->where('published', true)
53
            ->with([
54
                'department',
55
                'province',
56
                'job_term',
57
            ])
58
            ->withCount([
59
                'submitted_applications',
60
            ])
61
            ->get();
62
        return view('applicant/job_index', [
63
            'job_index' => Lang::get('applicant/job_index'),
64
            'jobs' => $jobs
65
        ]);
66
    }
67
68
    /**
69
     * Display a listing of a manager's JobPosters.
70
     *
71
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
72
     */
73 1
    public function managerIndex()
74
    {
75 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...
76 1
        $jobs = JobPoster::where('manager_id', $manager->id)
77 1
            ->withCount('submitted_applications')
78 1
            ->get();
79
80 1
        return view('manager/job_index', [
81
            /*Localization Strings*/
82 1
            'jobs_l10n' => Lang::get('manager/job_index'),
83
84
            /* Data */
85 1
            'jobs' => $jobs,
86
        ]);
87
    }
88
89
    /**
90
     * Submit the Job Poster for review.
91
     *
92
     * @param \Illuminate\Http\Request $request   Incoming request object.
93
     * @param \App\Models\JobPoster    $jobPoster Job Poster object.
94
     *
95
     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
96
     */
97 1
    public function submitForReview(Request $request, JobPoster $jobPoster)
98
    {
99
        // Update review request timestamp
100 1
        $jobPoster->review_requested_at = new Date();
101 1
        $jobPoster->save();
102
103
        // Refresh model instance with updated DB values.
104 1
        $jobPoster = JobPoster::withCount('submitted_applications')->where('id', $jobPoster->id)->first();
105
106
        // Send email
107 1
        $reviewer_email = config('mail.reviewer_email');
108 1
        if (isset($reviewer_email)) {
109 1
            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

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

376
                'form_action_url' => route(/** @scrutinizer ignore-type */ /** @scrutinizer ignore-type */ ...$route), // phpcs:ignore
Loading history...
377 1
                'skills' => $skills,
378 1
                'skill_levels' => $skillLevels,
379 1
                'skill_template' => $skillLangs,
380
            ]
381
        );
382
    }
383
384
    /**
385
     * Create a new resource in storage
386
     *
387
     * @param \Illuminate\Http\Request $request   Incoming request object.
388
     * @param \App\Models\JobPoster    $jobPoster Optional Job Poster object.
389
     *
390
     * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse A redirect to the Job Index
391
     */
392 1
    public function store(Request $request, JobPoster $jobPoster = null)
393
    {
394
        // Don't allow edits for published Job Posters
395
        // Also check auth while we're at it
396 1
        if (isset($jobPoster)) {
397 1
            $this->authorize('update', $jobPoster);
398 1
            JobPosterValidator::validateUnpublished($jobPoster);
399
        } else {
400
            $this->authorize('create', JobPoster::class);
401
        }
402
403 1
        $input = $request->input();
404
405 1
        $job = (isset($jobPoster) ? $jobPoster : new JobPoster());
406
407 1
        $job->manager_id = $request->user()->manager->id;
408
409 1
        $this->fillAndSaveJobPoster($input, $job);
410
411 1
        $this->fillAndSaveJobPosterTasks($input, $job, isset($jobPoster));
412
413 1
        $this->fillAndSaveJobPosterQuestions($input, $job, isset($jobPoster));
414
415 1
        $this->fillAndSaveJobPosterCriteria($input, $job, isset($jobPoster));
416
417 1
        return redirect(route('manager.jobs.show', $job->id));
418
    }
419
420
    /**
421
     * Fill Job Poster model's properties and save
422
     *
423
     * @param mixed[]               $input     Field values.
424
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
425
     *
426
     * @return void
427
     */
428 1
    protected function fillAndSaveJobPoster(array $input, JobPoster $jobPoster) : void
429
    {
430 1
        $closeDate = new Date($input['close_date']);
431 1
        $openDate = new Date($input['open_date']);
432 1
        $startDate = new Date($input['start_date']);
433
434 1
        $jobPoster->fill(
435
            [
436 1
                'job_term_id' => JobTerm::where('name', 'month')->firstOrFail()->id,
437 1
                'term_qty' => $input['term_qty'],
438 1
                'open_date_time' => pstDayStartToUtcTime($openDate->year, $openDate->month, $openDate->day),
439 1
                'close_date_time' => pstDayEndToUtcTime($closeDate->year, $closeDate->month, $closeDate->day),
440 1
                'start_date_time' => pstDayStartToUtcTime($startDate->year, $startDate->month, $startDate->day),
441 1
                'department_id' => $input['department'],
442 1
                'province_id' => $input['province'],
443 1
                'salary_min' => $input['salary_min'],
444 1
                'salary_max' => $input['salary_max'],
445 1
                'noc' => $input['noc'],
446 1
                'classification' => $input['classification'],
447 1
                'security_clearance_id' => $input['security_clearance'],
448 1
                'language_requirement_id' => $input['language_requirement'],
449 1
                'remote_work_allowed' => (isset($input['remote_work_allowed']) ? $input['remote_work_allowed'] : false),
450
                'en' => [
451 1
                    'city' => $input['city'],
452 1
                    'title' => $input['title']['en'],
453 1
                    'impact' => $input['impact']['en'],
454 1
                    'branch' => $input['branch']['en'],
455 1
                    'division' => $input['division']['en'],
456 1
                    'education' => $input['education']['en'],
457
                ],
458
                'fr' => [
459 1
                    'city' => $input['city'],
460 1
                    'title' => $input['title']['fr'],
461 1
                    'impact' => $input['impact']['fr'],
462 1
                    'branch' => $input['branch']['fr'],
463 1
                    'division' => $input['division']['fr'],
464 1
                    'education' => $input['education']['fr'],
465
                ],
466
            ]
467
        );
468 1
        $jobPoster->save();
469 1
    }
470
471
    /**
472
     * Fill Job Poster's tasks and save
473
     *
474
     * @param mixed[]               $input     Field values.
475
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
476
     * @param boolean               $replace   Remove existing relationships.
477
     *
478
     * @return void
479
     */
480 1
    protected function fillAndSaveJobPosterTasks(array $input, JobPoster $jobPoster, bool $replace) : void
481
    {
482 1
        if ($replace) {
483 1
            $jobPoster->job_poster_key_tasks()->delete();
484
        }
485
486 1
        if (!array_key_exists('task', $input) || !is_array($input['task'])) {
487 1
            return;
488
        }
489
490
        foreach ($input['task'] as $task) {
491
            $jobPosterTask = new JobPosterKeyTask();
492
            $jobPosterTask->job_poster_id = $jobPoster->id;
493
            $jobPosterTask->fill(
494
                [
495
                    'en' => [
496
                        'description' => $task['en']
497
                    ],
498
                    'fr' => [
499
                        'description' => $task['fr']
500
                    ]
501
                ]
502
            );
503
            $jobPosterTask->save();
504
        }
505
    }
506
507
    /**
508
     * Fill Job Poster's questions and save
509
     *
510
     * @param mixed[]               $input     Field values.
511
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
512
     * @param boolean               $replace   Remove existing relationships.
513
     *
514
     * @return void
515
     */
516 1
    protected function fillAndSaveJobPosterQuestions(array $input, JobPoster $jobPoster, bool $replace) : void
517
    {
518 1
        if ($replace) {
519 1
            $jobPoster->job_poster_questions()->delete();
520
        }
521
522 1
        if (!array_key_exists('question', $input) || !is_array($input['question'])) {
523 1
            return;
524
        }
525
526
        foreach ($input['question'] as $question) {
527
            $jobQuestion = new JobPosterQuestion();
528
            $jobQuestion->job_poster_id = $jobPoster->id;
529
            $jobQuestion->fill(
530
                [
531
                    'en' => [
532
                        'question' => $question['question']['en'],
533
                        'description' => $question['description']['en']
534
                    ],
535
                    'fr' => [
536
                        'question' => $question['question']['fr'],
537
                        'description' => $question['description']['fr']
538
                    ]
539
                ]
540
            );
541
            $jobQuestion->save();
542
        }
543
    }
544
545
    /**
546
     * Fill Job Poster's criteria and save
547
     *
548
     * @param mixed[]               $input     Field values.
549
     * @param \App\Models\JobPoster $jobPoster Job Poster object.
550
     * @param boolean               $replace   Remove existing relationships.
551
     *
552
     * @return void
553
     */
554 1
    protected function fillAndSaveJobPosterCriteria(array $input, JobPoster $jobPoster, bool $replace) : void
555
    {
556 1
        if ($replace) {
557 1
            $jobPoster->criteria()->delete();
558
        }
559
560 1
        if (!array_key_exists('criteria', $input) || !is_array($input['criteria'])) {
561 1
            return;
562
        }
563
564
        $criteria = $input['criteria'];
565
566
        $combinedCriteria = [];
567
        if (isset($criteria['old'])) {
568
            $combinedCriteria = array_replace_recursive($combinedCriteria, $criteria['old']);
569
        }
570
        if (isset($criteria['new'])) {
571
            $combinedCriteria = array_replace_recursive($combinedCriteria, $criteria['new']);
572
        }
573
574
        if (! empty($combinedCriteria)) {
575
            foreach ($combinedCriteria as $criteriaType => $criteriaTypeInput) {
576
                foreach ($criteriaTypeInput as $skillType => $skillTypeInput) {
577
                    foreach ($skillTypeInput as $criteriaInput) {
578
                        $criteria = new Criteria();
579
                        $criteria->job_poster_id = $jobPoster->id;
580
                        $criteria->fill(
581
                            [
582
                                'criteria_type_id' => CriteriaType::where('name', $criteriaType)->firstOrFail()->id,
583
                                'skill_id' => $criteriaInput['skill_id'],
584
                                'skill_level_id' => $criteriaInput['skill_level_id'],
585
                                'en' => [
586
                                    'description' => $criteriaInput['description']['en'],
587
                                ],
588
                                'fr' => [
589
                                    'description' => $criteriaInput['description']['fr'],
590
                                ],
591
                            ]
592
                        );
593
                        $criteria->save();
594
                    }
595
                }
596
            }
597
        }
598
    }
599
600
    /**
601
     * Get the localized default questions and add them to an array.
602
     *
603
     * @return mixed[]|void
604
     */
605
    protected function populateDefaultQuestions()
606
    {
607
        $defaultQuestions = [
608
            'en' => array_values(Lang::get('manager/job_create', [], 'en')['questions']),
609
            'fr' => array_values(Lang::get('manager/job_create', [], 'fr')['questions']),
610
        ];
611
612
        if (count($defaultQuestions['en']) !== count($defaultQuestions['fr'])) {
613
            Log::warning('There must be the same number of French and English default questions for a Job Poster.');
614
            return;
615
        }
616
617
        $jobQuestions = [];
618
619
        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...
620
            $jobQuestion = new JobPosterQuestion();
621
            $jobQuestion->fill(
622
                [
623
                    'en' => [
624
                        'question' => $defaultQuestions['en'][$i],
625
                    ],
626
                    'fr' => [
627
                        'question' => $defaultQuestions['fr'][$i],
628
                    ]
629
                ]
630
            );
631
            // Workaround for Default Questions with empty descriptions
632
            // throwing an error during save.
633
            // The id isn't actually used during the fillAndSaveJobPosterQuestions
634
            // method call.
635
            $jobQuestion->id = $i + 1;
636
            $jobQuestions[] = $jobQuestion;
637
        }
638
639
        return $jobQuestions;
640
    }
641
}
642