Passed
Push — feature/job-builder/tasks-redu... ( 55c8c7...85da17 )
by Chris
13:07
created

JobTaskController::batchUpdate()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 5

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 20
c 2
b 0
f 0
dl 0
loc 33
ccs 20
cts 20
cp 1
rs 9.2888
cc 5
nc 9
nop 2
crap 5
1
<?php
2
3
namespace App\Http\Controllers\Api;
4
5
use App\Models\JobPosterKeyTask;
6
use App\Models\JobPoster;
7
use App\Http\Controllers\Controller;
8
use App\Http\Requests\BatchUpdateJobTask;
9
10
class JobTaskController extends Controller
11
{
12
    /**
13
     * Converts a JobPosterKeyTask to an array appropriate for the api.
14
     *
15
     * @param  JobPosterKeyTask $model Incoming Job Poster Key Task object.
16
     * @return array
17
     */
18 5
    public function toApiArray(JobPosterKeyTask $model)
19
    {
20 5
        return array_merge($model->toArray(), $model->getTranslationsArray());
21
    }
22
23 1
    public function indexByJob(JobPoster $jobPoster)
1 ignored issue
show
Coding Style Documentation introduced by
Missing doc comment for function indexByJob()
Loading history...
24
    {
25 1
        $toApiArray = array($this, 'toApiArray');
26 1
        $taskArray = JobPosterKeyTask::where('job_poster_id', $jobPoster->id)->get()->map($toApiArray);
27 1
        return response()->json($taskArray);
28
    }
29
30
    /**
31
     * Update the set of tasks associated with a Job.
32
     *
33
     * @param  \App\Http\Requests\BatchUpdateJobTask $request   Incoming form request.
34
     * @param  \App\Models\JobPoster                 $jobPoster Incoming Job Poster object.
35
     * @return \Illuminate\Http\Response
36
     */
37 4
    public function batchUpdate(BatchUpdateJobTask $request, JobPoster $jobPoster)
38
    {
39 4
        $toApiArray = array($this, 'toApiArray');
40
41 4
        $newTasks = collect($request->validated()); // Collection of JobPosterKeyTasks.
42 4
        $oldTasks = $jobPoster->job_poster_key_tasks;
43
44 4
        $savedNewTaskIds = [];
45
46
        // First, delete old tasks that weren't resubmitted, and update those that were.
47 4
        foreach ($oldTasks as $task) {
48 3
            $newTask = $newTasks->firstWhere('id', $task['id']);
49 3
            if ($newTask) {
50 2
                $savedNewTaskIds[] = $newTask['id'];
51 2
                $task->fill(collect($newTask)->only(['en', 'fr'])->toArray());
52 2
                $task->save();
53
            } else {
54 2
                $task->delete();
55
            }
56
        }
57
58
        // Now, save any new tasks that remain.
59 4
        foreach ($newTasks as $task) {
60 4
            if ($this->isUnsaved($task, $savedNewTaskIds)) {
61 3
                $jobPosterTask = new JobPosterKeyTask();
62 3
                $jobPosterTask->job_poster_id = $jobPoster->id;
63 3
                $jobPosterTask->fill(collect($task)->only(['en', 'fr'])->toArray());
64 3
                $jobPosterTask->save();
65
            }
66
        }
67
68 4
        $taskArray = $jobPoster->fresh()->job_poster_key_tasks->map($toApiArray);
69 4
        return response()->json($taskArray);
70
    }
71
72
    /**
73
     * Helper function to determine whether a task is unsaved.
74
     *
75
     * @param mixed    $task         Single collection item from new tasks array.
76
     * @param number[] $savedTaskIds Array of saved task IDs.
77
     * @return boolean
78
     */
79 4
    private function isUnsaved($task, array $savedTaskIds): bool
80
    {
81 4
        return !array_key_exists('id', $task) || !in_array($task['id'], $savedTaskIds);
82
    }
83
}
84