Completed
Push — api/develop ( decc3a...0c5db2 )
by Bertrand
06:57
created

CustomFieldsController::createNewOptions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.1406

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 11
ccs 6
cts 8
cp 0.75
rs 9.4285
cc 3
eloc 5
nc 3
nop 2
crap 3.1406
1
<?php
2
3
/**
4
 * This file is part of the HRis Software package.
5
 *
6
 * HRis - Human Resource and Payroll System
7
 *
8
 * @link    http://github.com/HB-Co/HRis
9
 */
10
namespace HRis\Api\Controllers\PIM\Configuration;
11
12
use Exception;
13
use HRis\Api\Controllers\BaseController;
14
use HRis\Api\Eloquent\CustomField;
15
use HRis\Api\Eloquent\CustomFieldOption;
16
use HRis\Api\Eloquent\CustomFieldSection;
17
use HRis\Api\Eloquent\CustomFieldType;
18
use HRis\Api\Eloquent\Navlink;
19
use HRis\Api\Requests\PIM\CustomFieldRequest;
20
use HRis\Api\Requests\PIM\CustomFieldSectionsRequest;
21
use Illuminate\Http\Request;
22
use Illuminate\Support\Facades\DB;
23
24
/**
25
 * Class CustomFieldsController.
26
 */
27
class CustomFieldsController extends BaseController
28
{
29
    /**
30
     * @var CustomFieldSection
31
     */
32
    protected $custom_field_section;
33
34
    /**
35
     * @var CustomField
36
     */
37
    protected $custom_field;
38
39
    /**
40
     * @var CustomFieldType
41
     */
42
    protected $custom_field_type;
43
44
    /**
45
     * @param CustomFieldSection $custom_field_section
46
     * @param CustomField        $custom_field
47
     * @param CustomFieldType    $custom_field_type
48
     * @param CustomFieldOption  $custom_field_option
49
     *
50
     * @author Bertrand Kintanar <[email protected]>
51
     */
52 28
    public function __construct(CustomFieldSection $custom_field_section, CustomField $custom_field, CustomFieldType $custom_field_type, CustomFieldOption $custom_field_option)
53
    {
54 28
        $this->custom_field = $custom_field;
55 28
        $this->custom_field_section = $custom_field_section;
56 28
        $this->custom_field_type = $custom_field_type;
57 28
        $this->custom_field_option = $custom_field_option;
0 ignored issues
show
Bug introduced by
The property custom_field_option does not seem to exist. Did you mean custom_field?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
58 28
    }
59
60
    /**
61
     * Delete the PIM - Custom Field Section.
62
     *
63
     * @param CustomFieldSectionsRequest $request
64
     *
65
     * @return \Dingo\Api\Http\Response
66
     *
67
     * @author Bertrand Kintanar <[email protected]>
68
     */
69 4
    public function destroy(CustomFieldSectionsRequest $request)
70
    {
71 4
        return $this->destroyModel($request, $this->custom_field_section);
72
    }
73
74 4
    public function destroyCustomField(CustomFieldRequest $request)
75
    {
76 4
        return $this->destroyModel($request, $this->custom_field);
77
    }
78
79
    /**
80
     * Show the PIM - Custom Fields.
81
     *
82
     * @return \Dingo\Api\Http\Response
83
     *
84
     * @author Bertrand Kintanar <[email protected]>
85
     */
86 2
    public function index()
87
    {
88 2
        $custom_field_sections = $this->custom_field_section->with('screen')->paginate(ROWS_PER_PAGE);
89
90 2
        if (!$custom_field_sections) {
91
            return $this->responseAPI(404, UNABLE_RETRIEVE_MESSAGE);
92
        }
93
94 2
        return $this->responseAPI(200, SUCCESS_RETRIEVE_MESSAGE, ['data' => $custom_field_sections, 'table' => $this->setupDataTable($custom_field_sections)]);
95
    }
96
97
    /**
98
     * Setup table for custom field section.
99
     *
100
     * @param $custom_field_sections
101
     *
102
     * @return array
103
     *
104
     * @author Bertrand Kintanar <[email protected]>
105
     */
106 4
    public function setupDataTable($custom_field_sections)
107
    {
108 4
        $table = [];
109
110 4
        $table['title'] = 'Custom Field Sections';
111 4
        $table['permission'] = 'pim.configuration.custom-field-sections';
112 4
        $table['headers'] = ['Id', 'Name', 'Screen'];
113 4
        $table['model'] = [
114 4
            'singular' => 'custom_field_section',
115 4
            'plural'   => 'custom_field_sections',
116 4
            'dashed'   => 'custom-field-sections',
117
        ];
118 4
        $table['items'] = $custom_field_sections;
119
120 4
        return $table;
121
    }
122
123
    /**
124
     * Show a PIM - Custom Field Section.
125
     *
126
     * @param Request $request
127
     *
128
     * @return \Dingo\Api\Http\Response
129
     *
130
     * @author Bertrand Kintanar <[email protected]>
131
     */
132 2
    public function show(Request $request)
133
    {
134 2
        $custom_field_section_id = $request->get('custom_field_section_id');
135 2
        $custom_field_section = $this->custom_field_section->whereId($custom_field_section_id)->first();
0 ignored issues
show
Documentation Bug introduced by
The method whereId does not exist on object<HRis\Api\Eloquent\CustomFieldSection>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
136
137 2
        if (!$custom_field_section) {
138
            return $this->responseAPI(404, UNABLE_RETRIEVE_MESSAGE);
139
        }
140
141 2
        $custom_fields = $this->custom_field->with('type', 'options')->whereCustomFieldSectionId($custom_field_section_id)->paginate(ROWS_PER_PAGE);
142
143 2
        return $this->responseAPI(200, SUCCESS_RETRIEVE_MESSAGE, ['data' => $custom_fields, 'table' => $this->setupDataTable($custom_fields)]);
144
    }
145
146
    /**
147
     * Setup table for custom field.
148
     *
149
     * @param $custom_fields
150
     *
151
     * @return array
152
     *
153
     * @author Bertrand Kintanar <[email protected]>
154
     */
155
    public function setupDataTableCustomField($custom_fields)
156
    {
157
        $table = [];
158
159
        $table['title'] = 'Custom Fields';
160
        $table['permission'] = 'pim.configuration.custom-fields';
161
        $table['headers'] = ['Id', 'Name', 'Type', 'Mask', 'Has Options', 'Required'];
162
        $table['model'] = [
163
            'singular' => 'custom_field',
164
            'plural'   => 'custom_fields',
165
            'dashed'   => 'custom-fields',
166
        ];
167
        $table['items'] = $custom_fields;
168
169
        return $table;
170
    }
171
172
    /**
173
     * Save the PIM - Custom Field Section.
174
     *
175
     * @param CustomFieldSectionsRequest $request
176
     *
177
     * @return \Dingo\Api\Http\Response
178
     *
179
     * @author Bertrand Kintanar <[email protected]>
180
     */
181 16
    public function store(CustomFieldSectionsRequest $request)
182
    {
183 16
        return $this->storeModel($request, $this->custom_field_section, 'custom_field_section');
184
    }
185
186
    /**
187
     * Save the PIM - Custom Field.
188
     *
189
     * @param CustomFieldRequest $request
190
     *
191
     * @return \Dingo\Api\Http\Response
192
     *
193
     * @author Bertrand Kintanar <[email protected]>
194
     */
195 10
    public function storeCustomField(CustomFieldRequest $request)
196
    {
197 10
        $custom_field_section_id = $request->get('custom_field_section_id');
198
        try {
199 10
            DB::beginTransaction();
200
201 10
            $custom_field_section = $this->custom_field_section->findOrFail($custom_field_section_id);
0 ignored issues
show
Documentation Bug introduced by
The method findOrFail does not exist on object<HRis\Api\Eloquent\CustomFieldSection>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
202
203
            $data = [
204 8
                'custom_field_type_id' => $request->get('type_id'),
205 8
                'name'                 => $request->get('name'),
206 8
                'required'             => $request->get('required'),
207 8
                'mask'                 => $request->has('mask') ? $request->get('mask') : null,
208 8
            ];
209
210
            // Create CustomField and attach it to the CustomFieldSection
211 8
            $custom_field = $custom_field_section->customFields()->create($data);
212
213 8
            $custom_field_type = $this->custom_field_type->whereId($data['custom_field_type_id'])->first();
0 ignored issues
show
Documentation Bug introduced by
The method whereId does not exist on object<HRis\Api\Eloquent\CustomFieldType>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
214
215
            // Checks if the CustomFieldType has options
216 8
            if ($custom_field_type->has_options) {
217 8
                $options = explode(',', $request->get('custom_field_options'));
218
219 8
                foreach ($options as $option) {
220 8
                    $custom_field->options()->create(['name' => $option]);
221 8
                }
222 8
            }
223 10
        } catch (Exception $e) {
224 2
            DB::rollback();
225
226 2
            return $this->responseAPI(422, UNABLE_ADD_MESSAGE);
227
        }
228
229 8
        DB::commit();
230
231 8
        $custom_field = $this->custom_field->with('type', 'options')->whereId($custom_field->id)->first();
232
233 8
        return $this->responseAPI(201, SUCCESS_ADD_MESSAGE, compact('custom_field'));
234
    }
235
236
    /**
237
     * Update the PIM - Custom Field Section.
238
     *
239
     * @param CustomFieldSectionsRequest $request
240
     *
241
     * @return \Dingo\Api\Http\Response
242
     *
243
     * @author Bertrand Kintanar <[email protected]>
244
     */
245 4
    public function update(CustomFieldSectionsRequest $request)
246
    {
247
        try {
248 4
            DB::beginTransaction();
249
250 4
            $custom_field_section = CustomFieldSection::whereId($request->get('custom_field_section_id'))->first();
251
252 4
            if (!$custom_field_section) {
253 2
                return $this->responseAPI(404, UNABLE_RETRIEVE_MESSAGE);
254
            }
255
256 2
            $custom_field_section->update($request->only(['name', 'screen_id']));
257 2
        } catch (Exception $e) {
258
            DB::rollback();
259
260
            return $this->responseAPI(422, UNABLE_UPDATE_MESSAGE);
261
        }
262
263 2
        DB::commit();
264
265 2
        return $this->responseAPI(200, SUCCESS_UPDATE_MESSAGE);
266
    }
267
268
    /**
269
     * Update the PIM - Custom Field.
270
     *
271
     * @param CustomFieldRequest $request
272
     *
273
     * @return \Dingo\Api\Http\Response
274
     *
275
     * @author Bertrand Kintanar <[email protected]>
276
     */
277 4
    public function updateCustomField(CustomFieldRequest $request)
278
    {
279
        try {
280 4
            DB::beginTransaction();
281
282 4
            $custom_field = $this->custom_field->whereId($request->get('custom_field_id'))->first();
0 ignored issues
show
Documentation Bug introduced by
The method whereId does not exist on object<HRis\Api\Eloquent\CustomField>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
283
284 4
            if(!$custom_field) {
285 2
                return $this->responseAPI(404, UNABLE_RETRIEVE_MESSAGE);
286
            }
287
288
            $data = [
289 2
                'custom_field_type_id' => $request->get('type_id'),
290 2
                'name'                 => $request->get('name'),
291 2
                'required'             => $request->get('required'),
292 2
                'mask'                 => $request->has('mask') ? $request->get('mask') : null,
293 2
            ];
294
295 2
            $custom_field->update($data);
296
297 2
            $custom_field_type = $this->custom_field_type->whereId($data['custom_field_type_id'])->first();
0 ignored issues
show
Documentation Bug introduced by
The method whereId does not exist on object<HRis\Api\Eloquent\CustomFieldType>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
298
299
            // Checks if the CustomFieldType has options.
300 2
            if ($custom_field_type->has_options) {
301 2
                $old_options = $this->custom_field_option->whereCustomFieldId($custom_field->id)->get();
0 ignored issues
show
Bug introduced by
The property custom_field_option does not seem to exist. Did you mean custom_field?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
302 2
                $options = explode(',', $request->get('custom_field_options'));
303
304
                // Delete database entry that aren't in the new option list.
305 2
                $this->deleteOldOptions($options, $old_options);
306
307
                // Assign / Create database entry basing on the new option list.
308 2
                $this->createNewOptions($options, $custom_field);
309 2
            }
310 2
        } catch (Exception $e) {
311
            DB::rollback();
312
313
            return $this->responseAPI(422, UNABLE_UPDATE_MESSAGE);
314
        }
315
316 2
        DB::commit();
317
318 2
        return $this->responseAPI(200, SUCCESS_UPDATE_MESSAGE);
319
    }
320
321
    /**
322
     * Get Custom Field Sections by Screen Id.
323
     *
324
     * @param Request $request
325
     *
326
     * @return \Dingo\Api\Http\Response
327
     *
328
     * @author Bertrand Kintanar <[email protected]>
329
     */
330
    public function getCustomFieldSectionsByScreenId(Request $request)
331
    {
332
        $screen_id = Navlink::whereName($request->get('screen_name'))->pluck('id');
333
334
        $custom_field_sections = $this->custom_field_section->with('customFields.options')->whereScreenId($screen_id)->get();
335
336
        $custom_field_sections->each(function ($custom_field_section) {
337
            $custom_fields = $custom_field_section->customFields;
338
339
            $custom_field_section->fields = array_chunk($custom_fields->toArray(), 2);
340
        });
341
342
        return $this->responseAPI(200, SUCCESS_RETRIEVE_MESSAGE, compact('custom_field_sections'));
343
    }
344
345
    /**
346
     * Delete database entry that aren't in the new option list.
347
     *
348
     * @param $options
349
     * @param $old_options
350
     *
351
     * @author Bertrand Kintanar <[email protected]>
352
     */
353 2
    private function deleteOldOptions($options, $old_options)
354
    {
355 2
        foreach ($old_options as $option) {
356 2
            if (!in_array($option->name, $options)) {
357
                $option->delete();
358
            }
359 2
        }
360 2
    }
361
362
    /**
363
     * Create database entry basing on the new option list.
364
     *
365
     * @param $options
366
     * @param $custom_field
367
     *
368
     * @author Bertrand Kintanar <[email protected]>
369
     */
370 2
    private function createNewOptions($options, $custom_field)
371
    {
372 2
        foreach ($options as $option) {
373 2
            $custom_field_option = $this->custom_field_option->whereCustomFieldId($custom_field->id)->whereName($option)->count();
0 ignored issues
show
Bug introduced by
The property custom_field_option does not seem to exist. Did you mean custom_field?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
374
375
            // Only add to database those options that aren't there yet.
376 2
            if (!$custom_field_option) {
377
                $custom_field->options()->create(['name' => $option]);
378
            }
379 2
        }
380 2
    }
381
}
382