Completed
Push — master ( 2c7de6...6483d0 )
by Song
10s
created

Field::file()   B

Complexity

Conditions 5
Paths 1

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

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