Completed
Push — master ( 0ba9c9...c4f173 )
by jxlwqq
15s queued 11s
created

src/Form/Field/ImageField.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Encore\Admin\Form\Field;
4
5
use Illuminate\Support\Str;
6
use Intervention\Image\Constraint;
7
use Intervention\Image\Facades\Image as InterventionImage;
8
use Intervention\Image\ImageManagerStatic;
9
use Symfony\Component\HttpFoundation\File\UploadedFile;
10
11
trait ImageField
12
{
13
    /**
14
     * Intervention calls.
15
     *
16
     * @var array
17
     */
18
    protected $interventionCalls = [];
19
20
    /**
21
     * Thumbnail settings.
22
     *
23
     * @var array
24
     */
25
    protected $thumbnails = [];
26
27
    /**
28
     * Default directory for file to upload.
29
     *
30
     * @return mixed
31
     */
32
    public function defaultDirectory()
33
    {
34
        return config('admin.upload.directory.image');
35
    }
36
37
    /**
38
     * Execute Intervention calls.
39
     *
40
     * @param string $target
41
     *
42
     * @return mixed
43
     */
44
    public function callInterventionMethods($target)
45
    {
46
        if (!empty($this->interventionCalls)) {
47
            $image = ImageManagerStatic::make($target);
48
49
            foreach ($this->interventionCalls as $call) {
50
                call_user_func_array(
51
                    [$image, $call['method']],
52
                    $call['arguments']
53
                )->save($target);
54
            }
55
        }
56
57
        return $target;
58
    }
59
60
    /**
61
     * Call intervention methods.
62
     *
63
     * @param string $method
64
     * @param array  $arguments
65
     *
66
     * @throws \Exception
67
     *
68
     * @return $this
69
     */
70
    public function __call($method, $arguments)
71
    {
72
        if (static::hasMacro($method)) {
73
            return $this;
74
        }
75
76
        if (!class_exists(ImageManagerStatic::class)) {
77
            throw new \Exception('To use image handling and manipulation, please install [intervention/image] first.');
78
        }
79
80
        $this->interventionCalls[] = [
81
            'method'    => $method,
82
            'arguments' => $arguments,
83
        ];
84
85
        return $this;
86
    }
87
88
    /**
89
     * Render a image form field.
90
     *
91
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
92
     */
93
    public function render()
94
    {
95
        $this->options(['allowedFileTypes' => ['image'], 'msgPlaceholder' => trans('admin.choose_image')]);
96
97
        return parent::render();
98
    }
99
100
    /**
101
     * @param string|array $name
102
     * @param int          $width
103
     * @param int          $height
104
     *
105
     * @return $this
106
     */
107
    public function thumbnail($name, int $width = null, int $height = null)
108
    {
109
        if (func_num_args() == 1 && is_array($name)) {
110
            foreach ($name as $key => $size) {
111
                if (count($size) >= 2) {
112
                    $this->thumbnails[$key] = $size;
113
                }
114
            }
115
        } elseif (func_num_args() == 3) {
116
            $this->thumbnails[$name] = [$width, $height];
117
        }
118
119
        return $this;
120
    }
121
122
    /**
123
     * Destroy original thumbnail files.
124
     *
125
     * @return void.
126
     */
127
    public function destroyThumbnail()
128
    {
129
        if ($this->retainable) {
130
            return;
131
        }
132
133
        foreach ($this->thumbnails as $name => $_) {
134
            /*  Refactoring actual remove lofic to another method destroyThumbnailFile()
135
            to make deleting thumbnails work with multiple as well as
136
            single image upload. */
137
138
            if (is_array($this->original)) {
139
                if (empty($this->original)) {
0 ignored issues
show
The property original 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...
140
                    continue;
141
                }
142
143
                foreach ($this->original as $original) {
144
                    $this->destroyThumbnailFile($original, $name);
145
                }
146
            } else {
147
                $this->destroyThumbnailFile($this->original, $name);
148
            }
149
        }
150
    }
151
152
    /**
153
     * Remove thumbnail file from disk.
154
     *
155
     * @return void.
0 ignored issues
show
The doc-type void. could not be parsed: Unknown type name "void." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
156
     */
157
    public function destroyThumbnailFile($original, $name)
158
    {
159
        $ext = @pathinfo($original, PATHINFO_EXTENSION);
160
161
        // We remove extension from file name so we can append thumbnail type
162
        $path = @Str::replaceLast('.'.$ext, '', $original);
163
164
        // We merge original name + thumbnail name + extension
165
        $path = $path.'-'.$name.'.'.$ext;
166
167
        if ($this->storage->exists($path)) {
168
            $this->storage->delete($path);
169
        }
170
    }
171
172
    /**
173
     * Upload file and delete original thumbnail files.
174
     *
175
     * @param UploadedFile $file
176
     *
177
     * @return $this
178
     */
179
    protected function uploadAndDeleteOriginalThumbnail(UploadedFile $file)
180
    {
181
        foreach ($this->thumbnails as $name => $size) {
182
            // We need to get extension type ( .jpeg , .png ...)
183
            $ext = pathinfo($this->name, PATHINFO_EXTENSION);
184
185
            // We remove extension from file name so we can append thumbnail type
186
            $path = Str::replaceLast('.'.$ext, '', $this->name);
187
188
            // We merge original name + thumbnail name + extension
189
            $path = $path.'-'.$name.'.'.$ext;
190
191
            /** @var \Intervention\Image\Image $image */
192
            $image = InterventionImage::make($file);
193
194
            $action = $size[2] ?? 'resize';
195
            // Resize image with aspect ratio
196
            $image->$action($size[0], $size[1], function (Constraint $constraint) {
197
                $constraint->aspectRatio();
198
            })->resizeCanvas($size[0], $size[1], 'center', false, '#ffffff');
199
200
            if (!is_null($this->storagePermission)) {
201
                $this->storage->put("{$this->getDirectory()}/{$path}", $image->encode(), $this->storagePermission);
202
            } else {
203
                $this->storage->put("{$this->getDirectory()}/{$path}", $image->encode());
204
            }
205
        }
206
207
        $this->destroyThumbnail();
208
209
        return $this;
210
    }
211
}
212