Completed
Push — master ( 8c64c3...017009 )
by Song
02:56
created

ImageField::thumbnail()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 3
nop 3
dl 0
loc 14
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Form\Field;
4
5
use Intervention\Image\Constraint;
6
use Intervention\Image\Facades\Image as InterventionImage;
7
use Intervention\Image\ImageManagerStatic;
8
use Symfony\Component\HttpFoundation\File\UploadedFile;
9
10
trait ImageField
11
{
12
    /**
13
     * Intervention calls.
14
     *
15
     * @var array
16
     */
17
    protected $interventionCalls = [];
18
19
    /**
20
     * Thumbnail settings.
21
     *
22
     * @var array
23
     */
24
    protected $thumbnails = [];
25
26
    /**
27
     * Default directory for file to upload.
28
     *
29
     * @return mixed
30
     */
31
    public function defaultDirectory()
32
    {
33
        return config('admin.upload.directory.image');
34
    }
35
36
    /**
37
     * Execute Intervention calls.
38
     *
39
     * @param string $target
40
     *
41
     * @return mixed
42
     */
43
    public function callInterventionMethods($target)
44
    {
45
        if (!empty($this->interventionCalls)) {
46
            $image = ImageManagerStatic::make($target);
47
48
            foreach ($this->interventionCalls as $call) {
49
                call_user_func_array(
50
                    [$image, $call['method']],
51
                    $call['arguments']
52
                )->save($target);
53
            }
54
        }
55
56
        return $target;
57
    }
58
59
    /**
60
     * Call intervention methods.
61
     *
62
     * @param string $method
63
     * @param array  $arguments
64
     *
65
     * @throws \Exception
66
     *
67
     * @return $this
68
     */
69
    public function __call($method, $arguments)
70
    {
71
        if (static::hasMacro($method)) {
72
            return $this;
73
        }
74
75
        if (!class_exists(ImageManagerStatic::class)) {
76
            throw new \Exception('To use image handling and manipulation, please install [intervention/image] first.');
77
        }
78
79
        $this->interventionCalls[] = [
80
            'method'    => $method,
81
            'arguments' => $arguments,
82
        ];
83
84
        return $this;
85
    }
86
87
    /**
88
     * Render a image form field.
89
     *
90
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
91
     */
92
    public function render()
93
    {
94
        $this->options(['allowedFileTypes' => ['image'], 'msgPlaceholder' => trans('admin.choose_image')]);
0 ignored issues
show
Documentation Bug introduced by
The method options does not exist on object<Encore\Admin\Form\Field\ImageField>? 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...
95
96
        return parent::render();
97
    }
98
99
    /**
100
     * @param string|array $name
101
     * @param int    $width
102
     * @param int    $height
103
     *
104
     * @return $this
105
     */
106
    public function thumbnail($name, int $width = null, int $height = null)
107
    {
108
        if (func_num_args() == 1 && is_array($name)) {
109
            foreach ($name as $key => $size) {
110
                if (count($size) == 2) {
111
                    $this->thumbnails[$key] = $size;
112
                }
113
            }
114
        } elseif (func_num_args() == 3) {
115
            $this->thumbnails[$name] = [$width, $height];
116
        }
117
118
        return $this;
119
    }
120
121
    /**
122
     * Destroy original thumbnail files.
123
     *
124
     * @return void.
0 ignored issues
show
Documentation introduced by
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...
125
     */
126
    public function destroyThumbnail()
127
    {
128
        if ($this->retainable) {
0 ignored issues
show
Bug introduced by
The property retainable 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...
129
            return;
130
        }
131
132
        foreach ($this->thumbnails as $name => $_) {
133
            // We need to get extension type ( .jpeg , .png ...)
134
            $ext = pathinfo($this->original, PATHINFO_EXTENSION);
0 ignored issues
show
Bug introduced by
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...
135
136
            // We remove extension from file name so we can append thumbnail type
137
            $path = str_replace_last('.'.$ext, '', $this->original);
0 ignored issues
show
Deprecated Code introduced by
The function str_replace_last() has been deprecated with message: Str::replaceLast() should be used directly instead. Will be removed in Laravel 5.9.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
138
139
            // We merge original name + thumbnail name + extension
140
            $path = $path.'-'.$name.'.'.$ext;
141
142
            if ($this->storage->exists($path)) {
143
                $this->storage->delete($path);
0 ignored issues
show
Bug introduced by
The property storage 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...
144
            }
145
        }
146
    }
147
148
    /**
149
     * Upload file and delete original thumbnail files.
150
     *
151
     * @param UploadedFile $file
152
     *
153
     * @return $this
154
     */
155
    protected function uploadAndDeleteOriginalThumbnail(UploadedFile $file)
156
    {
157
        foreach ($this->thumbnails as $name => $size) {
158
            // We need to get extension type ( .jpeg , .png ...)
159
            $ext = pathinfo($this->name, PATHINFO_EXTENSION);
0 ignored issues
show
Bug introduced by
The property name 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...
160
161
            // We remove extension from file name so we can append thumbnail type
162
            $path = str_replace_last('.'.$ext, '', $this->name);
0 ignored issues
show
Deprecated Code introduced by
The function str_replace_last() has been deprecated with message: Str::replaceLast() should be used directly instead. Will be removed in Laravel 5.9.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
163
164
            // We merge original name + thumbnail name + extension
165
            $path = $path.'-'.$name.'.'.$ext;
166
167
168
            /** @var \Intervention\Image\Image $image */
169
            $image = InterventionImage::make($file);
170
171
            // Resize image with aspect ratio
172
            $image->resize($size[0], $size[1], function (Constraint $constraint) {
173
                $constraint->aspectRatio();
174
            })->resizeCanvas($size[0], $size[1], 'center', false, '#ffffff');
175
176
            if (!is_null($this->storagePermission)) {
0 ignored issues
show
Bug introduced by
The property storagePermission does not seem to exist. Did you mean storage?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
177
                $this->storage->put("{$this->getDirectory()}/{$path}", $image->encode(), $this->storagePermission);
0 ignored issues
show
Bug introduced by
The property storagePermission does not seem to exist. Did you mean storage?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Documentation Bug introduced by
The method getDirectory does not exist on object<Encore\Admin\Form\Field\ImageField>? 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...
178
            } else {
179
                $this->storage->put("{$this->getDirectory()}/{$path}", $image->encode());
0 ignored issues
show
Documentation Bug introduced by
The method getDirectory does not exist on object<Encore\Admin\Form\Field\ImageField>? 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...
180
            }
181
        }
182
183
        $this->destroyThumbnail();
184
185
        return $this;
186
    }
187
}
188