Completed
Push — master ( 88ab05...dae06d )
by Song
02:49
created

ExtendDisplay::extend()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Grid\Column;
4
5
use Carbon\Carbon;
6
use Encore\Admin\Grid\Column;
7
use Encore\Admin\Grid\Displayers;
8
use Encore\Admin\Grid\Model;
9
use Illuminate\Support\Arr;
10
11
/**
12
 * Trait ExtendDisplay
13
 *
14
 * @method $this editable()
15
 * @method $this image($server = '', $width = 200, $height = 200)
16
 * @method $this label($style = 'success')
17
 * @method $this button($style = null)
18
 * @method $this link($href = '', $target = '_blank')
19
 * @method $this badge($style = 'red')
20
 * @method $this progress($style = 'primary', $size = 'sm', $max = 100)
21
 * @method $this orderable($column, $label = '')
22
 * @method $this table($titles = [])`
23
 * @method $this expand($callback = null)
24
 * @method $this modal($title, $callback = null)
25
 * @method $this carousel(int $width = 300, int $height = 200, $server = '')
26
 * @method $this downloadable($server = '')
27
 * @method $this copyable()
28
 * @method $this qrcode($formatter = null, $width = 150, $height = 150)
29
 * @method $this prefix($prefix, $delimiter = '&nbsp;')
30
 * @method $this suffix($suffix, $delimiter = '&nbsp;')
31
 * @method $this secret($dotCount = 6)
32
 * @method $this limit($limit = 100, $end = '...')
33
 */
34
trait ExtendDisplay
35
{
36
    /**
37
     * Displayers for grid column.
38
     *
39
     * @var array
40
     */
41
    public static $displayers = [
42
        'editable'      => Displayers\Editable::class,
43
        'image'         => Displayers\Image::class,
44
        'label'         => Displayers\Label::class,
45
        'button'        => Displayers\Button::class,
46
        'link'          => Displayers\Link::class,
47
        'badge'         => Displayers\Badge::class,
48
        'progressBar'   => Displayers\ProgressBar::class,
49
        'progress'      => Displayers\ProgressBar::class,
50
        'orderable'     => Displayers\Orderable::class,
51
        'table'         => Displayers\Table::class,
52
        'expand'        => Displayers\Expand::class,
53
        'modal'         => Displayers\Modal::class,
54
        'carousel'      => Displayers\Carousel::class,
55
        'downloadable'  => Displayers\Downloadable::class,
56
        'copyable'      => Displayers\Copyable::class,
57
        'qrcode'        => Displayers\QRCode::class,
58
        'prefix'        => Displayers\Prefix::class,
59
        'suffix'        => Displayers\Suffix::class,
60
        'secret'        => Displayers\Secret::class,
61
        'limit'         => Displayers\Limit::class,
62
    ];
63
64
    /**
65
     * @var bool
66
     */
67
    protected $searchable = false;
68
69
    /**
70
     * Extend column displayer.
71
     *
72
     * @param $name
73
     * @param $displayer
74
     */
75
    public static function extend($name, $displayer)
76
    {
77
        static::$displayers[$name] = $displayer;
78
    }
79
80
    /**
81
     * Set column as searchable.
82
     *
83
     * @return $this
84
     */
85
    public function searchable()
86
    {
87
        $this->searchable = true;
88
89
        $name = $this->getName();
0 ignored issues
show
Bug introduced by
It seems like getName() 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...
90
        $query = request()->query();
91
92
        $this->prefix(function ($_, $original) use ($name, $query) {
93
            Arr::set($query, $name, $original);
94
95
            $url = request()->fullUrlWithQuery($query);
96
97
            return "<a href=\"{$url}\"><i class=\"fa fa-search\"></i></a>";
98
        }, '&nbsp;&nbsp;');
99
100
        return $this;
101
    }
102
103
    /**
104
     * Bind search query to grid model.
105
     *
106
     * @param Model $model
107
     */
108
    public function bindSearchQuery(Model $model)
109
    {
110
        if ($this->searchable && ($value = request($this->getName())) != '') {
0 ignored issues
show
Bug introduced by
It seems like getName() 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...
111
            $model->where($this->getName(), $value);
0 ignored issues
show
Bug introduced by
It seems like getName() 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...
Documentation Bug introduced by
The method where does not exist on object<Encore\Admin\Grid\Model>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
112
        }
113
    }
114
115
    /**
116
     * Display column using array value map.
117
     *
118
     * @param array $values
119
     * @param null  $default
120
     *
121
     * @return $this
122
     */
123 View Code Duplication
    public function using(array $values, $default = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
124
    {
125
        return $this->display(function ($value) use ($values, $default) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
126
            if (is_null($value)) {
127
                return $default;
128
            }
129
130
            return Arr::get($values, $value, $default);
131
        });
132
    }
133
134
    /**
135
     * Replace output value with giving map.
136
     *
137
     * @param array $replacements
138
     *
139
     * @return $this
140
     */
141
    public function replace(array $replacements)
142
    {
143
        return $this->display(function ($value) use ($replacements) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
144
            if (isset($replacements[$value])) {
145
                return $replacements[$value];
146
            }
147
148
            return $value;
149
        });
150
    }
151
152
    /**
153
     * @param string|Closure $input
154
     * @param string $seperator
155
     *
156
     * @return $this
157
     */
158
    public function repeat($input, $seperator = '')
159
    {
160
        if (is_string($input)) {
161
            $input = function () use ($input) {
162
                return $input;
163
            };
164
        }
165
166
        if ($input instanceof Closure) {
0 ignored issues
show
Bug introduced by
The class Encore\Admin\Grid\Column\Closure does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
167
            return $this->display(function ($value) use ($input, $seperator) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
168
                return join($seperator, array_fill(0, (int) $value, $input->call($this, [$value])));
169
            });
170
        }
171
172
        return $this;
173
    }
174
175
    /**
176
     * Render this column with the given view.
177
     *
178
     * @param string $view
179
     *
180
     * @return $this
181
     */
182
    public function view($view)
183
    {
184
        return $this->display(function ($value) use ($view) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
185
            $model = $this;
186
187
            return view($view, compact('model', 'value'))->render();
0 ignored issues
show
Bug introduced by
The method render does only exist in Illuminate\View\View, but not in Illuminate\Contracts\View\Factory.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
188
        });
189
    }
190
191
    /**
192
     * Convert file size to a human readable format like `100mb`.
193
     *
194
     * @return $this
195
     */
196
    public function filesize()
197
    {
198
        return $this->display(function ($value) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
199
            return file_size($value);
200
        });
201
    }
202
203
    /**
204
     * Display the fields in the email format as gavatar.
205
     *
206
     * @param int $size
207
     *
208
     * @return $this
209
     */
210
    public function gravatar($size = 30)
211
    {
212
        return $this->display(function ($value) use ($size) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
213
            $src = sprintf(
214
                'https://www.gravatar.com/avatar/%s?s=%d',
215
                md5(strtolower($value)),
216
                $size
217
            );
218
219
            return "<img src='$src' class='img img-circle'/>";
220
        });
221
    }
222
223
    /**
224
     * Display field as a loading icon.
225
     *
226
     * @param array $values
227
     * @param array $others
228
     *
229
     * @return $this
230
     */
231
    public function loading($values = [], $others = [])
232
    {
233
        return $this->display(function ($value) use ($values, $others) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
234
            $values = (array) $values;
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $values, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
235
236
            if (in_array($value, $values)) {
237
                return '<i class="fa fa-refresh fa-spin text-primary"></i>';
238
            }
239
240
            return Arr::get($others, $value, $value);
241
        });
242
    }
243
244
    /**
245
     * Display column as an font-awesome icon based on it's value.
246
     *
247
     * @param array  $setting
248
     * @param string $default
249
     *
250
     * @return $this
251
     */
252
    public function icon(array $setting, $default = '')
253
    {
254
        return $this->display(function ($value) use ($setting, $default) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
255
            $fa = '';
256
257
            if (isset($setting[$value])) {
258
                $fa = $setting[$value];
259
            } elseif ($default) {
260
                $fa = $default;
261
            }
262
263
            return "<i class=\"fa fa-{$fa}\"></i>";
264
        });
265
    }
266
267
    /**
268
     * Return a human readable format time.
269
     *
270
     * @param null $locale
271
     *
272
     * @return $this
273
     */
274
    public function diffForHumans($locale = null)
275
    {
276
        if ($locale) {
277
            Carbon::setLocale($locale);
278
        }
279
280
        return $this->display(function ($value) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
281
            return Carbon::parse($value)->diffForHumans();
282
        });
283
    }
284
285
    /**
286
     * Display column as boolean , `✓` for true, and `✗` for false.
287
     *
288
     * @param array $map
289
     * @param bool  $default
290
     *
291
     * @return $this
292
     */
293
    public function bool(array $map = [], $default = false)
294
    {
295
        return $this->display(function ($value) use ($map, $default) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
296
            $bool = empty($map) ? boolval($value) : Arr::get($map, $value, $default);
297
298
            return $bool ? '<i class="fa fa-check text-green"></i>' : '<i class="fa fa-close text-red"></i>';
299
        });
300
    }
301
302
    /**
303
     * Display column as a default value if empty.
304
     *
305
     * @param string $default
306
     * @return $this
307
     */
308
    public function default($default = '-')
309
    {
310
        return $this->display(function ($value) use ($default) {
0 ignored issues
show
Bug introduced by
It seems like display() 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...
311
            return $value ?: $default;
312
        });
313
    }
314
315
    /**
316
     * Add a `dot` before column text.
317
     *
318
     * @param array  $options
319
     * @param string $default
320
     *
321
     * @return $this
322
     */
323
    public function dot($options = [], $default = '')
324
    {
325
        return $this->prefix(function ($_, $original) use ($options, $default) {
326
            if (is_null($original)) {
327
                $style = $default;
328
            } else {
329
                $style = Arr::get($options, $original, $default);
330
            }
331
332
            return "<span class=\"label-{$style}\" style='width: 8px;height: 8px;padding: 0;border-radius: 50%;display: inline-block;'></span>";
333
        }, '&nbsp;&nbsp;');
334
    }
335
}
336