EditController::deleteRelation()   B
last analyzed

Complexity

Conditions 7
Paths 12

Size

Total Lines 37
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 37
rs 8.8333
cc 7
nc 12
nop 3
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;
7
use Uccello\Core\Forms\EditForm;
8
use Uccello\Core\Events\BeforeSaveEvent;
9
use Uccello\Core\Events\AfterSaveEvent;
10
use Uccello\Core\Events\BeforeDeleteEvent;
11
use Uccello\Core\Events\AfterDeleteEvent;
12
use Uccello\Core\Models\Domain;
13
use Uccello\Core\Models\Module;
14
use Uccello\Core\Models\Relatedlist;
15
16
class EditController extends Controller
17
{
18
    protected $viewName = 'edit.main';
19
    protected $formBuilder;
20
21
    /**
22
     * Check user permissions
23
     */
24
    protected function checkPermissions()
25
    {
26
        if (request()->has('id')) {
27
            $this->middleware('uccello.permissions:update');
28
        } else {
29
            $this->middleware('uccello.permissions:create');
30
        }
31
    }
32
33
    public function __construct(FormBuilder $formBuilder)
34
    {
35
        $this->formBuilder = $formBuilder;
36
37
        parent::__construct();
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function process(?Domain $domain, Module $module, Request $request)
44
    {
45
        // Pre-process
46
        $this->preProcess($domain, $module, $request);
47
48
        // Retrieve record or get a new empty instance
49
        $record = $this->getRecordFromRequest();
50
51
        // Get form
52
        $form = $this->getForm($record);
53
54
        // Get mode
55
        $mode = !is_null($record->getKey()) ? 'edit' : 'create';
56
57
        return $this->autoView([
58
            'form' => $form,
59
            'record' => $record,
60
            'mode' => $mode
61
        ]);
62
    }
63
64
    /**
65
     * Create or update record into database
66
     *
67
     * @param Domain|null $domain
68
     * @param Module $module
69
     * @param boolean $redirect
70
     * @return void
71
     */
72
    public function save(?Domain $domain, Module $module, Request $request, bool $redirect = true)
73
    {
74
        // Pre-process
75
        $this->preProcess($domain, $module, $request);
76
77
        // Get model class used by the module
78
        $modelClass = $this->module->model_class;
0 ignored issues
show
Bug introduced by
The property model_class does not seem to exist on Uccello\Core\Models\Module. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
Unused Code introduced by
The assignment to $modelClass is dead and can be removed.
Loading history...
79
80
        // Retrieve record or get a new empty instance
81
        $record = $this->getRecordFromRequest();
82
83
        // Get form
84
        $form = $this->getForm($record);
85
86
        // Redirect if form not valid (the record is made here)
87
        $form->redirectIfNotValid();
88
89
        $mode = $record->getKey() ? 'edit' : 'create';
90
91
        event(new BeforeSaveEvent($domain, $module, $request, $record, $mode));
92
93
        // Save record
94
        $form->getModel()->save();
95
96
        event(new AfterSaveEvent($domain, $module, $request, $record, $mode));
97
98
        // Save relation if necessary
99
        if ($request->input('relatedlist') && $request->input('src_id')) {
100
            $relatedlist = Relatedlist::findOrFail($request->input('relatedlist'));
101
            $sourceRecordId = (int)$request->input('src_id');
102
            $tabId = $request->input('tab');
103
104
            if ($relatedlist->type === 'n-n') {
0 ignored issues
show
Bug introduced by
The property type does not seem to exist on Uccello\Core\Models\Relatedlist. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
105
                $this->saveRelation($relatedlist, $sourceRecordId, $record->id);
106
            }
107
108
            $redirectToSourceRecord = true;
109
        }
110
111
        // Redirect
112
        if ($redirect === true) {
113
            // Redirect to source record if a relation was made
114
            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...
115
                $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...
116
117
                // Add tab id if defined to select it automaticaly
118
                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...
119
                    $params[ 'tab' ] = $tabId;
120
                }
121
                // Add related list id to select the related tab automaticaly
122
                else {
123
                    $params[ 'relatedlist' ] = $relatedlist->id;
124
                }
125
126
                $route = ucroute('uccello.detail', $domain, $relatedlist->module, $params);
127
            }
128
129
            // Redirect to edit if the user want to create a new record
130
            elseif ($request->input('save_new_hdn') === '1') {
131
                $route = ucroute('uccello.edit', $domain, $module);
132
133
                // Notification
134
                ucnotify(uctrans('notification.record.created', $module), 'success');
135
            }
136
            // Else redirect to detail
137
            else {
138
                $route = ucroute('uccello.detail', $domain, $module, [ 'id' => $record->getKey() ]);
139
            }
140
141
            return redirect($route);
0 ignored issues
show
Bug Best Practice introduced by
The expression return redirect($route) returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type void.
Loading history...
142
        }
143
        // Or return record
144
        else {
145
            return $form->getModel();
146
        }
147
    }
148
149
    /**
150
     * Restore a record from trash
151
     *
152
     * @param Domain|null $domain
153
     * @param Module $module
154
     * @param Request $request
155
     * @return @return \Illuminate\Http\Response
0 ignored issues
show
Documentation Bug introduced by
The doc comment @return at position 0 could not be parsed: Unknown type name '@return' at position 0 in @return.
Loading history...
156
     */
157
    public function restore(?Domain $domain, Module $module, Request $request)
158
    {
159
        // Pre-process
160
        $this->preProcess($domain, $module, $request);
161
162
        // Retrieve record
163
        $recordId = (int) request('id');
164
        $modelClass = $module->model_class;
0 ignored issues
show
Bug introduced by
The property model_class does not seem to exist on Uccello\Core\Models\Module. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
165
        $record = $modelClass::onlyTrashed()->findOrFail($recordId);
166
167
        // Restore record if exists
168
        if ($record) {
169
            $record->restore();
170
171
            ucnotify(uctrans('notification.record.restored', $module), 'success');
172
        }
173
174
        // Redirect to the trash list
175
        $route = ucroute('uccello.list', $domain, $module, ['filter' => 'trash']);
176
        return redirect($route);
177
    }
178
179
    /**
180
     * Add a relation between two records
181
     *
182
     * @param Domain|null $domain
183
     * @param Module $module
184
     * @param Request $request
185
     * @return integer|null
186
     */
187
    public function addRelation(?Domain $domain, Module $module, Request $request)
188
    {
189
        // Pre-process
190
        $this->preProcess($domain, $module, $request);
191
192
        // Retrieve record or get a new empty instance
193
        $record = $this->getRecordFromRequest();
194
195
        if ($request->input('relatedlist') && $request->input('related_id')) {
196
            $relatedlist = Relatedlist::findOrFail($request->input('relatedlist'));
197
            $relatedRecordId = (int)$request->input('related_id');
198
199
            $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...
200
201
            $response = [
202
                'success' => true,
203
                'data' => $relationId
204
            ];
205
        } else {
206
            $response = [
207
                'success' => false,
208
                'message' => uctrans('error.field.mandatory', $module)
209
            ];
210
        }
211
212
        return $response;
213
    }
214
215
    /**
216
     * Delete a relation between two records
217
     *
218
     * @param Domain|null $domain
219
     * @param Module $module
220
     * @param Request $request
221
     * @return integer|null
222
     */
223
    public function deleteRelation(?Domain $domain, Module $module, Request $request)
224
    {
225
        // Pre-process
226
        $this->preProcess($domain, $module, $request);
227
228
        // Get related list if defined
229
        $relatedListId = $request->get('relatedlist');
230
        if ($relatedListId) {
231
            $relatedList = Relatedlist::find($relatedListId);
232
        } else {
233
            $relatedList = null;
234
        }
235
236
        
237
        if ($relatedList && $relatedList->type === 'n-n') {
0 ignored issues
show
Bug introduced by
The property type does not seem to exist on Uccello\Core\Models\Relatedlist. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
238
            // Delete relation if it is a N-N relation
239
            $this->deleteRelationForNN($request);
240
            $message = 'notification.relation.deleted';
241
        } elseif ($relatedList && $relatedList->type === 'n-1') {
242
            // Delete relation if it is a N-1 relation
243
            $this->deleteRelationForN1($request);
244
            $message = 'notification.relation.deleted';
245
        } else {
246
            // Else delete record
247
            $this->deleteRecord($module, $request);
248
            $message = 'notification.record.deleted';
249
        }
250
251
        // Notification
252
        if (!empty($message)) {
253
            ucnotify(uctrans($message, $module), 'success');
254
        }
255
256
        // Redirect to the previous page
257
        $route = $this->getRedirectionRoute();
258
259
        return redirect($route);
0 ignored issues
show
Bug Best Practice introduced by
The expression return redirect($route) returns the type Illuminate\Http\RedirectResponse which is incompatible with the documented return type integer|null.
Loading history...
260
    }
261
262
    public function getForm($record = null)
263
    {
264
        return $this->formBuilder->create(EditForm::class, [
265
            'model' => $record,
266
            'data' => [
267
                'domain' => $this->domain,
268
                'module' => $this->module,
269
                'request' => $this->request
270
            ]
271
        ]);
272
    }
273
274
    /**
275
     * Save relation between two records
276
     *
277
     * @param Relatedlist $relatedList
278
     * @param integer $recordId
279
     * @param integer $relatedRecordId
280
     * @return void
281
     */
282
    protected function saveRelation(Relatedlist $relatedList, int $recordId, int $relatedRecordId)
283
    {
284
        $relationName = $relatedList->relationName;
285
        $modelClass = $relatedList->module->model_class;
0 ignored issues
show
Bug introduced by
The property model_class does not seem to exist on Uccello\Core\Models\Module. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
286
287
        $record = $modelClass::find($recordId);
288
289
        if ($record) {
290
            $relation = $record->$relationName();
291
            if ($relatedList->type=='n-n') {
0 ignored issues
show
Bug introduced by
The property type does not seem to exist on Uccello\Core\Models\Relatedlist. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
292
                $relation->attach($relatedRecordId);
293
            } elseif ($relatedList->type=='n-1') {
294
                $relatedModelClass = $relatedList->relatedModule->model_class;
295
                $related_record = $relatedModelClass::find($relatedRecordId);
296
                $relation->save($related_record);
297
            }
298
        }
299
    }
300
301
    /**
302
     * Retrieve the redirection route from request parameters.
303
     *
304
     * @return string
305
     */
306
    protected function getRedirectionRoute(): string
307
    {
308
        $request = $this->request;
309
        $domain = $this->domain;
310
        $module = $this->module;
311
312
        // Retrieve a related list by its id if it is defined
313
        if ($request->input('relatedlist')) {
314
            $relatedlist = Relatedlist::find($request->input('relatedlist'));
315
        }
316
317
        // Redirect to source record if a relation was deleted
318
        if (isset($relatedlist) && $request->input('id')) {
319
            $params = ['id' => $request->input('id')];
320
321
            // Add tab id if defined to select it automaticaly
322
            if ($request->input('tab')) {
323
                $params['tab'] = $request->input('tab');
324
            }
325
            // Add related list id to select the related tab automaticaly
326
            else {
327
                $params['relatedlist'] = $relatedlist->id;
328
            }
329
330
            $route = ucroute('uccello.detail', $domain, $relatedlist->module, $params);
331
        }
332
        // Else redirect to list
333
        else {
334
            $route = ucroute('uccello.list', $domain, $module);
335
        }
336
337
        return $route;
338
    }
339
340
    /**
341
     * Delete record after retrieving from the request
342
     *
343
     * @param Module $module
344
     * @param Request $request
345
     * @return void
346
     */
347
    protected function deleteRecord(Module $module, Request $request)
348
    {
349
        $relatedRecord = $this->getRecordFromRequest('related_id');
350
351
        // Delete record if exists
352
        if ($relatedRecord) {
353
            event(new BeforeDeleteEvent($this->domain, $module, $request, $relatedRecord, 'delete'));
354
355
            $relatedRecord->delete();
356
357
            event(new AfterDeleteEvent($this->domain, $module, $request, $relatedRecord, 'delete'));
358
        }
359
    }
360
361
    /**
362
     * Delete a relation for a N-N related list
363
     *
364
     * @return void
365
     */
366
    protected function deleteRelationForNN(Request $request)
367
    {
368
        $relatedListId = $request->get('relatedlist');
369
        $recordId = $request->get('id');
370
        $relatedRecordId = $request->get('related_id');
371
372
        // Get related list
373
        $relatedList = Relatedlist::find($relatedListId);
374
        $relationName = $relatedList->relationName;
375
376
        if ($relatedList) {
377
            // Get record
378
            $modelClass = $relatedList->module->model_class;
0 ignored issues
show
Bug introduced by
The property model_class does not seem to exist on Uccello\Core\Models\Module. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
379
            $record = $modelClass::find($recordId);
380
381
            // Delete relation
382
            if ($record) {
383
                $record->$relationName()->detach($relatedRecordId);
384
            }
385
        }
386
    }
387
388
    /**
389
     * Delete a relation for a N-1 related list
390
     *
391
     * @return void
392
     */
393
    protected function deleteRelationForN1(Request $request)
394
    {
395
        $relatedListId = $request->get('relatedlist');
396
        $recordId = $request->get('id');
397
        $relatedRecordId = $request->get('related_id');
398
        $relatedList = Relatedlist::find($relatedListId);
399
        $modelClass = $relatedList->module->model_class;
0 ignored issues
show
Bug introduced by
The property model_class does not seem to exist on Uccello\Core\Models\Module. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
400
        $record = $modelClass::find($recordId);
401
        if ($record) {
402
            $relatedModelClass = $relatedList->relatedModule->model_class;
403
            $related_record = $relatedModelClass::find($relatedRecordId);
404
            $relationName = $relatedList->module->name;
0 ignored issues
show
Bug introduced by
The property name does not seem to exist on Uccello\Core\Models\Module. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
405
            
406
            $related_record->$relationName()->dissociate();
407
            $related_record->save();
408
        }
409
    }
410
}
411