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 — v4dot1 ( bece96 )
by Cristian
10:39 queued 08:03
created

SaveActions::getFallBackSaveAction()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Library\CrudPanel\Traits;
4
5
use Illuminate\Support\Arr;
6
7
trait SaveActions
8
{
9
    /**
10
     * Get the developer's preference on what save action is the default one
11
     * for the current operation.
12
     *
13
     * @return string
14
     */
15
    public function getSaveActionDefaultForCurrentOperation()
16
    {
17
        return config('backpack.crud.operations.'.$this->getCurrentOperation().'.defaultSaveAction', 'save_and_back');
0 ignored issues
show
Bug introduced by
It seems like getCurrentOperation() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
18
    }
19
20
    /**
21
     * Get the save action with full fallback until default.
22
     *
23
     * @return string
24
     */
25
    public function getFallBackSaveAction()
26
    {
27
        //we get the higher order in save actions array. It will return something only when explicit by developer
28
        $higherAction = $this->getSaveActionByOrder(1);
29
30
        if (empty($higherAction)) {
31
            if ($this->hasOperationSetting('defaultSaveAction')) {
32
                return $this->getOperationSetting('defaultSaveAction');
33
            }
34
35
            return $this->getSaveActionDefaultForCurrentOperation();
36
        }
37
38
        return key($higherAction);
39
    }
40
41
    /**
42
     * Gets the save action that has the desired order.
43
     *
44
     * @param int $order
45
     * @return array
46
     */
47
    public function getSaveActionByOrder($order)
48
    {
49
        return array_filter($this->getOperationSetting('save_actions'), function ($arr) use ($order) {
50
            return $arr['order'] == $order;
51
        });
52
    }
53
54
    /**
55
     * Allow the developer to register multiple save actions.
56
     *
57
     * @param array $saveActions
58
     * @return void
59
     */
60
    public function addSaveActions($saveActions)
61
    {
62
        // count vs count recursive will be diferent when counting single dimension vs multiple dimension arrays.
63
        // count([1,2]) = 2, count([1,[2,3]]) = 2 with recursive it's 3. so if counts are different we have a
64
        // multi dimensional array
65
        if (count($saveActions) != count($saveActions, COUNT_RECURSIVE)) {
66
            foreach ($saveActions as $saveAction) {
67
                $this->addSaveAction($saveAction);
68
            }
69
        }
70
    }
71
72
    /**
73
     * Allow developers to register save action into CRUD.
74
     *
75
     * @param array $saveAction
76
     * @return void
77
     */
78
    public function addSaveAction(array $saveAction)
79
    {
80
        $orderCounter = $this->getOperationSetting('save_actions') !== null ? (count($this->getOperationSetting('save_actions')) + 1) : 1;
81
        //check for some mandatory fields
82
        $saveAction['name'] ?? abort(500, 'Please define save action name.');
83
        $saveAction['redirect'] = $saveAction['redirect'] ?? function ($crud, $request, $itemId) {
84
            return $request->has('http_referrer') ? $request->get('http_referrer') : $crud->route;
85
        };
86
        $saveAction['visible'] = $saveAction['visible'] ?? true;
87
        $saveAction['button_text'] = $saveAction['button_text'] ?? $saveAction['name'];
88
        $saveAction['order'] = isset($saveAction['order']) ? $this->orderSaveAction($saveAction['name'], $saveAction['order']) : $orderCounter;
89
90
        $actions = $this->getOperationSetting('save_actions') ?? [];
91
92
        if (! in_array($saveAction['name'], $actions)) {
93
            $actions[$saveAction['name']] = $saveAction;
94
        }
95
96
        $this->setOperationSetting('save_actions', $actions);
97
    }
98
99
    /**
100
     * Replaces setting order or forces some default.
101
     *
102
     * @param string $saveAction
103
     * @param int $wantedOrder
104
     * @return int
105
     */
106
    public function orderSaveAction(string $saveAction, int $wantedOrder)
107
    {
108
        $actions = $this->getOperationSetting('save_actions') ?? [];
109
        if (! empty($actions)) {
110
            $replaceOrder = isset($actions[$saveAction]) ? $actions[$saveAction]['order'] : count($actions) + 1;
111
112
            foreach ($actions as $key => $sv) {
113
                if ($wantedOrder == $sv['order']) {
114
                    $actions[$key]['order'] = $replaceOrder;
115
                }
116
                if ($key == $saveAction) {
117
                    $actions[$key]['order'] = $wantedOrder;
118
                }
119
            }
120
            $this->setOperationSetting('save_actions', $actions);
121
        }
122
123
        return $wantedOrder;
124
    }
125
126
    /**
127
     * Replace the current save actions with the ones provided.
128
     *
129
     * @param array $saveActions
130
     * @return void
131
     */
132
    public function replaceSaveActions($saveActions)
133
    {
134
        //we reset all save actions
135
        $this->setOperationSetting('save_actions', []);
0 ignored issues
show
Bug introduced by
It seems like setOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
136
137
        if (count($saveActions) != count($saveActions, COUNT_RECURSIVE)) {
138
            $this->addSaveActions($saveActions);
139
        } else {
140
            $this->addSaveAction($saveActions);
141
        }
142
    }
143
144
    /**
145
     * Alias function of replaceSaveActions() for CRUD consistency.
146
     *
147
     * @param array $saveActions
148
     * @return void
149
     */
150
    public function setSaveActions($saveActions)
151
    {
152
        return $this->replaceSaveActions($saveActions);
153
    }
154
155
    /**
156
     * Allow the developer to remove multiple save actions from settings.
157
     *
158
     * @param array $saveActions
159
     * @return void
160
     */
161
    public function removeSaveActions(array $saveActions)
162
    {
163
        foreach ($saveActions as $sv) {
164
            $this->removeSaveAction($sv);
165
        }
166
    }
167
168
    /**
169
     * Allow the developer to remove a save action from settings.
170
     *
171
     * @param string $saveAction
172
     * @return void
173
     */
174
    public function removeSaveAction(string $saveAction)
175
    {
176
        $actions = $this->getOperationSetting('save_actions') ?? [];
0 ignored issues
show
Bug introduced by
It seems like getOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
177
        if (isset($actions[$saveAction])) {
178
            $actions[$saveAction] = null;
179
        }
180
        $this->setOperationSetting('save_actions', array_filter($actions));
0 ignored issues
show
Bug introduced by
It seems like setOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
181
    }
182
183
    /**
184
     * Allow the developer to unset all save actions.
185
     *
186
     * @param string $saveAction
0 ignored issues
show
Bug introduced by
There is no parameter named $saveAction. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
187
     * @return void
188
     */
189
    public function removeAllSaveActions()
190
    {
191
        $this->setOperationSettings('save_actions', []);
0 ignored issues
show
Bug introduced by
It seems like setOperationSettings() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
192
    }
193
194
    /**
195
     * Allows the developer to set save actions order. It could be ['action1','action2'] or ['action1' => 1, 'action2' => 2].
196
     *
197
     * @param array $saveActions
198
     * @return void
199
     */
200
    public function orderSaveActions(array $saveActions)
201
    {
202
        foreach ($saveActions as $sv => $order) {
203
            if (! is_int($order)) {
204
                $this->orderSaveAction($order, $sv + 1);
205
            } else {
206
                $this->orderSaveAction($sv, $order);
207
            }
208
        }
209
    }
210
211
    /**
212
     * Return the ordered save actions to use in the crud panel.
213
     *
214
     * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
215
     */
216
    public function getOrderedSaveActions()
217
    {
218
        $actions = $this->getOperationSetting('save_actions') ?? [];
0 ignored issues
show
Bug introduced by
It seems like getOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
219
220
        uasort($actions, function ($a, $b) {
221
            return $a['order'] <=> $b['order'];
222
        });
223
224
        return $actions;
225
    }
226
227
    /**
228
     * Returns the save actions that passed the visible callback.
229
     *
230
     * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
231
     */
232
    public function getVisibleSaveActions()
233
    {
234
        $actions = $this->getOrderedSaveActions();
235
        foreach ($actions as $actionName => $action) {
236
            $visible = $action['visible'];
237
            if (is_callable($visible)) {
238
                $actions[$actionName]['visible'] = $visible($this);
239
            }
240
        }
241
242
        return array_filter($actions, function ($action) {
243
            return $action['visible'] == true;
244
        }, ARRAY_FILTER_USE_BOTH);
245
    }
246
247
    /**
248
     * Gets the current save action for this crud.
249
     *
250
     * @param array $saveOptions
251
     * @return array
252
     */
253
    public function getCurrentSaveAction($saveOptions)
254
    {
255
256
        //get save action from session if exists, or get the developer defined order
257
        $saveAction = session($this->getCurrentOperation().'.saveAction', $this->getFallBackSaveAction());
0 ignored issues
show
Bug introduced by
It seems like getCurrentOperation() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
258
        if (isset($saveOptions[$saveAction])) {
259
            $currentAction = $saveOptions[$saveAction];
260
        } else {
261
            $currentAction = Arr::first($saveOptions);
0 ignored issues
show
Documentation introduced by
$saveOptions is of type array, but the function expects a object<Illuminate\Support\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
262
        }
263
264
        return [
265
            'value' => $currentAction['name'],
266
            'label' => $currentAction['button_text'],
267
        ];
268
    }
269
270
    /**
271
     * Here we check for save action visibility and prepare the actions array for display.
272
     *
273
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
274
     */
275
    public function getSaveAction()
276
    {
277
        //get only the save actions that pass visibility callback
278
        $saveOptions = $this->getVisibleSaveActions();
279
280
        //get the current action
281
        $saveCurrent = $this->getCurrentSaveAction($saveOptions);
282
283
        //get the dropdown options
284
        $dropdownOptions = [];
285
        foreach ($saveOptions as $key => $option) {
286
            if ($option['name'] != $saveCurrent['value']) {
287
                $dropdownOptions[$option['name']] = $option['button_text'];
288
            }
289
        }
290
291
        return [
292
            'active'  => $saveCurrent,
293
            'options' => $dropdownOptions,
294
        ];
295
    }
296
297
    /**
298
     * Change the session variable that remembers what to do after the "Save" action.
299
     *
300
     * @param string|null $forceSaveAction
301
     *
302
     * @return void
303
     */
304
    public function setSaveAction($forceSaveAction = null)
305
    {
306
        $saveAction = $forceSaveAction ?:
307
            \Request::input('save_action', $this->getFallBackSaveAction());
308
309
        $showBubble = $this->getOperationSetting('showSaveActionChange') ?? config('backpack.crud.operations.'.$this->getCurrentOperation().'.showSaveActionChange') ?? true;
0 ignored issues
show
Bug introduced by
It seems like getOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
Bug introduced by
It seems like getCurrentOperation() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
310
311
        if (
312
            $showBubble &&
313
            session($this->getCurrentOperation().'.saveAction', 'save_and_back') !== $saveAction
0 ignored issues
show
Bug introduced by
It seems like getCurrentOperation() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
314
        ) {
315
            \Alert::info(trans('backpack::crud.save_action_changed_notification'))->flash();
316
        }
317
318
        session([$this->getCurrentOperation().'.saveAction' => $saveAction]);
0 ignored issues
show
Bug introduced by
It seems like getCurrentOperation() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
319
    }
320
321
    /**
322
     * Redirect to the correct URL, depending on which save action has been selected.
323
     *
324
     * @param string $itemId
0 ignored issues
show
Documentation introduced by
Should the type for parameter $itemId not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
325
     *
326
     * @return \Illuminate\Http\Response
0 ignored issues
show
Documentation introduced by
Should the return type not be array|\Illuminate\Http\RedirectResponse?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
327
     */
328
    public function performSaveAction($itemId = null)
329
    {
330
        $request = \Request::instance();
331
        $saveAction = $request->input('save_action', $this->getFallBackSaveAction());
332
        $itemId = $itemId ?: $request->input('id');
333
        $actions = $this->getOperationSetting('save_actions');
0 ignored issues
show
Bug introduced by
It seems like getOperationSetting() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
334
335
        if (isset($actions[$saveAction])) {
336 View Code Duplication
            if (is_callable($actions[$saveAction]['redirect'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
337
                $redirectUrl = $actions[$saveAction]['redirect']($this, $request, $itemId);
338
            }
339
340
            //allow the save action to define default http_referrer (url for the save_and_back button)
341
            if (isset($actions[$saveAction]['referrer_url'])) {
342 View Code Duplication
                if (is_callable($actions[$saveAction]['referrer_url'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
343
                    $referrer_url = $actions[$saveAction]['referrer_url']($this, $request, $itemId);
344
                }
345
            }
346
        }
347
348
        // if the request is AJAX, return a JSON response
349
        if ($this->request->ajax()) {
0 ignored issues
show
Bug introduced by
The property request does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
350
            return [
351
                'success'      => true,
352
                'data'         => $this->entry,
0 ignored issues
show
Bug introduced by
The property entry does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
353
                'redirect_url' => $redirectUrl,
0 ignored issues
show
Bug introduced by
The variable $redirectUrl does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
354
                'referrer_url' => $referrer_url,
0 ignored issues
show
Bug introduced by
The variable $referrer_url does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
355
            ];
356
        }
357
358
        if (isset($referrer_url)) {
359
            session()->flash('referrer_url_override', $referrer_url);
360
        }
361
362
        return \Redirect::to($redirectUrl);
363
    }
364
365
    /**
366
     * This functions register Backpack default save actions into CRUD.
367
     *
368
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
369
     */
370
    public function setupDefaultSaveActions()
371
    {
372
        $defaultSaveActions = [
373
            [
374
                'name' => 'save_and_back',
375
                'visible' => function ($crud) {
376
                    return $crud->hasAccess('list');
377
                },
378
                'redirect' => function ($crud, $request, $itemId = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $itemId is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
379
                    return $request->has('http_referrer') ? $request->get('http_referrer') : $crud->route;
380
                },
381
                'button_text' => trans('backpack::crud.save_action_save_and_back'),
382
            ],
383
            [
384
                'name' => 'save_and_edit',
385
                'visible' => function ($crud) {
386
                    return $crud->hasAccess('update');
387
                },
388
                'redirect' => function ($crud, $request, $itemId = null) {
389
                    $itemId = $itemId ?: $request->input('id');
390
                    $redirectUrl = $crud->route.'/'.$itemId.'/edit';
391
                    if ($request->has('locale')) {
392
                        $redirectUrl .= '?locale='.$request->input('locale');
393
                    }
394
                    if ($request->has('current_tab')) {
395
                        $redirectUrl = $redirectUrl.'#'.$request->get('current_tab');
396
                    }
397
398
                    return $redirectUrl;
399
                },
400
                'referrer_url' => function ($crud, $request, $itemId) {
401
                    return url($crud->route.'/'.$itemId.'/edit');
402
                },
403
                'button_text' => trans('backpack::crud.save_action_save_and_edit'),
404
            ],
405
            [
406
                'name' => 'save_and_new',
407
                'visible' => function ($crud) {
408
                    return $crud->hasAccess('create');
409
                },
410
                'redirect' => function ($crud, $request, $itemId = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $crud is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $itemId is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
411
                    return $this->route.'/create';
0 ignored issues
show
Bug introduced by
The property route does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
412
                },
413
                'button_text' => trans('backpack::crud.save_action_save_and_new'),
414
            ],
415
        ];
416
417
        $this->addSaveActions($defaultSaveActions);
418
    }
419
}
420