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

Passed
Push — CrudButton-fixees ( a4c9f3...1a6e15 )
by Pedro
15:19
created

CrudButton::__construct()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 29
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 12
c 0
b 0
f 0
nc 8
nop 5
dl 0
loc 29
rs 8.8333
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel;
4
5
use Backpack\CRUD\ViewNamespaces;
6
use Illuminate\Contracts\Support\Arrayable;
7
use Backpack\CRUD\app\Library\CrudPanel\Enums\ButtonStackEnum;
8
use Backpack\CRUD\app\Library\CrudPanel\Enums\ButtonPositionEnum;
9
10
/**
11
 * Adds fluent syntax to Backpack CRUD Buttons.
12
 *
13
 * In addition to the existing:
14
 * - CRUD::addButton('top', 'create', 'view', 'crud::buttons.create');
15
 *
16
 * Developers can also do:
17
 * - CRUD::button('create')->stack('top')->view('crud::buttons.create');
18
 *
19
 * And if the developer uses CrudButton as Button in their CrudController:
20
 * - Button::name('create')->stack('top')->view('crud::butons.create');
21
 */
22
class CrudButton implements Arrayable
23
{
24
    public $stack;
25
26
    public $name;
27
28
    public $type;
29
30
    public $content;
31
32
    public $position;
33
34
    public function __construct($name, $stack = null, $type = null, $content = null, $position = null)
35
    {
36
        // in case an array was passed as name
37
        // assume it's an array that includes [$name, $stack, $type, $content]
38
        if (is_array($name)) {
39
            extract($name);
40
        }
41
42
        // check if position is a valid position
43
        if ($position && ! ButtonPositionEnum::isValid($position)) {
44
            throw new \Exception('CRUD Button position "'.$position.'" is not a valid position. Please use one of the following: '.implode(', ', ButtonPositionEnum::getValues()), 500);
45
        }
46
47
        // check if stack is a valid stack
48
        if ($stack && ! ButtonStackEnum::isValid($stack)) {
49
                throw new \Exception('CRUD Button stack "'.$stack.'" is not a valid stack. Please use one of the following: '.implode(', ', ButtonStackEnum::getValues()), 500);
50
        }
51
        
52
        $this->name = $name ?? 'button_'.rand(1, 999999999);
53
        $this->stack = $stack ?? 'top';
54
        $this->type = $type ?? 'view';
55
        $this->content = $content;
56
57
        // if no position was passed, the defaults are:
58
        // - 'beginning' for the 'line' stack
59
        // - 'end' for all other stacks
60
        $this->position = $position ?? ($this->stack == 'line' ? 'beginning' : 'end');
61
62
        return $this->save();
63
    }
64
65
    // ------
66
    // MAKERS
67
    // ------
68
69
    /**
70
     * Add a new button to the default stack.
71
     *
72
     * @param  string|array  $attributes  Button name or array that contains name, stack, type and content.
73
     */
74
    public static function name($attributes = null)
75
    {
76
        return new static($attributes);
77
    }
78
79
    /**
80
     * Add a new button to the default stack.
81
     *
82
     * @param  string|array  $attributes  Button name or array that contains name, stack, type and content.
83
     */
84
    public static function add($attributes = null)
85
    {
86
        return new static($attributes);
87
    }
88
89
    /**
90
     * This method allows one to create a button without attaching it to any 'real'
91
     * button stack, by moving it to a 'hidden' stack.
92
     *
93
     * It exists for one reason: so that developers can add buttons to a custom array, without
94
     * adding them to one of the button stacks.
95
     *
96
     * Ex: when developers need to pass multiple buttons as contents of the
97
     * div button. But they don't want them added to the before_content of after_content
98
     * stacks. So what they do is basically add them to a 'hidden' stack, that nobody will ever see.
99
     *
100
     * @param  string|array  $attributes  Button name or array that contains name, stack, type and content.
101
     * @return CrudButton
102
     */
103
    public static function make($attributes = null)
104
    {
105
        $button = static::add($attributes);
106
        $button->stack('hidden');
107
108
        return $button;
109
    }
110
111
    // -------
112
    // SETTERS
113
    // -------
114
115
    /**
116
     * Set the button stack (where the button will be shown).
117
     *
118
     * @param  string  $stack  The name of the stack where the button should be moved.
119
     * @return CrudButton
120
     */
121
    public function stack($stack)
122
    {
123
        $this->stack = $stack;
124
125
        return $this->save();
126
    }
127
128
    /**
129
     * Sets the button type (view or model_function).
130
     *
131
     * @param  string  $type  The type of button - view or model_function.
132
     * @return CrudButton
133
     */
134
    public function type($type)
135
    {
136
        $this->type = $type;
137
138
        return $this->save();
139
    }
140
141
    /**
142
     * Sets the content of the button.
143
     * For the view button type, set it to the view path, including namespace.
144
     * For the model_function button type, set it to the name of the method on the model.
145
     *
146
     * @param  string  $content  Path to view or name of method on Model.
147
     * @return CrudButton
148
     */
149
    public function content($content)
150
    {
151
        $this->content = $content;
152
153
        return $this->save();
154
    }
155
156
    /**
157
     * Sets the namespace and path of the view for this button.
158
     * Sets the button type as 'view'.
159
     *
160
     * @param  string  $value  Path to view file.
161
     * @return CrudButton
162
     */
163
    public function view($value)
164
    {
165
        $this->content = $value;
166
        $this->type = 'view';
167
168
        return $this->save();
169
    }
170
171
    /**
172
     * Sets the name of the method on the model that contains the HTML for this button.
173
     * Sets the button type as 'model_function'.
174
     *
175
     * @param  string  $value  Name of the method on the model.
176
     * @return CrudButton
177
     */
178
    public function modelFunction($value)
179
    {
180
        $this->content = $value;
181
        $this->type = 'model_function';
182
        $this->stack = 'line';
183
184
        return $this->save();
185
    }
186
187
    /**
188
     * Sets the name of the method on the model that contains the HTML for this button.
189
     * Sets the button type as 'model_function'.
190
     * Alias of the modelFunction() method.
191
     *
192
     * @param  string  $value  Name of the method on the model.
193
     * @return CrudButton
194
     */
195
    public function model_function($value)
196
    {
197
        return $this->modelFunction($value);
198
    }
199
200
    /**
201
     * Unserts an property that is set on the current button.
202
     * Possible properties: name, stack, type, content.
203
     *
204
     * @param  string  $property  Name of the property that should be cleared.
205
     * @return CrudButton
206
     */
207
    public function forget($property)
208
    {
209
        $this->{$property} = null;
210
211
        return $this->save();
212
    }
213
214
    // --------------
215
    // SETTER ALIASES
216
    // --------------
217
218
    /**
219
     * Moves the button to a certain button stack.
220
     * Alias of stack().
221
     *
222
     * @param  string  $stack  The name of the stack where the button should be moved.
223
     * @return self
224
     */
225
    public function to($stack)
226
    {
227
        return $this->stack($stack);
228
    }
229
230
    /**
231
     * Moves the button to a certain button stack.
232
     * Alias of stack().
233
     *
234
     * @param  string  $stack  The name of the stack where the button should be moved.
235
     * @return self
236
     */
237
    public function group($stack)
238
    {
239
        return $this->stack($stack);
240
    }
241
242
    /**
243
     * Moves the button to a certain button stack.
244
     * Alias of stack().
245
     *
246
     * @param  string  $stack  The name of the stack where the button should be moved.
247
     * @return self
248
     */
249
    public function section($stack)
250
    {
251
        return $this->stack($stack);
252
    }
253
254
    // -------
255
    // GETTERS
256
    // -------
257
258
    /**
259
     * Get the end result that should be displayed to the user.
260
     * The HTML itself of the button.
261
     *
262
     * @param  object|null  $entry  The eloquent Model for the current entry or null if no current entry.
263
     * @return HTML
0 ignored issues
show
Bug introduced by
The type Backpack\CRUD\app\Library\CrudPanel\HTML 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...
264
     */
265
    public function getHtml($entry = null)
266
    {
267
        $button = $this;
268
        $crud = $this->crud();
269
270
        if ($this->type == 'model_function') {
271
            if (is_null($entry)) {
272
                return $crud->model->{$button->content}($crud);
273
            }
274
275
            return $entry->{$button->content}($crud);
276
        }
277
278
        if ($this->type == 'view') {
279
            return view($button->getFinalViewPath(), compact('button', 'crud', 'entry'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return view($button->get...ton', 'crud', 'entry')) returns the type Illuminate\View\View which is incompatible with the documented return type Backpack\CRUD\app\Library\CrudPanel\HTML.
Loading history...
280
        }
281
282
        abort(500, 'Unknown button type');
283
    }
284
285
    /**
286
     * Get an array of full paths to the filter view, consisting of:
287
     * - the path given in the button definition
288
     * - fallback view paths as configured in backpack/config/crud.php.
289
     *
290
     * @return array
291
     */
292
    private function getViewPathsWithFallbacks()
293
    {
294
        $type = $this->name;
295
        $paths = array_map(function ($item) use ($type) {
296
            return $item.'.'.$type;
297
        }, ViewNamespaces::getFor('buttons'));
298
299
        return array_merge([$this->content], $paths);
300
    }
301
302
    private function getFinalViewPath()
303
    {
304
        foreach ($this->getViewPathsWithFallbacks() as $path) {
305
            if (view()->exists($path)) {
306
                return $path;
307
            }
308
        }
309
310
        abort(500, 'Button view and fallbacks do not exist for '.$this->name.' button.');
311
    }
312
313
    /**
314
     * Get the key for this button in the global buttons collection.
315
     *
316
     * @return int
317
     */
318
    public function getKey()
319
    {
320
        return $this->crud()->getButtonKey($this->name);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->crud()->getButtonKey($this->name) returns the type string which is incompatible with the documented return type integer.
Loading history...
321
    }
322
323
    // -----
324
    // ORDER
325
    // -----
326
    // Manipulate the button collection (inside the global CrudPanel object).
327
328
    /**
329
     * Move this button to be the first in the buttons list.
330
     *
331
     * @return CrudButton
332
     */
333
    public function makeFirst()
334
    {
335
        return $this->before($this->collection()->first()->name);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->before($th...ction()->first()->name) returns the type Backpack\CRUD\app\Library\CrudPanel\CrudFilter which is incompatible with the documented return type Backpack\CRUD\app\Library\CrudPanel\CrudButton.
Loading history...
336
    }
337
338
    /**
339
     * Move this button to be the last one in the buttons list.
340
     *
341
     * @return CrudButton
342
     */
343
    public function makeLast()
344
    {
345
        return $this->after($this->collection()->last()->name);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->after($thi...ection()->last()->name) returns the type Backpack\CRUD\app\Library\CrudPanel\CrudFilter which is incompatible with the documented return type Backpack\CRUD\app\Library\CrudPanel\CrudButton.
Loading history...
346
    }
347
348
    /**
349
     * Move the current filter after another filter.
350
     *
351
     * @param  string  $destination  Name of the destination filter.
352
     * @return CrudFilter
353
     */
354
    public function after($destination)
355
    {
356
        $this->crud()->moveButton($this->name, 'after', $destination);
357
358
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Backpack\CRUD\app\Library\CrudPanel\CrudButton which is incompatible with the documented return type Backpack\CRUD\app\Library\CrudPanel\CrudFilter.
Loading history...
359
    }
360
361
    /**
362
     * Move the current field before another field.
363
     *
364
     * @param  string  $destination  Name of the destination field.
365
     * @return CrudFilter
366
     */
367
    public function before($destination)
368
    {
369
        $this->crud()->moveButton($this->name, 'before', $destination);
370
371
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Backpack\CRUD\app\Library\CrudPanel\CrudButton which is incompatible with the documented return type Backpack\CRUD\app\Library\CrudPanel\CrudFilter.
Loading history...
372
    }
373
374
    /**
375
     * Remove the button from the global button collection.
376
     *
377
     * @return void
378
     */
379
    public function remove()
380
    {
381
        $this->crud()->removeButton($this->getKey());
382
    }
383
384
    // --------------
385
    // GLOBAL OBJECTS
386
    // --------------
387
    // Access to the objects stored in Laravel's service container.
388
389
    /**
390
     * Access the global collection when all buttons are stored.
391
     *
392
     * @return \Illuminate\Support\Collection
393
     */
394
    public function collection()
395
    {
396
        return $this->crud()->buttons();
397
    }
398
399
    /**
400
     * Access the global CrudPanel object.
401
     *
402
     * @return \Backpack\CRUD\app\Library\CrudPanel\CrudPanel
403
     */
404
    public function crud()
405
    {
406
        return app('crud');
407
    }
408
409
    // -----------------
410
    // DEBUGGING METHODS
411
    // -----------------
412
413
    /**
414
     * Dump the current object to the screen,
415
     * so that the developer can see its contents.
416
     *
417
     * @codeCoverageIgnore
418
     *
419
     * @return CrudButton
420
     */
421
    public function dump()
422
    {
423
        dump($this);
424
425
        return $this;
426
    }
427
428
    /**
429
     * Dump and die. Duumps the current object to the screen,
430
     * so that the developer can see its contents, then stops
431
     * the execution.
432
     *
433
     * @codeCoverageIgnore
434
     *
435
     * @return CrudButton
436
     */
437
    public function dd()
438
    {
439
        dd($this);
440
441
        return $this;
442
    }
443
444
    // ---------------
445
    // PRIVATE METHODS
446
    // ---------------
447
448
    /**
449
     * Update the global CrudPanel object with the current button.
450
     *
451
     * @return CrudButton
452
     */
453
    private function save()
454
    {
455
        if($this->collection()->isEmpty()) {
456
            $this->crud()->addCrudButton($this);
457
            return $this;
458
        }
459
460
        $itemExists = $this->collection()->contains('name', $this->name);
461
       
462
        if (! $itemExists) { 
463
            $this->crud()->addCrudButton($this);
464
            if ($this->position == 'beginning') {
465
                $this->before($this->collection()->first()->name);
466
            } else {
467
                $this->after($this->collection()->last()->name);
468
            }    
469
470
            // clear the custom position, so that the next daisy chained method
471
            // doesn't move it yet again
472
            $this->position = null;
473
        } else {
474
           
475
            $this->crud()->modifyButton($this->name, $this->toArray());
476
        }
477
478
        return $this;
479
    }
480
481
    public function toArray() 
482
    {
483
        return (array) $this;
484
    }
485
}
486