Passed
Push — feature/azure-webapp-pipeline-... ( feaa42...29a14a )
by Grant
09:47 queued 03:56
created

JobController::show()   C

Complexity

Conditions 12
Paths 28

Size

Total Lines 124
Code Lines 85

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 85
c 2
b 0
f 0
dl 0
loc 124
rs 5.9006
cc 12
nc 28
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Http\Request;
9
use App\Http\Controllers\Controller;
10
use App\Models\JobApplication;
11
use Carbon\Carbon;
12
use App\Models\JobPoster;
13
use App\Models\JobPosterQuestion;
14
use App\Models\Manager;
15
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
16
use App\Services\Validation\JobPosterValidator;
17
use Facades\App\Services\WhichPortal;
18
19
class JobController extends Controller
20
{
21
    /**
22
     * Display a listing of JobPosters.
23
     *
24
     * @return \Illuminate\Http\Response
25
     */
26
    public function index()
27
    {
28
        $now = Carbon::now();
29
30
        // Find published jobs that are currently open for applications.
31
        // Eager load required relationships: Department, Province, JobTerm.
32
        // Eager load the count of submitted applications, to prevent the relationship
33
        // from being actually loaded and firing off events.
34
        $jobs = JobPoster::where('open_date_time', '<=', $now)
35
            ->where('close_date_time', '>=', $now)
36
            ->where('published', true)
37
            ->with([
38
                'department',
39
                'province',
40
                'job_term',
41
            ])
42
            ->withCount([
43
                'submitted_applications',
44
            ])
45
            ->get();
46
        return view('applicant/job_index', [
0 ignored issues
show
Bug introduced by
The function view was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

46
        return /** @scrutinizer ignore-call */ view('applicant/job_index', [
Loading history...
47
            'job_index' => Lang::get('applicant/job_index'),
48
            'jobs' => $jobs
49
        ]);
50
    }
51
52
    /**
53
     * Display a listing of a manager's JobPosters.
54
     *
55
     * @return \Illuminate\Http\Response
56
     */
57
    public function managerIndex()
58
    {
59
        $manager = Auth::user()->manager;
60
61
        $jobs = JobPoster::where('manager_id', $manager->id)
62
            ->with('classification')
63
            ->withCount('submitted_applications')
64
            ->get();
65
66
        foreach ($jobs as &$job) {
67
            $chosen_lang = $job->chosen_lang;
68
69
            // Show chosen lang title if current title is empty.
70
            if (empty($job->title)) {
71
                $job->title = $job->getTranslation('title', $chosen_lang);
72
                $job->trans_required = true;
73
            }
74
75
            // Always preview and edit in the chosen language.
76
            $job->preview_link = LaravelLocalization::getLocalizedURL($chosen_lang, route('manager.jobs.show', $job));
0 ignored issues
show
Bug introduced by
The function route was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

76
            $job->preview_link = LaravelLocalization::getLocalizedURL($chosen_lang, /** @scrutinizer ignore-call */ route('manager.jobs.show', $job));
Loading history...
77
            $job->edit_link = LaravelLocalization::getLocalizedURL($chosen_lang, route('manager.jobs.edit', $job));
78
        }
79
80
81
        return view('manager/job_index', [
0 ignored issues
show
Bug introduced by
The function view was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

81
        return /** @scrutinizer ignore-call */ view('manager/job_index', [
Loading history...
82
            // Localization Strings.
83
            'jobs_l10n' => Lang::get('manager/job_index'),
84
            // Data.
85
            'jobs' => $jobs,
86
        ]);
87
    }
88
89
    /**
90
     * Display a listing of a hr advisor's JobPosters.
91
     *
92
     * @return \Illuminate\Http\Response
93
     */
94
    public function hrIndex(Request $request)
95
    {
96
        $hrAdvisor = $request->user()->hr_advisor;
97
        return view('hr_advisor/job_index', [
0 ignored issues
show
Bug introduced by
The function view was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

97
        return /** @scrutinizer ignore-call */ view('hr_advisor/job_index', [
Loading history...
98
            'title' => Lang::get('hr_advisor/job_index.title'),
99
            'hr_advisor_id' => $hrAdvisor->id
100
        ]);
101
    }
102
103
104
105
106
    /**
107
     * Delete a draft Job Poster.
108
     *
109
     * @param  \Illuminate\Http\Request $request   Incoming request object.
110
     * @param  \App\Models\JobPoster    $jobPoster Job Poster object.
111
     * @return \Illuminate\Http\Response
112
     */
113
    public function destroy(Request $request, JobPoster $jobPoster)
114
    {
115
        $jobPoster->delete();
116
    }
117
118
    /**
119
     * Display the specified job poster.
120
     *
121
     * @param  \Illuminate\Http\Request $request   Incoming request object.
122
     * @param  \App\Models\JobPoster    $jobPoster Job Poster object.
123
     * @return \Illuminate\Http\Response
124
     */
125
    public function show(Request $request, JobPoster $jobPoster)
126
    {
127
        $jobPoster->load([
128
            'department',
129
            'criteria.skill.skill_type',
130
            'manager.team_culture',
131
            'manager.work_environment'
132
        ]);
133
134
        $user = Auth::user();
135
136
        // TODO: Improve workplace photos, and reference them in template direction from WorkEnvironment model.
137
        $workplacePhotos = [];
138
        foreach ($jobPoster->manager->work_environment->workplace_photo_captions as $photoCaption) {
139
            $workplacePhotos[] = [
140
                'description' => $photoCaption->description,
141
                'url' => '/images/user.png'
142
            ];
143
        }
144
145
        // TODO: replace route('manager.show',manager.id) in templates with link using slug.
146
        $criteria = [
147
            'essential' => $jobPoster->criteria->filter(
148
                function ($value, $key) {
149
                    return $value->criteria_type->name == 'essential';
150
                }
151
            ),
152
            'asset' => $jobPoster->criteria->filter(
153
                function ($value, $key) {
154
                    return $value->criteria_type->name == 'asset';
155
                }
156
            ),
157
        ];
158
159
        $jobLang = Lang::get('applicant/job_post');
160
161
        $applyButton = [];
162
        if (WhichPortal::isManagerPortal()) {
163
            $applyButton = [
164
                'href' => route('manager.jobs.edit', $jobPoster->id),
0 ignored issues
show
Bug introduced by
The function route was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

164
                'href' => /** @scrutinizer ignore-call */ route('manager.jobs.edit', $jobPoster->id),
Loading history...
165
                'title' => $jobLang['apply']['edit_link_title'],
166
                'text' => $jobLang['apply']['edit_link_label'],
167
            ];
168
        } elseif (WhichPortal::isHrPortal()) {
169
            if ($jobPoster->hr_advisors->contains('user_id', $user->id)) {
170
                $applyButton = [
171
                    'href' => route('hr_advisor.jobs.summary', $jobPoster->id),
172
                    'title' => null,
173
                    'text' => Lang::get('hr_advisor/job_summary.summary_title'),
174
                ];
175
            } else {
176
                $applyButton = [
177
                    'href' => route('hr_advisor.jobs.index'),
178
                    'title' => null,
179
                    'text' => Lang::get('hr_advisor/job_index.title'),
180
                ];
181
            }
182
        } elseif (Auth::check() && $jobPoster->isOpen()) {
183
            $application = JobApplication::where('applicant_id', Auth::user()->applicant->id)
184
            ->where('job_poster_id', $jobPoster->id)->first();
185
            // If applicants job application is not draft anymore then link to application preview page.
186
            if ($application != null && $application->application_status->name != 'draft') {
187
                $applyButton = [
188
                    'href' => route('applications.show', $application->id),
189
                    'title' => $jobLang['apply']['view_link_title'],
190
                    'text' => $jobLang['apply']['view_link_label'],
191
                ];
192
            } else {
193
                $applyButton = [
194
                    'href' => route('job.application.edit.1', $jobPoster->id),
195
                    'title' => $jobLang['apply']['apply_link_title'],
196
                    'text' => $jobLang['apply']['apply_link_label'],
197
                ];
198
            }
199
        } elseif (Auth::guest() && $jobPoster->isOpen()) {
200
            $applyButton = [
201
                'href' => route('job.application.edit.1', $jobPoster->id),
202
                'title' => $jobLang['apply']['login_link_title'],
203
                'text' => $jobLang['apply']['login_link_label'],
204
            ];
205
        } else {
206
            $applyButton = [
207
                'href' => null,
208
                'title' => null,
209
                'text' => $jobLang['apply']['job_closed_label'],
210
            ];
211
        }
212
213
        $jpb_release_date = strtotime('2019-08-21 16:18:17');
214
        $job_created_at = strtotime($jobPoster->created_at);
215
216
        // If the job poster is created after the release of the JPB.
217
        // Then, render with updated poster template.
218
        // Else, render with old poster template.
219
        if ($job_created_at > $jpb_release_date) {
220
            // Updated job poster (JPB).
221
            return view(
0 ignored issues
show
Bug introduced by
The function view was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

221
            return /** @scrutinizer ignore-call */ view(
Loading history...
222
                'applicant/jpb_job_post',
223
                [
224
                    'job_post' => $jobLang,
225
                    'frequencies' => Lang::get('common/lookup/frequency'),
226
                    'skill_template' => Lang::get('common/skills'),
227
                    'job' => $jobPoster,
228
                    'manager' => $jobPoster->manager,
229
                    'criteria' => $criteria,
230
                    'apply_button' => $applyButton,
231
                ]
232
            );
233
        } else {
234
            // Old job poster.
235
            return view(
236
                'applicant/job_post',
237
                [
238
                    'job_post' => $jobLang,
239
                    'frequencies' => Lang::get('common/lookup/frequency'),
240
                    'manager' => $jobPoster->manager,
241
                    'manager_profile_photo_url' => '/images/user.png', // TODO get real photo.
242
                    'team_culture' => $jobPoster->manager->team_culture,
243
                    'work_environment' => $jobPoster->manager->work_environment,
244
                    'workplace_photos' => $workplacePhotos,
245
                    'job' => $jobPoster,
246
                    'criteria' => $criteria,
247
                    'apply_button' => $applyButton,
248
                    'skill_template' => Lang::get('common/skills'),
249
                ]
250
            );
251
        }
252
    }
253
254
    /**
255
     * Display the form for editing an existing Job Poster
256
     * Only allows editing fields that don't appear on the react-built Job Poster Builder.
257
     *
258
     * @param  \Illuminate\Http\Request $request   Incoming request object.
259
     * @param  \App\Models\JobPoster    $jobPoster Job Poster object.
260
     * @return \Illuminate\Http\Response
261
     */
262
    public function edit(Request $request, JobPoster $jobPoster)
263
    {
264
        $manager = $jobPoster->manager;
265
266
        if ($jobPoster->job_poster_questions === null || $jobPoster->job_poster_questions->count() === 0) {
267
            $jobPoster->job_poster_questions()->saveMany($this->populateDefaultQuestions());
268
            $jobPoster->refresh();
269
        }
270
271
        return view(
0 ignored issues
show
Bug introduced by
The function view was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

271
        return /** @scrutinizer ignore-call */ view(
Loading history...
272
            'manager/job_create',
273
            [
274
                // Localization Strings.
275
                'job_l10n' => Lang::get('manager/job_edit'),
276
                // Data.
277
                'manager' => $manager,
278
                'job' => $jobPoster,
279
                'form_action_url' => route('admin.jobs.update', $jobPoster),
0 ignored issues
show
Bug introduced by
The function route was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

279
                'form_action_url' => /** @scrutinizer ignore-call */ route('admin.jobs.update', $jobPoster),
Loading history...
280
            ]
281
        );
282
    }
283
284
    /**
285
     * Create a blank job poster for the specified manager
286
     *
287
     * @param  \App\Models\Manager $manager Incoming Manager object.
288
     * @return \Illuminate\Http\Response Job Create view
289
     */
290
    public function createAsManager(Manager $manager)
291
    {
292
        $jobPoster = new JobPoster();
293
        $jobPoster->manager_id = $manager->id;
294
295
        // Save manager-specific info to the job poster - equivalent to the intro step of the JPB
296
        $divisionEn = $manager->getTranslation('division', 'en');
297
        $divisionFr = $manager->getTranslation('division', 'fr');
298
        $jobPoster->fill([
299
            'department_id' => $manager->department_id,
300
            'division' => ['en' => $divisionEn],
301
            'division' => ['fr' => $divisionFr],
302
        ]);
303
304
        $jobPoster->save();
305
306
        return redirect()->route('manager.jobs.edit', $jobPoster->id);
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

306
        return /** @scrutinizer ignore-call */ redirect()->route('manager.jobs.edit', $jobPoster->id);
Loading history...
307
    }
308
309
    /**
310
     * Update a resource in storage
311
     * NOTE: Only saves fields that are not on the react-built Job Poster Builder
312
     *
313
     * @param  \Illuminate\Http\Request $request   Incoming request object.
314
     * @param  \App\Models\JobPoster    $jobPoster Optional Job Poster object.
315
     * @return \Illuminate\Http\Response
316
     */
317
    public function store(Request $request, JobPoster $jobPoster)
318
    {
319
        // Don't allow edits for published Job Posters
320
        // Also check auth while we're at it.
321
        $this->authorize('update', $jobPoster);
322
        JobPosterValidator::validateUnpublished($jobPoster);
323
324
        $input = $request->input();
325
326
        if ($jobPoster->manager_id == null) {
327
            $jobPoster->manager_id = $request->user()->manager->id;
328
            $jobPoster->save();
329
        }
330
331
        $this->fillAndSaveJobPosterQuestions($input, $jobPoster, true);
332
333
        return redirect(route('manager.jobs.show', $jobPoster->id));
0 ignored issues
show
Bug introduced by
The function route was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

333
        return redirect(/** @scrutinizer ignore-call */ route('manager.jobs.show', $jobPoster->id));
Loading history...
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

333
        return /** @scrutinizer ignore-call */ redirect(route('manager.jobs.show', $jobPoster->id));
Loading history...
334
    }
335
336
    /**
337
     * Fill Job Poster's questions and save
338
     *
339
     * @param  mixed[]               $input     Field values.
340
     * @param  \App\Models\JobPoster $jobPoster Job Poster object.
341
     * @param  boolean               $replace   Remove existing relationships.
342
     * @return void
343
     */
344
    protected function fillAndSaveJobPosterQuestions(array $input, JobPoster $jobPoster, bool $replace) : void
345
    {
346
        if ($replace) {
347
            $jobPoster->job_poster_questions()->delete();
348
        }
349
350
        if (!array_key_exists('question', $input) || !is_array($input['question'])) {
351
            return;
352
        }
353
354
        foreach ($input['question'] as $question) {
355
            $jobQuestion = new JobPosterQuestion();
356
            $jobQuestion->job_poster_id = $jobPoster->id;
357
            $jobQuestion->fill(
358
                [
359
                    'question' => [
360
                        'en' => $question['question']['en'],
361
                        'fr' => $question['question']['fr']
362
363
                    ],
364
                    'description' => [
365
                        'en' => $question['description']['en'],
366
                        'fr' => $question['description']['fr']
367
                    ]
368
                ]
369
            );
370
            $jobPoster->save();
371
            $jobQuestion->save();
372
        }
373
    }
374
375
    /**
376
     * Get the localized default questions and add them to an array.
377
     *
378
     * @return mixed[]|void
379
     */
380
    protected function populateDefaultQuestions()
381
    {
382
        $defaultQuestions = [
383
            'en' => array_values(Lang::get('manager/job_create', [], 'en')['questions']),
384
            'fr' => array_values(Lang::get('manager/job_create', [], 'fr')['questions']),
385
        ];
386
387
        if (count($defaultQuestions['en']) !== count($defaultQuestions['fr'])) {
388
            Log::warning('There must be the same number of French and English default questions for a Job Poster.');
389
            return;
390
        }
391
392
        $jobQuestions = [];
393
394
        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...
395
            $jobQuestion = new JobPosterQuestion();
396
            $jobQuestion->fill(
397
                [
398
                    'question' => [
399
                        'en' => $defaultQuestions['en'][$i],
400
                        'fr' => $defaultQuestions['fr'][$i],
401
                    ]
402
                ]
403
            );
404
            $jobQuestions[] = $jobQuestion;
405
        }
406
407
        return $jobQuestions;
408
    }
409
}
410