Passed
Push — master ( c98abf...91bafd )
by Jonathan
19:18
created

EditController::deleteRelation()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
c 0
b 0
f 0
nc 8
nop 3
dl 0
loc 33
rs 9.4222
1
<?php
2
3
namespace Uccello\Core\Http\Controllers\Core;
4
5
use Kris\LaravelFormBuilder\FormBuilder;
0 ignored issues
show
Bug introduced by
The type Kris\LaravelFormBuilder\FormBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Illuminate\Http\Request;
0 ignored issues
show
Bug introduced by
The type Illuminate\Http\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Uccello\Core\Forms\EditForm;
8
use Uccello\Core\Events\BeforeSaveEvent;
9
use Uccello\Core\Events\AfterSaveEvent;
10
use Uccello\Core\Models\Domain;
11
use Uccello\Core\Models\Module;
12
use Uccello\Core\Models\Relatedlist;
13
14
class EditController extends Controller
15
{
16
    protected $viewName = 'edit.main';
17
    protected $formBuilder;
18
19
    /**
20
     * Check user permissions
21
     */
22
    protected function checkPermissions()
23
    {
24
        if (request()->has('id')) {
0 ignored issues
show
Bug introduced by
The function request 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

24
        if (/** @scrutinizer ignore-call */ request()->has('id')) {
Loading history...
25
            $this->middleware('uccello.permissions:update');
26
        } else {
27
            $this->middleware('uccello.permissions:create');
28
        }
29
    }
30
31
    public function __construct(FormBuilder $formBuilder)
32
    {
33
        $this->formBuilder = $formBuilder;
34
35
        parent::__construct();
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function process(?Domain $domain, Module $module, Request $request)
42
    {
43
        // Pre-process
44
        $this->preProcess($domain, $module, $request);
45
46
        // Retrieve record or get a new empty instance
47
        $record = $this->getRecordFromRequest();
48
49
        // Get form
50
        $form = $this->getForm($record);
51
52
        // Get mode
53
        $mode = !is_null($record->getKey()) ? 'edit' : 'create';
54
55
        return $this->autoView([
56
            'form' => $form,
57
            'record' => $record,
58
            'mode' => $mode
59
        ]);
60
    }
61
62
    /**
63
     * Create or update record into database
64
     *
65
     * @param Domain|null $domain
66
     * @param Module $module
67
     * @param boolean $redirect
68
     * @return void
69
     */
70
    public function save(?Domain $domain, Module $module, Request $request, bool $redirect = true)
71
    {
72
        // Pre-process
73
        $this->preProcess($domain, $module, $request);
74
75
        // Get model class used by the module
76
        $modelClass = $this->module->model_class;
0 ignored issues
show
Unused Code introduced by
The assignment to $modelClass is dead and can be removed.
Loading history...
77
78
        // Retrieve record or get a new empty instance
79
        $record = $this->getRecordFromRequest();
80
81
        // Get form
82
        $form = $this->getForm($record);
83
84
        // Redirect if form not valid (the record is made here)
85
        $form->redirectIfNotValid();
86
87
        $mode = $record->getKey() ? 'edit' : 'create';
88
89
        event(new BeforeSaveEvent($domain, $module, $request, $record, $mode));
0 ignored issues
show
Bug introduced by
The function event 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

89
        /** @scrutinizer ignore-call */ 
90
        event(new BeforeSaveEvent($domain, $module, $request, $record, $mode));
Loading history...
90
91
        // Save record
92
        $form->getModel()->save();
93
94
        event(new AfterSaveEvent($domain, $module, $request, $record, $mode));
95
96
        // Save relation if necessary
97
        if ($request->input('relatedlist') && $request->input('src_id')) {
98
            $relatedlist = Relatedlist::findOrFail($request->input('relatedlist'));
99
            $sourceRecordId = (int)$request->input('src_id');
100
            $tabId = $request->input('tab');
101
102
            if ($relatedlist->type === 'n-n') {
103
                $this->saveRelation($relatedlist, $sourceRecordId, $record->id);
104
            }
105
106
            $redirectToSourceRecord = true;
107
        }
108
109
        // Redirect
110
        if ($redirect === true) {
111
            // Redirect to source record if a relation was made
112
            if (isset($relatedlist) && $redirectToSourceRecord === true) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $redirectToSourceRecord does not seem to be defined for all execution paths leading up to this point.
Loading history...
113
                $params = [ 'id' => $sourceRecordId ];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $sourceRecordId does not seem to be defined for all execution paths leading up to this point.
Loading history...
114
115
                // Add tab id if defined to select it automaticaly
116
                if ($tabId) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tabId does not seem to be defined for all execution paths leading up to this point.
Loading history...
117
                    $params[ 'tab' ] = $tabId;
118
                }
119
                // Add related list id to select the related tab automaticaly
120
                else {
121
                    $params[ 'relatedlist' ] = $relatedlist->id;
122
                }
123
124
                $route = ucroute('uccello.detail', $domain, $relatedlist->module, $params);
125
            }
126
127
            // Redirect to edit if the user want to create a new record
128
            elseif ($request->input('save_new_hdn') === '1') {
129
                $route = ucroute('uccello.edit', $domain, $module);
130
131
                // Notification
132
                ucnotify(uctrans('notification.record.created', $module), 'success');
0 ignored issues
show
Bug introduced by
It seems like uctrans('notification.record.created', $module) can also be of type array; however, parameter $message of ucnotify() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

132
                ucnotify(/** @scrutinizer ignore-type */ uctrans('notification.record.created', $module), 'success');
Loading history...
133
            }
134
            // Else redirect to detail
135
            else {
136
                $route = ucroute('uccello.detail', $domain, $module, [ 'id' => $record->getKey() ]);
137
            }
138
139
            return redirect($route);
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

139
            return /** @scrutinizer ignore-call */ redirect($route);
Loading history...
140
        }
141
        // Or return record
142
        else {
143
            return $form->getModel();
144
        }
145
    }
146
147
    /**
148
     * Add a relation between two records
149
     *
150
     * @param Domain|null $domain
151
     * @param Module $module
152
     * @param Request $request
153
     * @return integer|null
154
     */
155
    public function addRelation(?Domain $domain, Module $module, Request $request)
156
    {
157
        // Pre-process
158
        $this->preProcess($domain, $module, $request);
159
160
        // Retrieve record or get a new empty instance
161
        $record = $this->getRecordFromRequest();
162
163
        if ($request->input('relatedlist') && $request->input('related_id')) {
164
            $relatedlist = Relatedlist::findOrFail($request->input('relatedlist'));
165
            $relatedRecordId = (int)$request->input('related_id');
166
167
            $relationId = $this->saveRelation($relatedlist, $record->id, $relatedRecordId);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $relationId is correct as $this->saveRelation($rel...->id, $relatedRecordId) targeting Uccello\Core\Http\Contro...troller::saveRelation() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
168
169
            $response = [
170
                'success' => true,
171
                'data' => $relationId
172
            ];
173
        } else {
174
            $response = [
175
                'success' => false,
176
                'message' => uctrans('error.field.mandatory', $module)
177
            ];
178
        }
179
180
        return $response;
181
    }
182
183
    /**
184
     * Delete a relation between two records
185
     *
186
     * @param Domain|null $domain
187
     * @param Module $module
188
     * @param Request $request
189
     * @return integer|null
190
     */
191
    public function deleteRelation(?Domain $domain, Module $module, Request $request)
192
    {
193
        // Pre-process
194
        $this->preProcess($domain, $module, $request);
195
196
        // Get related list if defined
197
        $relatedListId = $request->get('relatedlist');
198
        if ($relatedListId) {
199
            $relatedList = Relatedlist::find($relatedListId);
200
        } else {
201
            $relatedList = null;
202
        }
203
204
        // Delete relation if it is a N-N relation
205
        if ($relatedList && $relatedList->type === 'n-n') {
206
            $this->deleteRelationForNN($request);
207
            $message = 'notification.relation.deleted';
208
        }
209
        // Else delete record
210
        else {
211
            $this->deleteRecord($module, $request);
212
            $message = 'notification.record.deleted';
213
        }
214
215
        // Notification
216
        if (!empty($message)) {
217
            ucnotify(uctrans($message, $module), 'success');
0 ignored issues
show
Bug introduced by
It seems like uctrans($message, $module) can also be of type array; however, parameter $message of ucnotify() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

217
            ucnotify(/** @scrutinizer ignore-type */ uctrans($message, $module), 'success');
Loading history...
218
        }
219
220
        // Redirect to the previous page
221
        $route = $this->getRedirectionRoute();
222
223
        return redirect($route);
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

223
        return /** @scrutinizer ignore-call */ redirect($route);
Loading history...
224
    }
225
226
    public function getForm($record = null)
227
    {
228
        return $this->formBuilder->create(EditForm::class, [
229
            'model' => $record,
230
            'data' => [
231
                'domain' => $this->domain,
232
                'module' => $this->module,
233
                'request' => $this->request
234
            ]
235
        ]);
236
    }
237
238
    /**
239
     * Save relation between two records
240
     *
241
     * @param Relatedlist $relatedList
242
     * @param integer $recordId
243
     * @param integer $relatedRecordId
244
     * @return void
245
     */
246
    protected function saveRelation(Relatedlist $relatedList, int $recordId, int $relatedRecordId)
247
    {
248
        $relationName = $relatedList->relationName;
249
        $modelClass = $relatedList->module->model_class;
250
251
        $record = $modelClass::find($recordId);
252
253
        if ($record) {
254
            $relation = $record->$relationName();
255
            $relation->attach($relatedRecordId);
256
        }
257
    }
258
259
    /**
260
     * Retrieve the redirection route from request parameters.
261
     *
262
     * @return string
263
     */
264
    protected function getRedirectionRoute(): string
265
    {
266
        $request = $this->request;
267
        $domain = $this->domain;
268
        $module = $this->module;
269
270
        // Retrieve a related list by its id if it is defined
271
        if ($request->input('relatedlist')) {
272
            $relatedlist = Relatedlist::find($request->input('relatedlist'));
273
        }
274
275
        // Redirect to source record if a relation was deleted
276
        if (isset($relatedlist) && $request->input('id')) {
277
            $params = ['id' => $request->input('id')];
278
279
            // Add tab id if defined to select it automaticaly
280
            if ($request->input('tab')) {
281
                $params['tab'] = $request->input('tab');
282
            }
283
            // Add related list id to select the related tab automaticaly
284
            else {
285
                $params['relatedlist'] = $relatedlist->id;
286
            }
287
288
            $route = ucroute('uccello.detail', $domain, $relatedlist->module, $params);
289
        }
290
        // Else redirect to list
291
        else {
292
            $route = ucroute('uccello.list', $domain, $module);
293
        }
294
295
        return $route;
296
    }
297
298
    /**
299
     * Delete record after retrieving from the request
300
     *
301
     * @param Module $module
302
     * @param Request $request
303
     * @return void
304
     */
305
    protected function deleteRecord(Module $module, Request $request)
306
    {
307
        $relatedRecord = $this->getRecordFromRequest('related_id');
308
309
        // Delete record if exists
310
        if ($relatedRecord) {
311
            event(new BeforeDeleteEvent($this->domain, $module, $request, $relatedRecord, 'delete'));
0 ignored issues
show
Bug introduced by
The type Uccello\Core\Http\Contro...\Core\BeforeDeleteEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The function event 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

311
            /** @scrutinizer ignore-call */ 
312
            event(new BeforeDeleteEvent($this->domain, $module, $request, $relatedRecord, 'delete'));
Loading history...
312
313
            $relatedRecord->delete();
314
315
            event(new AfterDeleteEvent($this->domain, $module, $request, $relatedRecord, 'delete'));
0 ignored issues
show
Bug introduced by
The type Uccello\Core\Http\Contro...s\Core\AfterDeleteEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
316
        }
317
    }
318
319
    /**
320
     * Delete a relation for a N-N related list
321
     *
322
     * @return void
323
     */
324
    protected function deleteRelationForNN(Request $request)
325
    {
326
        $relatedListId = $request->get('relatedlist');
327
        $recordId = $request->get('id');
328
        $relatedRecordId = $request->get('related_id');
329
330
        // Get related list
331
        $relatedList = Relatedlist::find($relatedListId);
332
        $relationName = $relatedList->relationName;
333
334
        if ($relatedList) {
335
            // Get record
336
            $modelClass = $relatedList->module->model_class;
337
            $record = $modelClass::find($recordId);
338
339
            // Delete relation
340
            if ($record) {
341
                $record->$relationName()->detach($relatedRecordId);
342
            }
343
        }
344
    }
345
}
346