Completed
Pull Request — master (#2624)
by
unknown
02:44
created

Field::json()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 1
nop 0
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Show;
4
5
use Encore\Admin\Show;
6
use Illuminate\Contracts\Support\Arrayable;
7
use Illuminate\Contracts\Support\Renderable;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Support\Collection;
10
use Illuminate\Support\Facades\File;
11
use Illuminate\Support\Facades\Storage;
12
use Illuminate\Support\Traits\Macroable;
13
14
class Field implements Renderable
15
{
16
    use Macroable {
17
        __call as macroCall;
18
    }
19
20
    /**
21
     * @var string
22
     */
23
    protected $view = 'admin::show.field';
24
25
    /**
26
     * Name of column.
27
     *
28
     * @var string
29
     */
30
    protected $name;
31
32
    /**
33
     * Label of column.
34
     *
35
     * @var string
36
     */
37
    protected $label;
38
39
    /**
40
     * Escape field value or not.
41
     *
42
     * @var bool
43
     */
44
    protected $escape = true;
45
46
    /**
47
     * Field value.
48
     *
49
     * @var mixed
50
     */
51
    protected $value;
52
53
    /**
54
     * @var Collection
55
     */
56
    protected $showAs = [];
57
58
    /**
59
     * Parent show instance.
60
     *
61
     * @var Show
62
     */
63
    protected $parent;
64
65
    /**
66
     * Relation name.
67
     *
68
     * @var string
69
     */
70
    protected $relation;
71
72
    /**
73
     * If show contents in box.
74
     *
75
     * @var bool
76
     */
77
    public $wrapped = true;
78
79
    /**
80
     * @var array
81
     */
82
    protected $fileTypes = [
83
        'image'      => 'png|jpg|jpeg|tmp|gif',
84
        'word'       => 'doc|docx',
85
        'excel'      => 'xls|xlsx|csv',
86
        'powerpoint' => 'ppt|pptx',
87
        'pdf'        => 'pdf',
88
        'code'       => 'php|js|java|python|ruby|go|c|cpp|sql|m|h|json|html|aspx',
89
        'archive'    => 'zip|tar\.gz|rar|rpm',
90
        'txt'        => 'txt|pac|log|md',
91
        'audio'      => 'mp3|wav|flac|3pg|aa|aac|ape|au|m4a|mpc|ogg',
92
        'video'      => 'mkv|rmvb|flv|mp4|avi|wmv|rm|asf|mpeg',
93
    ];
94
95
    /**
96
     * Field constructor.
97
     *
98
     * @param string $name
99
     * @param string $label
100
     */
101
    public function __construct($name = '', $label = '')
102
    {
103
        $this->name = $name;
104
105
        $this->label = $this->formatLabel($label);
106
107
        $this->showAs = new Collection();
108
    }
109
110
    /**
111
     * Set parent show instance.
112
     *
113
     * @param Show $show
114
     *
115
     * @return $this
116
     */
117
    public function setParent(Show $show)
118
    {
119
        $this->parent = $show;
120
121
        return $this;
122
    }
123
124
    /**
125
     * Get name of this column.
126
     *
127
     * @return mixed
128
     */
129
    public function getName()
130
    {
131
        return $this->name;
132
    }
133
134
    /**
135
     * Format label.
136
     *
137
     * @param $label
138
     *
139
     * @return mixed
140
     */
141
    protected function formatLabel($label)
142
    {
143
        $label = $label ?: ucfirst($this->name);
144
145
        return str_replace(['.', '_'], ' ', $label);
146
    }
147
148
    /**
149
     * Get label of the column.
150
     *
151
     * @return mixed
152
     */
153
    public function getLabel()
154
    {
155
        return $this->label;
156
    }
157
158
    /**
159
     * Field display callback.
160
     *
161
     * @param callable $callable
162
     *
163
     * @return $this
164
     */
165
    public function as(callable $callable)
166
    {
167
        $this->showAs->push($callable);
168
169
        return $this;
170
    }
171
172
    /**
173
     * Display field using array value map.
174
     *
175
     * @param array $values
176
     * @param null  $default
177
     *
178
     * @return $this
179
     */
180 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...
181
    {
182
        return $this->as(function ($value) use ($values, $default) {
183
            if (is_null($value)) {
184
                return $default;
185
            }
186
187
            return array_get($values, $value, $default);
188
        });
189
    }
190
191
    /**
192
     * Show field as a image.
193
     *
194
     * @param string $server
195
     * @param int    $width
196
     * @param int    $height
197
     *
198
     * @return $this
199
     */
200
    public function image($server = '', $width = 200, $height = 200)
201
    {
202
        return $this->unescape()->as(function ($path) use ($server, $width, $height) {
203
            if (empty($path)) {
204
                return '';
205
            }
206
207
            if (url()->isValidUrl($path)) {
208
                $src = $path;
209
            } elseif ($server) {
210
                $src = $server.$path;
211
            } else {
212
                $disk = config('admin.upload.disk');
213
214
                if (config("filesystems.disks.{$disk}")) {
215
                    $src = Storage::disk($disk)->url($path);
216
                } else {
217
                    return '';
218
                }
219
            }
220
221
            return "<img src='$src' style='max-width:{$width}px;max-height:{$height}px' class='img' />";
222
        });
223
    }
224
225
    /**
226
     * Show field as a file.
227
     *
228
     * @param string $server
229
     * @param bool   $download
230
     *
231
     * @return Field
232
     */
233
    public function file($server = '', $download = true)
234
    {
235
        if ( ! $this->value ) return;
236
        $field = $this;
237
238
        return $this->unescape()->as(function ($path) use ($server, $download, $field) {
239
            $name = basename($path);
240
241
            $field->wrapped = false;
242
243
            $size = $url = '';
244
245
            if (url()->isValidUrl($path)) {
246
                $url = $path;
247
            } elseif ($server) {
248
                $url = $server.$path;
249
            } else {
250
                $storage = Storage::disk(config('admin.upload.disk'));
251
                if ($storage->exists($path)) {
252
                    $url = $storage->url($path);
253
                    $size = ($storage->size($path) / 1000).'KB';
254
                }
255
            }
256
257
            return <<<HTML
258
<ul class="mailbox-attachments clearfix">
259
    <li style="margin-bottom: 0;">
260
      <span class="mailbox-attachment-icon"><i class="fa {$field->getFileIcon($name)}"></i></span>
261
      <div class="mailbox-attachment-info">
262
        <div class="mailbox-attachment-name">
263
            <i class="fa fa-paperclip"></i> {$name}
264
            </div>
265
            <span class="mailbox-attachment-size">
266
              {$size}&nbsp;
267
              <a href="{$url}" class="btn btn-default btn-xs pull-right" target="_blank"><i class="fa fa-cloud-download"></i></a>
268
            </span>
269
      </div>
270
    </li>
271
  </ul>
272
HTML;
273
        });
274
    }
275
276
    /**
277
     * Show field as a link.
278
     *
279
     * @param string $href
280
     * @param string $target
281
     *
282
     * @return Field
283
     */
284
    public function link($href = '', $target = '_blank')
285
    {
286
        return $this->unescape()->as(function ($link) use ($href, $target) {
287
            $href = $href ?: $link;
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $href, 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...
288
289
            return "<a href='$href' target='{$target}'>{$link}</a>";
290
        });
291
    }
292
293
    /**
294
     * Show field as labels.
295
     *
296
     * @param string $style
297
     *
298
     * @return Field
299
     */
300 View Code Duplication
    public function label($style = 'success')
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...
301
    {
302
        return $this->unescape()->as(function ($value) use ($style) {
303
            if ($value instanceof Arrayable) {
304
                $value = $value->toArray();
305
            }
306
307
            return collect((array) $value)->map(function ($name) use ($style) {
308
                return "<span class='label label-{$style}'>$name</span>";
309
            })->implode('&nbsp;');
310
        });
311
    }
312
313
    /**
314
     * Show field as badges.
315
     *
316
     * @param string $style
317
     *
318
     * @return Field
319
     */
320 View Code Duplication
    public function badge($style = 'blue')
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...
321
    {
322
        return $this->unescape()->as(function ($value) use ($style) {
323
            if ($value instanceof Arrayable) {
324
                $value = $value->toArray();
325
            }
326
327
            return collect((array) $value)->map(function ($name) use ($style) {
328
                return "<span class='badge bg-{$style}'>$name</span>";
329
            })->implode('&nbsp;');
330
        });
331
    }
332
333
    /**
334
     * Show field as json code.
335
     *
336
     * @return Field
337
     */
338
    public function json()
339
    {
340
        $field = $this;
341
342
        return $this->unescape()->as(function ($value) use ($field) {
343
            $content = json_decode($value, true);
344
345
            if (json_last_error() == 0) {
346
                $field->wrapped = false;
347
348
                return '<pre><code>'.json_encode($content, JSON_PRETTY_PRINT).'</code></pre>';
349
            }
350
351
            return $value;
352
        });
353
    }
354
355
    /**
356
     * Get file icon.
357
     *
358
     * @param string $file
359
     *
360
     * @return string
361
     */
362
    public function getFileIcon($file = '')
363
    {
364
        $extension = File::extension($file);
365
366
        foreach ($this->fileTypes as $type => $regex) {
367
            if (preg_match("/^($regex)$/i", $extension) !== 0) {
368
                return "fa-file-{$type}-o";
369
            }
370
        }
371
372
        return 'fa-file-o';
373
    }
374
375
    /**
376
     * Set escape or not for this field.
377
     *
378
     * @param bool $escape
379
     *
380
     * @return $this
381
     */
382
    public function setEscape($escape = true)
383
    {
384
        $this->escape = $escape;
385
386
        return $this;
387
    }
388
389
    /**
390
     * Unescape for this field.
391
     *
392
     * @return Field
393
     */
394
    public function unescape()
395
    {
396
        return $this->setEscape(false);
397
    }
398
399
    /**
400
     * Set value for this field.
401
     *
402
     * @param Model $model
403
     *
404
     * @return $this
405
     */
406
    public function setValue(Model $model)
407
    {
408
        if ($this->relation) {
409
            if (!$model->{$this->relation}) {
410
                return $this;
411
            }
412
413
            $this->value = $model->{$this->relation}->getAttribute($this->name);
414
        } else {
415
            $this->value = $model->getAttribute($this->name);
416
        }
417
418
        return $this;
419
    }
420
421
    /**
422
     * Set relation name for this field.
423
     *
424
     * @param string $relation
425
     *
426
     * @return $this
427
     */
428
    public function setRelation($relation)
429
    {
430
        $this->relation = $relation;
431
432
        return $this;
433
    }
434
435
    /**
436
     * @param string $method
437
     * @param array  $arguments
438
     *
439
     * @return $this
440
     */
441
    public function __call($method, $arguments = [])
442
    {
443
        if (static::hasMacro($method)) {
444
            return $this->macroCall($method, $arguments);
445
        }
446
447
        if ($this->relation) {
448
            $this->name = $method;
449
            $this->label = $this->formatLabel(array_get($arguments, 0));
450
        }
451
452
        return $this;
453
    }
454
455
    /**
456
     * Get all variables passed to field view.
457
     *
458
     * @return array
459
     */
460
    protected function variables()
461
    {
462
        return [
463
            'content'   => $this->value,
464
            'escape'    => $this->escape,
465
            'label'     => $this->getLabel(),
466
            'wrapped'   => $this->wrapped,
467
        ];
468
    }
469
470
    /**
471
     * Render this field.
472
     *
473
     * @return string
474
     */
475
    public function render()
476
    {
477
        if ($this->showAs->isNotEmpty()) {
478
            $this->showAs->each(function ($callable) {
479
                $this->value = $callable->call(
480
                    $this->parent->getModel(),
481
                    $this->value
482
                );
483
            });
484
        }
485
486
        return view($this->view, $this->variables());
0 ignored issues
show
Bug Compatibility introduced by
The expression view($this->view, $this->variables()); of type Illuminate\View\View|Ill...\Contracts\View\Factory adds the type Illuminate\Contracts\View\Factory to the return on line 486 which is incompatible with the return type declared by the interface Illuminate\Contracts\Support\Renderable::render of type string.
Loading history...
487
    }
488
}
489