Completed
Push — master ( 3807c7...51c976 )
by Song
12s
created

Field::getFileIcon()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 12
rs 9.8666
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->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
        $field = $this;
236
237
        return $this->as(function ($path) use ($server, $download, $field) {
238
            $name = basename($path);
239
240
            $field->wrapped = false;
241
242
            $size = $url = '';
243
244
            if (url()->isValidUrl($path)) {
245
                $url = $path;
246
            } elseif ($server) {
247
                $url = $server.$path;
248
            } else {
249
                $storage = Storage::disk(config('admin.upload.disk'));
250
                if ($storage->exists($path)) {
251
                    $url = $storage->url($path);
252
                    $size = ($storage->size($path) / 1000).'KB';
253
                }
254
            }
255
256
            return <<<HTML
257
<ul class="mailbox-attachments clearfix">
258
    <li style="margin-bottom: 0;">
259
      <span class="mailbox-attachment-icon"><i class="fa {$field->getFileIcon($name)}"></i></span>
260
      <div class="mailbox-attachment-info">
261
        <div class="mailbox-attachment-name">
262
            <i class="fa fa-paperclip"></i> {$name}
263
            </div>
264
            <span class="mailbox-attachment-size">
265
              {$size}&nbsp;
266
              <a href="{$url}" class="btn btn-default btn-xs pull-right" target="_blank"><i class="fa fa-cloud-download"></i></a>
267
            </span>
268
      </div>
269
    </li>
270
  </ul>
271
HTML;
272
        });
273
    }
274
275
    /**
276
     * Show field as a link.
277
     *
278
     * @param string $href
279
     * @param string $target
280
     *
281
     * @return Field
282
     */
283
    public function link($href = '', $target = '_blank')
284
    {
285
        return $this->as(function ($link) use ($href, $target) {
286
            $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...
287
288
            return "<a href='$href' target='{$target}'>{$link}</a>";
289
        });
290
    }
291
292
    /**
293
     * Show field as labels.
294
     *
295
     * @param string $style
296
     *
297
     * @return Field
298
     */
299 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...
300
    {
301
        return $this->as(function ($value) use ($style) {
302
            if ($value instanceof Arrayable) {
303
                $value = $value->toArray();
304
            }
305
306
            return collect((array) $value)->map(function ($name) use ($style) {
307
                return "<span class='label label-{$style}'>$name</span>";
308
            })->implode('&nbsp;');
309
        });
310
    }
311
312
    /**
313
     * Show field as badges.
314
     *
315
     * @param string $style
316
     *
317
     * @return Field
318
     */
319 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...
320
    {
321
        return $this->as(function ($value) use ($style) {
322
            if ($value instanceof Arrayable) {
323
                $value = $value->toArray();
324
            }
325
326
            return collect((array) $value)->map(function ($name) use ($style) {
327
                return "<span class='badge bg-{$style}'>$name</span>";
328
            })->implode('&nbsp;');
329
        });
330
    }
331
332
    /**
333
     * Show field as json code.
334
     *
335
     * @return Field
336
     */
337
    public function json()
338
    {
339
        $field = $this;
340
341
        return $this->as(function ($value) use ($field) {
342
            $content = json_decode($value, true);
343
344
            if (json_last_error() == 0) {
345
                $field->wrapped = false;
346
347
                return '<pre><code>'.json_encode($content, JSON_PRETTY_PRINT).'</code></pre>';
348
            }
349
350
            return $value;
351
        });
352
    }
353
354
    /**
355
     * Get file icon.
356
     *
357
     * @param string $file
358
     *
359
     * @return string
360
     */
361
    public function getFileIcon($file = '')
362
    {
363
        $extension = File::extension($file);
364
365
        foreach ($this->fileTypes as $type => $regex) {
366
            if (preg_match("/^($regex)$/i", $extension) !== 0) {
367
                return "fa-file-{$type}-o";
368
            }
369
        }
370
371
        return 'fa-file-o';
372
    }
373
374
    /**
375
     * Set escape or not for this field.
376
     *
377
     * @param bool $escape
378
     *
379
     * @return $this
380
     */
381
    public function setEscape($escape)
382
    {
383
        $this->escape = $escape;
384
385
        return $this;
386
    }
387
388
    /**
389
     * Set value for this field.
390
     *
391
     * @param Model $model
392
     *
393
     * @return $this
394
     */
395
    public function setValue(Model $model)
396
    {
397
        if ($this->relation) {
398
            if (!$model->{$this->relation}) {
399
                return $this;
400
            }
401
402
            $this->value = $model->{$this->relation}->getAttribute($this->name);
403
        } else {
404
            $this->value = $model->getAttribute($this->name);
405
        }
406
407
        return $this;
408
    }
409
410
    /**
411
     * Set relation name for this field.
412
     *
413
     * @param string $relation
414
     *
415
     * @return $this
416
     */
417
    public function setRelation($relation)
418
    {
419
        $this->relation = $relation;
420
421
        return $this;
422
    }
423
424
    /**
425
     * @param string $method
426
     * @param array  $arguments
427
     *
428
     * @return $this
429
     */
430
    public function __call($method, $arguments = [])
431
    {
432
        if (static::hasMacro($method)) {
433
            return $this->macroCall($method, $arguments);
434
        }
435
436
        if ($this->relation) {
437
            $this->name = $method;
438
            $this->label = $this->formatLabel(array_get($arguments, 0));
439
        }
440
441
        return $this;
442
    }
443
444
    /**
445
     * Get all variables passed to field view.
446
     *
447
     * @return array
448
     */
449
    protected function variables()
450
    {
451
        return [
452
            'content'   => $this->value,
453
            'escape'    => $this->escape,
454
            'label'     => $this->getLabel(),
455
            'wrapped'   => $this->wrapped,
456
        ];
457
    }
458
459
    /**
460
     * Render this field.
461
     *
462
     * @return string
463
     */
464
    public function render()
465
    {
466
        if ($this->showAs->isNotEmpty()) {
467
            $this->showAs->each(function ($callable) {
468
                $this->value = $callable->call(
469
                    $this->parent->getModel(),
470
                    $this->value
471
                );
472
            });
473
        }
474
475
        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 475 which is incompatible with the return type declared by the interface Illuminate\Contracts\Support\Renderable::render of type string.
Loading history...
476
    }
477
}
478