Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Test Failed
Push — v4dot1 ( 7c548f...d0147e )
by
unknown
06:45 queued 10s
created

CrudPanel::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel;
4
5
use Backpack\CRUD\app\Library\CrudPanel\Traits\Access;
6
use Backpack\CRUD\app\Library\CrudPanel\Traits\AutoFocus;
7
use Backpack\CRUD\app\Library\CrudPanel\Traits\AutoSet;
8
use Backpack\CRUD\app\Library\CrudPanel\Traits\Buttons;
9
use Backpack\CRUD\app\Library\CrudPanel\Traits\Columns;
10
use Backpack\CRUD\app\Library\CrudPanel\Traits\Create;
11
use Backpack\CRUD\app\Library\CrudPanel\Traits\Delete;
12
use Backpack\CRUD\app\Library\CrudPanel\Traits\Errors;
13
use Backpack\CRUD\app\Library\CrudPanel\Traits\FakeColumns;
14
use Backpack\CRUD\app\Library\CrudPanel\Traits\FakeFields;
15
use Backpack\CRUD\app\Library\CrudPanel\Traits\Fields;
16
use Backpack\CRUD\app\Library\CrudPanel\Traits\Filters;
17
use Backpack\CRUD\app\Library\CrudPanel\Traits\HeadingsAndTitles;
18
use Backpack\CRUD\app\Library\CrudPanel\Traits\Macroable;
19
use Backpack\CRUD\app\Library\CrudPanel\Traits\Operations;
20
use Backpack\CRUD\app\Library\CrudPanel\Traits\Query;
21
use Backpack\CRUD\app\Library\CrudPanel\Traits\Read;
22
use Backpack\CRUD\app\Library\CrudPanel\Traits\Relationships;
23
use Backpack\CRUD\app\Library\CrudPanel\Traits\Reorder;
24
use Backpack\CRUD\app\Library\CrudPanel\Traits\SaveActions;
25
use Backpack\CRUD\app\Library\CrudPanel\Traits\Search;
26
use Backpack\CRUD\app\Library\CrudPanel\Traits\Settings;
27
use Backpack\CRUD\app\Library\CrudPanel\Traits\Tabs;
28
use Backpack\CRUD\app\Library\CrudPanel\Traits\Update;
29
use Backpack\CRUD\app\Library\CrudPanel\Traits\Validation;
30
use Backpack\CRUD\app\Library\CrudPanel\Traits\Views;
31
use Backpack\CRUD\app\Library\CrudPanel\Traits\ViewsAndRestoresRevisions;
32
use Illuminate\Database\Eloquent\Collection;
33
use Illuminate\Database\Eloquent\Relations\Relation;
34
use Illuminate\Support\Arr;
35
36
class CrudPanel
37
{
38
    // load all the default CrudPanel features
39
    use Create, Read, Search, Update, Delete, Errors, Reorder, Access, Columns, Fields, Query, Buttons, AutoSet, FakeFields, FakeColumns, ViewsAndRestoresRevisions, AutoFocus, Filters, Tabs, Views, Validation, HeadingsAndTitles, Operations, SaveActions, Settings, Relationships;
0 ignored issues
show
introduced by
The trait Backpack\CRUD\app\Librar...ewsAndRestoresRevisions requires some properties which are not provided by Backpack\CRUD\app\Library\CrudPanel\CrudPanel: $created_at, $revisionHistory, $key, $old_value
Loading history...
Bug introduced by
The trait Backpack\CRUD\app\Librar...Panel\Traits\Operations requires the property $action which is not provided by Backpack\CRUD\app\Library\CrudPanel\CrudPanel.
Loading history...
introduced by
The trait Backpack\CRUD\app\Library\CrudPanel\Traits\Filters requires some properties which are not provided by Backpack\CRUD\app\Library\CrudPanel\CrudPanel: $options, $logic, $name, $fallbackLogic
Loading history...
introduced by
The trait Backpack\CRUD\app\Library\CrudPanel\Traits\Buttons requires some properties which are not provided by Backpack\CRUD\app\Library\CrudPanel\CrudPanel: $stack, $name
Loading history...
40
    // allow developers to add their own closures to this object
41
    use Macroable;
0 ignored issues
show
Bug introduced by
The trait Backpack\CRUD\app\Librar...dPanel\Traits\Macroable requires the property $name which is not provided by Backpack\CRUD\app\Library\CrudPanel\CrudPanel.
Loading history...
42
43
    // --------------
44
    // CRUD variables
45
    // --------------
46
    // These variables are passed to the CRUD views, inside the $crud variable.
47
    // All variables are public, so they can be modified from your EntityCrudController.
48
    // All functions and methods are also public, so they can be used in your EntityCrudController to modify these variables.
49
50
    public $model = "\App\Models\Entity"; // what's the namespace for your entity's model
51
    public $route; // what route have you defined for your entity? used for links.
52
    public $entity_name = 'entry'; // what name will show up on the buttons, in singural (ex: Add entity)
53
    public $entity_name_plural = 'entries'; // what name will show up on the buttons, in plural (ex: Delete 5 entities)
54
55
    public $entry;
56
57
    protected $request;
58
59
    // The following methods are used in CrudController or your EntityCrudController to manipulate the variables above.
60
61
    public function __construct()
62
    {
63
        $this->setRequest();
64
65
        if ($this->getCurrentOperation()) {
66
            $this->setOperation($this->getCurrentOperation());
67
        }
68
    }
69
70
    /**
71
     * Set the request instance for this CRUD.
72
     *
73
     * @param \Illuminate\Http\Request $request
74
     */
75
    public function setRequest($request = null)
76
    {
77
        $this->request = $request ?? \Request::instance();
78
    }
79
80
    /**
81
     * [getRequest description].
82
     * @return [type] [description]
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
83
     */
84
    public function getRequest()
85
    {
86
        return $this->request;
87
    }
88
89
    // ------------------------------------------------------
90
    // BASICS - model, route, entity_name, entity_name_plural
91
    // ------------------------------------------------------
92
93
    /**
94
     * This function binds the CRUD to its corresponding Model (which extends Eloquent).
95
     * All Create-Read-Update-Delete operations are done using that Eloquent Collection.
96
     *
97
     * @param string $model_namespace Full model namespace. Ex: App\Models\Article
98
     *
99
     * @throws \Exception in case the model does not exist
100
     */
101
    public function setModel($model_namespace)
102
    {
103
        if (! class_exists($model_namespace)) {
104
            throw new \Exception('The model does not exist.', 500);
105
        }
106
107
        if (! method_exists($model_namespace, 'hasCrudTrait')) {
108
            throw new \Exception('Please use CrudTrait on the model.', 500);
109
        }
110
111
        $this->model = new $model_namespace();
112
        $this->query = $this->model->select('*');
113
        $this->entry = null;
114
    }
115
116
    /**
117
     * Get the corresponding Eloquent Model for the CrudController, as defined with the setModel() function.
118
     *
119
     * @return string|\Illuminate\Database\Eloquent\Model
120
     */
121
    public function getModel()
122
    {
123
        return $this->model;
124
    }
125
126
    /**
127
     * Get the database connection, as specified in the .env file or overwritten by the property on the model.
128
     *
129
     * @return \Illuminate\Database\Schema\Builder
130
     */
131
    private function getSchema()
132
    {
133
        return $this->getModel()->getConnection()->getSchemaBuilder();
134
    }
135
136
    /**
137
     * Check if the database connection driver is using mongodb.
138
     *
139
     * @return bool
140
     */
141
    private function driverIsMongoDb()
142
    {
143
        return $this->getSchema()->getConnection()->getConfig()['driver'] === 'mongodb';
144
    }
145
146
    /**
147
     * Set the route for this CRUD.
148
     * Ex: admin/article.
149
     *
150
     * @param string $route Route name.
151
     */
152
    public function setRoute($route)
153
    {
154
        $this->route = $route;
155
    }
156
157
    /**
158
     * Set the route for this CRUD using the route name.
159
     * Ex: admin.article.
160
     *
161
     * @param string $route      Route name.
162
     * @param array  $parameters Parameters.
163
     *
164
     * @throws \Exception
165
     */
166
    public function setRouteName($route, $parameters = [])
167
    {
168
        $complete_route = $route.'.index';
169
170
        if (! \Route::has($complete_route)) {
171
            throw new \Exception('There are no routes for this route name.', 404);
172
        }
173
174
        $this->route = route($complete_route, $parameters);
175
        $this->initButtons();
0 ignored issues
show
Bug introduced by
The method initButtons() does not exist on Backpack\CRUD\app\Library\CrudPanel\CrudPanel. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

175
        $this->/** @scrutinizer ignore-call */ 
176
               initButtons();
Loading history...
176
    }
177
178
    /**
179
     * Get the current CrudController route.
180
     *
181
     * Can be defined in the CrudController with:
182
     * - $this->crud->setRoute(config('backpack.base.route_prefix').'/article')
183
     * - $this->crud->setRouteName(config('backpack.base.route_prefix').'.article')
184
     * - $this->crud->route = config('backpack.base.route_prefix')."/article"
185
     *
186
     * @return string
187
     */
188
    public function getRoute()
189
    {
190
        return $this->route;
191
    }
192
193
    /**
194
     * Set the entity name in singular and plural.
195
     * Used all over the CRUD interface (header, add button, reorder button, breadcrumbs).
196
     *
197
     * @param string $singular Entity name, in singular. Ex: article
198
     * @param string $plural   Entity name, in plural. Ex: articles
199
     */
200
    public function setEntityNameStrings($singular, $plural)
201
    {
202
        $this->entity_name = $singular;
203
        $this->entity_name_plural = $plural;
204
    }
205
206
    // -----------------------------------------------
207
    // ACTIONS - the current operation being processed
208
    // -----------------------------------------------
209
210
    /**
211
     * Get the action being performed by the controller,
212
     * including middleware names, route name, method name,
213
     * namespace, prefix, etc.
214
     *
215
     * @return string The EntityCrudController route action array.
216
     */
217
    public function getAction()
218
    {
219
        return $this->getRequest()->route()->getAction();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getRequest()->route()->getAction() also could return the type array which is incompatible with the documented return type string.
Loading history...
220
    }
221
222
    /**
223
     * Get the full name of the controller method
224
     * currently being called (including namespace).
225
     *
226
     * @return string The EntityCrudController full method name with namespace.
227
     */
228
    public function getActionName()
229
    {
230
        return $this->getRequest()->route()->getActionName();
231
    }
232
233
    /**
234
     * Get the name of the controller method
235
     * currently being called.
236
     *
237
     * @return string The EntityCrudController method name.
238
     */
239
    public function getActionMethod()
240
    {
241
        return $this->getRequest()->route()->getActionMethod();
242
    }
243
244
    /**
245
     * Check if the controller method being called
246
     * matches a given string.
247
     *
248
     * @param string $methodName Name of the method (ex: index, create, update)
249
     *
250
     * @return bool Whether the condition is met or not.
251
     */
252
    public function actionIs($methodName)
253
    {
254
        return $methodName === $this->getActionMethod();
255
    }
256
257
    // ----------------------------------
258
    // Miscellaneous functions or methods
259
    // ----------------------------------
260
261
    /**
262
     * Return the first element in an array that has the given 'type' attribute.
263
     *
264
     * @param string $type
265
     * @param array  $array
266
     *
267
     * @return array
268
     */
269
    public function getFirstOfItsTypeInArray($type, $array)
270
    {
271
        return Arr::first($array, function ($item) use ($type) {
272
            return $item['type'] == $type;
273
        });
274
    }
275
276
    // ------------
277
    // TONE FUNCTIONS - UNDOCUMENTED, UNTESTED, SOME MAY BE USED IN THIS FILE
278
    // ------------
279
    //
280
    // TODO:
281
    // - figure out if they are really needed
282
    // - comments inside the function to explain how they work
283
    // - write docblock for them
284
    // - place in the correct section above (CREATE, READ, UPDATE, DELETE, ACCESS, MANIPULATION)
285
286
    public function sync($type, $fields, $attributes)
287
    {
288
        if (! empty($this->{$type})) {
289
            $this->{$type} = array_map(function ($field) use ($fields, $attributes) {
290
                if (in_array($field['name'], (array) $fields)) {
291
                    $field = array_merge($field, $attributes);
292
                }
293
294
                return $field;
295
            }, $this->{$type});
296
        }
297
    }
298
299
    /**
300
     * Get the Eloquent Model name from the given relation definition string.
301
     *
302
     * @example For a given string 'company' and a relation between App/Models/User and App/Models/Company, defined by a
303
     *          company() method on the user model, the 'App/Models/Company' string will be returned.
304
     * @example For a given string 'company.address' and a relation between App/Models/User, App/Models/Company and
305
     *          App/Models/Address defined by a company() method on the user model and an address() method on the
306
     *          company model, the 'App/Models/Address' string will be returned.
307
     *
308
     * @param string                              $relationString Relation string. A dot notation can be used to chain multiple relations.
309
     * @param int                                 $length         Optionally specify the number of relations to omit from the start of the relation string. If
310
     *                                                            the provided length is negative, then that many relations will be omitted from the end of the relation
311
     *                                                            string.
312
     * @param \Illuminate\Database\Eloquent\Model $model          Optionally specify a different model than the one in the crud object.
313
     *
314
     * @return string Relation model name.
315
     */
316
    public function getRelationModel($relationString, $length = null, $model = null)
317
    {
318
        $relationArray = explode('.', $relationString);
319
320
        if (! isset($length)) {
321
            $length = count($relationArray);
322
        }
323
324
        if (! isset($model)) {
325
            $model = $this->model;
326
        }
327
328
        $result = array_reduce(array_splice($relationArray, 0, $length), function ($obj, $method) {
329
            return $obj->$method()->getRelated();
330
        }, $model);
331
332
        return get_class($result);
333
    }
334
335
    /**
336
     * Get the given attribute from a model or models resulting from the specified relation string (eg: the list of streets from
337
     * the many addresses of the company of a given user).
338
     *
339
     * @param \Illuminate\Database\Eloquent\Model $model          Model (eg: user).
340
     * @param string                              $relationString Model relation. Can be a string representing the name of a relation method in the given
341
     *                                                            Model or one from a different Model through multiple relations. A dot notation can be used to specify
342
     *                                                            multiple relations (eg: user.company.address).
343
     * @param string                              $attribute      The attribute from the relation model (eg: the street attribute from the address model).
344
     *
345
     * @return array An array containing a list of attributes from the resulting model.
346
     */
347
    public function getRelatedEntriesAttributes($model, $relationString, $attribute)
348
    {
349
        $endModels = $this->getRelatedEntries($model, $relationString);
350
        $attributes = [];
351
        foreach ($endModels as $model => $entries) {
0 ignored issues
show
introduced by
$model is overwriting one of the parameters of this function.
Loading history...
352
            $modelKey = (new $model())->getKeyName();
353
            if (is_array($entries) && ! isset($entries[$attribute])) {
354
                foreach ($entries as $entry) {
355
                    $attributes[$entry[$modelKey]] = $entry[$attribute];
356
                }
357
            } elseif (is_array($entries) && isset($entries[$attribute])) {
358
                $attributes[$entries[$modelKey]] = $entries[$attribute];
359
            } elseif ($entries->{$attribute}) {
360
                $attributes[$entries->{$modelKey}] = $entries->{$attribute};
361
            }
362
        }
363
364
        return $attributes;
365
    }
366
367
    /**
368
     * Traverse the tree of relations for the given model, defined by the given relation string, and return the ending
369
     * associated model instance or instances.
370
     *
371
     * @param \Illuminate\Database\Eloquent\Model $model          The CRUD model.
372
     * @param string                              $relationString Relation string. A dot notation can be used to chain multiple relations.
373
     *
374
     * @return array An array of the associated model instances defined by the relation string.
375
     */
376
    private function getRelatedEntries($model, $relationString)
377
    {
378
        $relationArray = explode('.', $relationString);
379
        $firstRelationName = Arr::first($relationArray);
380
        $relation = $model->{$firstRelationName};
381
        $currentResults = [];
382
383
        $results = [];
384
        if (! is_null($relation)) {
385
            if ($relation instanceof Collection && ! $relation->isEmpty()) {
386
                $currentResults[get_class($relation->first())] = $relation->toArray();
387
            } elseif (is_array($relation) && ! empty($relation)) {
388
                $currentResults[get_class($relation->first())] = $relation;
389
            } else {
390
                //relation must be App\Models\Article or App\Models\Category
391
                if (! $relation instanceof Collection && ! empty($relation)) {
392
                    $currentResults[get_class($relation)] = $relation->toArray();
393
                }
394
            }
395
396
            array_shift($relationArray);
397
398
            if (! empty($relationArray)) {
399
                foreach ($currentResults as $model => $currentResult) {
0 ignored issues
show
introduced by
$model is overwriting one of the parameters of this function.
Loading history...
400
                    $results[$model] = array_merge($results[$model], $this->getRelatedEntries($currentResult, implode('.', $relationArray)));
401
                }
402
            } else {
403
                $results = $currentResults;
404
            }
405
        }
406
407
        return $results;
408
    }
409
}
410