Passed
Branch master (249862)
by Adam
07:51
created

SubmitController   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 293
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 293
rs 9.8
c 0
b 0
f 0
wmc 31

9 Methods

Rating   Name   Duplication   Size   Complexity  
A postFirm() 0 16 2
A postIndex() 0 14 1
A next() 0 7 2
A breadcrumb() 0 7 2
B getIndex() 0 31 5
C save() 0 76 10
A getFirm() 0 21 2
B getPreview() 0 33 6
A __construct() 0 12 1
1
<?php
2
3
namespace Coyote\Http\Controllers\Job;
4
5
use Coyote\Events\JobWasSaved;
6
use Coyote\Firm;
7
use Coyote\Firm\Benefit;
8
use Coyote\Http\Forms\Job\FirmForm;
9
use Coyote\Http\Forms\Job\JobForm;
10
use Coyote\Http\Transformers\FirmWithBenefits;
11
use Coyote\Job;
12
use Coyote\Http\Controllers\Controller;
13
use Coyote\Notifications\JobCreatedNotification;
14
use Coyote\Repositories\Contracts\FirmRepositoryInterface as FirmRepository;
15
use Coyote\Repositories\Contracts\JobRepositoryInterface as JobRepository;
16
use Coyote\Repositories\Contracts\PlanRepositoryInterface as PlanRepository;
17
use Coyote\Repositories\Criteria\EagerLoading;
18
use Coyote\Services\Job\Loader;
19
use Coyote\Services\UrlBuilder\UrlBuilder;
20
use Illuminate\Http\Request;
21
use Coyote\Services\Stream\Objects\Job as Stream_Job;
22
use Coyote\Services\Stream\Activities\Create as Stream_Create;
23
use Coyote\Services\Stream\Activities\Update as Stream_Update;
24
25
class SubmitController extends Controller
26
{
27
    /**
28
     * @var JobRepository
29
     */
30
    private $job;
31
32
    /**
33
     * @var FirmRepository
34
     */
35
    private $firm;
36
37
    /**
38
     * @var PlanRepository
39
     */
40
    private $plan;
41
42
    /**
43
     * @param JobRepository $job
44
     * @param FirmRepository $firm
45
     * @param PlanRepository $plan
46
     */
47
    public function __construct(JobRepository $job, FirmRepository $firm, PlanRepository $plan)
48
    {
49
        parent::__construct();
50
51
        $this->middleware('job.revalidate');
52
        $this->middleware('job.session', ['except' => ['getIndex']]);
53
54
        $this->breadcrumb->push('Praca', route('job.home'));
55
56
        $this->job = $job;
57
        $this->firm = $firm;
58
        $this->plan = $plan;
59
    }
60
61
    /**
62
     * @param Request $request
63
     * @param Loader $loader
64
     * @param int $id
65
     * @return \Illuminate\View\View
66
     */
67
    public function getIndex(Request $request, Loader $loader, $id = null)
68
    {
69
        /** @var \Coyote\Job $job */
70
        if ($id === null && $request->session()->has(Job::class)) {
71
            // get form content from session
72
            $job = $request->session()->get(Job::class);
73
        } else {
74
            $job = $this->job->findOrNew($id);
75
            abort_if($job->exists && $job->is_expired, 404);
76
77
            $job = $loader->init($job);
78
        }
79
80
        $this->authorize('update', $job);
81
        $this->authorize('update', $job->firm);
82
83
        $form = $this->createForm(JobForm::class, $job);
84
        $request->session()->put(Job::class, $job);
85
86
        $this->breadcrumb($job);
87
88
        return $this->view('job.submit.home', [
89
            'popular_tags'      => $this->job->getPopularTags(),
90
            'form'              => $form,
91
            'form_errors'       => $form->errors() ? $form->errors()->toJson() : '[]',
92
            'job'               => $form->toJson(),
93
            // firm information (in order to show firm nam on the button)
94
            'firm'              => $job->firm,
95
            // is plan is still going on?
96
            'is_plan_ongoing'   => $job->is_publish,
97
            'plans'             => $this->plan->active()->toJson()
98
        ]);
99
    }
100
101
    /**
102
     * @param Request $request
103
     * @return \Illuminate\Http\RedirectResponse
104
     */
105
    public function postIndex(Request $request)
106
    {
107
        /** @var \Coyote\Job $job */
108
        $job = clone $request->session()->get(Job::class);
109
110
        $form = $this->createForm(JobForm::class, $job);
111
        $form->validate();
112
113
        // only fillable columns! we don't want to set fields like "city" or "tags" because they don't really exists in db.
114
        $job->fill($form->all());
115
116
        $request->session()->put(Job::class, $job);
117
118
        return $this->next($request, redirect()->route('job.submit.firm'));
119
    }
120
121
    /**
122
     * @param Request $request
123
     * @return \Illuminate\View\View
124
     */
125
    public function getFirm(Request $request)
126
    {
127
        /** @var \Coyote\Job $job */
128
        $job = clone $request->session()->get(Job::class);
129
130
        // get all firms assigned to user...
131
        $this->firm->pushCriteria(new EagerLoading(['benefits', 'industries', 'gallery']));
132
        $firms = fractal($this->firm->findAllBy('user_id', $job->user_id), new FirmWithBenefits())->toJson();
133
134
        $this->breadcrumb($job);
135
136
        $form = $this->createForm(FirmForm::class, $job->firm);
137
138
        return $this->view('job.submit.firm')->with([
139
            'job'               => $job,
140
            'firm'              => $form->toJson(),
141
            'firms'             => $firms,
142
            'form'              => $form,
143
            'form_errors'       => $form->errors() ? $form->errors()->toJson() : '[]',
144
            'benefits'          => $form->get('benefits')->getChildrenValues(),
145
            'default_benefits'  => Benefit::getBenefitsList(), // default benefits,
146
        ]);
147
    }
148
149
    /**
150
     * @param Request $request
151
     * @return \Illuminate\Http\RedirectResponse
152
     */
153
    public function postFirm(Request $request)
154
    {
155
        /** @var \Coyote\Job $job */
156
        $job = $request->session()->get(Job::class);
157
158
        $form = $this->createForm(FirmForm::class, $job->firm);
159
        $form->validate();
160
161
        if ($job->firm->exists) {
162
            // syncOriginalAttribute() is important if user changes firm
163
            $job->firm->syncOriginalAttribute('id');
164
        }
165
166
        $request->session()->put(Job::class, $job);
167
168
        return $this->next($request, redirect()->route('job.submit.preview'));
169
    }
170
171
    /**
172
     * @param Request $request
173
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
174
     */
175
    public function getPreview(Request $request)
176
    {
177
        /** @var \Coyote\Job $job */
178
        $job = clone $request->session()->get(Job::class);
179
180
        $this->breadcrumb($job);
181
182
        $tags = $job->tags()->orderBy('priority', 'DESC')->with('category')->get()->groupCategory();
183
184
        $parser = app('parser.job');
185
186
        foreach (['description', 'requirements', 'recruitment'] as $name) {
187
            if (!empty($job[$name])) {
188
                $job[$name] = $parser->parse($job[$name]);
189
            }
190
        }
191
192
        if ($job->firm->is_private) {
193
            $job->firm()->dissociate();
194
        }
195
196
        if (!empty($job->firm->description)) {
197
            $job->firm->description = $parser->parse($job->firm->description);
198
        }
199
200
        return $this->view('job.submit.preview', [
201
            'job'               => $job,
202
            'firm'              => $job->firm ? $job->firm->toJson() : '{}',
203
            'tags'              => $tags,
204
            'rates_list'        => Job::getRatesList(),
205
            'seniority_list'    => Job::getSeniorityList(),
206
            'employment_list'   => Job::getEmploymentList(),
207
            'employees_list'    => Firm::getEmployeesList(),
208
        ]);
209
    }
210
211
    /**
212
     * @param Request $request
213
     * @return \Illuminate\Http\RedirectResponse
214
     */
215
    public function save(Request $request)
216
    {
217
        /** @var \Coyote\Job $job */
218
        $job = clone $request->session()->get(Job::class);
219
220
        $this->authorize('update', $job);
221
222
        $tags = [];
223
        if (count($job->tags)) {
224
            $order = 0;
225
226
            foreach ($job->tags as $tag) {
227
                $model = $tag->firstOrCreate(['name' => $tag->name]);
228
229
                $tags[$model->id] = [
230
                    'priority'  => $tag->pivot->priority ?? 0,
231
                    'order'     => ++$order
232
                ];
233
            }
234
        }
235
236
        $features = [];
237
        foreach ($job->features as $feature) {
238
            $features[$feature->id] = $feature->pivot->toArray();
239
        }
240
241
        $this->transaction(function () use (&$job, $request, $tags, $features) {
242
            $activity = $job->id ? Stream_Update::class : Stream_Create::class;
243
244
            if ($job->firm->is_private) {
245
                $job->firm()->dissociate();
246
            // firm name is required to save firm
247
            } elseif ($job->firm->name) {
248
                // user might click on "add new firm" button in form. make sure user_id is set up.
249
                $job->firm->setDefaultUserId($this->userId);
250
251
                $this->authorize('update', $job->firm);
252
253
                // fist, we need to save firm because firm might not exist.
254
                $job->firm->save();
255
256
                // reassociate job with firm. user could change firm, that's why we have to do it again.
257
                $job->firm()->associate($job->firm);
258
                // remove old benefits and save new ones.
259
                $job->firm->benefits()->push($job->firm->benefits);
260
                // sync industries
261
                $job->firm->industries()->sync($job->firm->industries);
262
                $job->firm->gallery()->push($job->firm->gallery);
263
            }
264
265
            $job->save();
266
            $job->locations()->push($job->locations);
267
268
            $job->tags()->sync($tags);
269
            $job->features()->sync($features);
270
271
            if ($job->wasRecentlyCreated || !$job->is_publish) {
272
                $job->payments()->create(['plan_id' => $job->plan_id, 'days' => $job->plan->length]);
273
274
                $job->user->notify(new JobCreatedNotification($job));
275
            }
276
277
            stream($activity, (new Stream_Job)->map($job));
278
            $request->session()->forget(Job::class);
279
280
            event(new JobWasSaved($job));
281
        });
282
283
        $paymentUuid = $job->getPaymentUuid();
284
        if ($paymentUuid !== null) {
285
            return redirect()
286
                ->route('job.payment', [$paymentUuid])
287
                ->with('success', 'Oferta została dodana, lecz nie jest jeszcze promowana. Uzupełnij poniższy formularz, aby zakończyć.');
288
        }
289
290
        return redirect()->to(UrlBuilder::job($job))->with('success', 'Oferta została prawidłowo dodana.');
291
    }
292
293
    /**
294
     * @param $job
295
     */
296
    private function breadcrumb($job)
297
    {
298
        if (empty($job['id'])) {
299
            $this->breadcrumb->push('Wystaw ofertę pracy', route('job.submit'));
300
        } else {
301
            $this->breadcrumb->push($job['title'], route('job.offer', [$job['id'], $job['slug']]));
302
            $this->breadcrumb->push('Edycja oferty', route('job.submit'));
303
        }
304
    }
305
306
    /**
307
     * @param Request $request
308
     * @param \Illuminate\Http\RedirectResponse $next
309
     * @return \Illuminate\Http\RedirectResponse
310
     */
311
    private function next(Request $request, $next)
312
    {
313
        if ($request->get('done')) {
314
            return $this->save($request);
315
        }
316
317
        return $next;
318
    }
319
}
320