Passed
Push — task/user-api-endpoint ( 6e4649...f0b85b )
by Chris
04:32
created

JobController::show()   C

Complexity

Conditions 10
Paths 24

Size

Total Lines 113
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 77
dl 0
loc 113
rs 6.6351
c 0
b 0
f 0
cc 10
nc 24
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 Carbon\Carbon;
11
use App\Models\JobPoster;
12
use App\Models\JobPosterQuestion;
13
use App\Models\Manager;
14
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
15
use App\Services\Validation\JobPosterValidator;
16
use Facades\App\Services\WhichPortal;
17
18
class JobController extends Controller
19
{
20
    /**
21
     * Display a listing of JobPosters.
22
     *
23
     * @return \Illuminate\Http\Response
24
     */
25
    public function index()
26
    {
27
        $now = Carbon::now();
28
29
        // Find published jobs that are currently open for applications.
30
        // Eager load required relationships: Department, Province, JobTerm.
31
        // Eager load the count of submitted applications, to prevent the relationship
32
        // from being actually loaded and firing off events.
33
        $jobs = JobPoster::where('open_date_time', '<=', $now)
34
            ->where('close_date_time', '>=', $now)
35
            ->where('published', true)
36
            ->with([
37
                'department',
38
                'province',
39
                'job_term',
40
            ])
41
            ->withCount([
42
                'submitted_applications',
43
            ])
44
            ->get();
45
        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

45
        return /** @scrutinizer ignore-call */ view('applicant/job_index', [
Loading history...
46
            'job_index' => Lang::get('applicant/job_index'),
47
            'jobs' => $jobs
48
        ]);
49
    }
50
51
    /**
52
     * Display a listing of a manager's JobPosters.
53
     *
54
     * @return \Illuminate\Http\Response
55
     */
56
    public function managerIndex()
57
    {
58
        $manager = Auth::user()->manager;
59
60
        $jobs = JobPoster::where('manager_id', $manager->id)
61
            ->with('classification')
62
            ->withCount('submitted_applications')
63
            ->get();
64
65
        foreach ($jobs as &$job) {
66
            $chosen_lang = $job->chosen_lang;
67
68
            // Show chosen lang title if current title is empty.
69
            if (empty($job->title)) {
70
                $job->title = $job->getTranslation('title', $chosen_lang);
71
                $job->trans_required = true;
72
            }
73
74
            // Always preview and edit in the chosen language.
75
            $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

75
            $job->preview_link = LaravelLocalization::getLocalizedURL($chosen_lang, /** @scrutinizer ignore-call */ route('manager.jobs.show', $job));
Loading history...
76
            $job->edit_link = LaravelLocalization::getLocalizedURL($chosen_lang, route('manager.jobs.edit', $job));
77
        }
78
79
80
        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

80
        return /** @scrutinizer ignore-call */ view('manager/job_index', [
Loading history...
81
            // Localization Strings.
82
            'jobs_l10n' => Lang::get('manager/job_index'),
83
            // Data.
84
            'jobs' => $jobs,
85
        ]);
86
    }
87
88
    /**
89
     * Display a listing of a hr advisor's JobPosters.
90
     *
91
     * @return \Illuminate\Http\Response
92
     */
93
    public function hrIndex(Request $request)
94
    {
95
        $hrAdvisor = $request->user()->hr_advisor;
96
        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

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

163
                'href' => /** @scrutinizer ignore-call */ route('manager.jobs.edit', $jobPoster->id),
Loading history...
164
                'title' => $jobLang['apply']['edit_link_title'],
165
                'text' => $jobLang['apply']['edit_link_label'],
166
            ];
167
        } elseif (WhichPortal::isHrPortal()) {
168
            if ($jobPoster->hr_advisors->contains('user_id', $user->id)) {
169
                $applyButton = [
170
                    'href' => route('hr_advisor.jobs.summary', $jobPoster->id),
171
                    'title' => null,
172
                    'text' => Lang::get('hr_advisor/job_summary.summary_title'),
173
                ];
174
            } else {
175
                $applyButton = [
176
                    'href' => route('hr_advisor.jobs.index'),
177
                    'title' => null,
178
                    'text' => Lang::get('hr_advisor/job_index.title'),
179
                ];
180
            }
181
        } elseif (Auth::check() && $jobPoster->isOpen()) {
182
            $applyButton = [
183
                'href' => route('job.application.edit.1', $jobPoster->id),
184
                'title' => $jobLang['apply']['apply_link_title'],
185
                'text' => $jobLang['apply']['apply_link_label'],
186
            ];
187
        } elseif (Auth::guest() && $jobPoster->isOpen()) {
188
            $applyButton = [
189
                'href' => route('job.application.edit.1', $jobPoster->id),
190
                'title' => $jobLang['apply']['login_link_title'],
191
                'text' => $jobLang['apply']['login_link_label'],
192
            ];
193
        } else {
194
            $applyButton = [
195
                'href' => null,
196
                'title' => null,
197
                'text' => $jobLang['apply']['job_closed_label'],
198
            ];
199
        }
200
201
        $jpb_release_date = strtotime('2019-08-21 16:18:17');
202
        $job_created_at = strtotime($jobPoster->created_at);
203
204
        // If the job poster is created after the release of the JPB.
205
        // Then, render with updated poster template.
206
        // Else, render with old poster template.
207
        if ($job_created_at > $jpb_release_date) {
208
            // Updated job poster (JPB).
209
            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

209
            return /** @scrutinizer ignore-call */ view(
Loading history...
210
                'applicant/jpb_job_post',
211
                [
212
                    'job_post' => $jobLang,
213
                    'frequencies' => Lang::get('common/lookup/frequency'),
214
                    'skill_template' => Lang::get('common/skills'),
215
                    'job' => $jobPoster,
216
                    'manager' => $jobPoster->manager,
217
                    'criteria' => $criteria,
218
                    'apply_button' => $applyButton,
219
                ]
220
            );
221
        } else {
222
            // Old job poster.
223
            return view(
224
                'applicant/job_post',
225
                [
226
                    'job_post' => $jobLang,
227
                    'frequencies' => Lang::get('common/lookup/frequency'),
228
                    'manager' => $jobPoster->manager,
229
                    'manager_profile_photo_url' => '/images/user.png', // TODO get real photo.
230
                    'team_culture' => $jobPoster->manager->team_culture,
231
                    'work_environment' => $jobPoster->manager->work_environment,
232
                    'workplace_photos' => $workplacePhotos,
233
                    'job' => $jobPoster,
234
                    'criteria' => $criteria,
235
                    'apply_button' => $applyButton,
236
                    'skill_template' => Lang::get('common/skills'),
237
                ]
238
            );
239
        }
240
    }
241
242
    /**
243
     * Display the form for editing an existing Job Poster
244
     * Only allows editing fields that don't appear on the react-built Job Poster Builder.
245
     *
246
     * @param  \Illuminate\Http\Request $request   Incoming request object.
247
     * @param  \App\Models\JobPoster    $jobPoster Job Poster object.
248
     * @return \Illuminate\Http\Response
249
     */
250
    public function edit(Request $request, JobPoster $jobPoster)
251
    {
252
        $manager = $jobPoster->manager;
253
254
        if ($jobPoster->job_poster_questions === null || $jobPoster->job_poster_questions->count() === 0) {
255
            $jobPoster->job_poster_questions()->saveMany($this->populateDefaultQuestions());
256
            $jobPoster->refresh();
257
        }
258
259
        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

259
        return /** @scrutinizer ignore-call */ view(
Loading history...
260
            'manager/job_create',
261
            [
262
                // Localization Strings.
263
                'job_l10n' => Lang::get('manager/job_edit'),
264
                // Data.
265
                'manager' => $manager,
266
                'job' => $jobPoster,
267
                '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

267
                'form_action_url' => /** @scrutinizer ignore-call */ route('admin.jobs.update', $jobPoster),
Loading history...
268
            ]
269
        );
270
    }
271
272
    /**
273
     * Create a blank job poster for the specified manager
274
     *
275
     * @param  \App\Models\Manager $manager Incoming Manager object.
276
     * @return \Illuminate\Http\Response Job Create view
277
     */
278
    public function createAsManager(Manager $manager)
279
    {
280
        $jobPoster = new JobPoster();
281
        $jobPoster->manager_id = $manager->id;
282
283
        // Save manager-specific info to the job poster - equivalent to the intro step of the JPB
284
        $divisionEn = $manager->getTranslation('division', 'en');
285
        $divisionFr = $manager->getTranslation('division', 'fr');
286
        $jobPoster->fill([
287
            'department_id' => $manager->department_id,
288
            'division' => ['en' => $divisionEn],
289
            'division' => ['fr' => $divisionFr],
290
        ]);
291
292
        $jobPoster->save();
293
294
        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

294
        return /** @scrutinizer ignore-call */ redirect()->route('manager.jobs.edit', $jobPoster->id);
Loading history...
295
    }
296
297
    /**
298
     * Update a resource in storage
299
     * NOTE: Only saves fields that are not on the react-built Job Poster Builder
300
     *
301
     * @param  \Illuminate\Http\Request $request   Incoming request object.
302
     * @param  \App\Models\JobPoster    $jobPoster Optional Job Poster object.
303
     * @return \Illuminate\Http\Response
304
     */
305
    public function store(Request $request, JobPoster $jobPoster)
306
    {
307
        // Don't allow edits for published Job Posters
308
        // Also check auth while we're at it.
309
        $this->authorize('update', $jobPoster);
310
        JobPosterValidator::validateUnpublished($jobPoster);
311
312
        $input = $request->input();
313
314
        if ($jobPoster->manager_id == null) {
315
            $jobPoster->manager_id = $request->user()->manager->id;
316
            $jobPoster->save();
317
        }
318
319
        $this->fillAndSaveJobPosterQuestions($input, $jobPoster, true);
320
321
        return redirect(route('manager.jobs.show', $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

321
        return /** @scrutinizer ignore-call */ redirect(route('manager.jobs.show', $jobPoster->id));
Loading history...
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

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