Completed
Push — master ( 6b72ed...29992f )
by Pavel
03:16
created

ImageBehavior::afterDelete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Image behavior for ActiveRecord
4
 *
5
 * @link https://github.com/inblank/yii2-image
6
 * @copyright Copyright (c) 2016 Pavel Aleksandrov <[email protected]>
7
 * @license http://opensource.org/licenses/MIT
8
 */
9
namespace inblank\image;
10
11
use Imagine\Image\Box;
12
use yii;
13
use yii\base\Behavior;
14
use yii\db\ActiveRecord;
15
16
/**
17
 * Class Image
18
 *
19
 * @property ActiveRecord $owner
20
 */
21
class ImageBehavior extends Behavior
22
{
23
24
    /**
25
     * Name of attribute to store the image
26
     * @var string
27
     */
28
    public $imageAttribute = "image";
29
    /**
30
     * Default image name
31
     * @var string
32
     */
33
    public $imageDefault = "image.png";
34
    /**
35
     * Path to store image files.
36
     * If empty will be init to /images/<ActiveRecord Class Name>
37
     * @var string
38
     */
39
    public $imagePath;
40
    /**
41
     * Size to convert image
42
     * If array: [width, height].
43
     * If integer: use value for with and height.
44
     * If not set: image save as is.
45
     * @var integer|array
46
     */
47
    public $imageSize;
48
    /**
49
     * Calculated absolute image path relative to webroot
50
     * @var
51
     */
52
    protected $_imageAbsolutePath;
53
54
    /**
55
     * @inheritdoc
56
     */
57 3
    public function events()
58
    {
59
        return [
60 3
            ActiveRecord::EVENT_AFTER_INSERT => 'afterSave',
61 3
            ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave',
62 3
            ActiveRecord::EVENT_AFTER_DELETE => 'afterDelete',
63 3
        ];
64
    }
65
66
    /**
67
     * After save action
68
     */
69 2
    public function afterSave()
70
    {
71 2
        $this->imageChangeByUpload();
72 2
    }
73
74
    /**
75
     * After delete action
76
     */
77 1
    public function afterDelete()
78
    {
79 1
        $this->imageRemoveFile();
80 1
    }
81
82
    /**
83
     * Get image path
84
     * @return string
85
     */
86 3
    public function getImagePath()
87
    {
88 3
        if ($this->imagePath === null) {
89 3
            $this->imagePath = '/images/' . strtolower((new \ReflectionClass($this->owner))->getShortName());
90 3
        }
91 3
        return $this->imagePath;
92
    }
93
94
    /**
95
     * Get default image URL
96
     * @return string
97
     * @throws yii\base\InvalidConfigException
98
     */
99
    public function getImageDefaultUrl()
100
    {
101
        return $this->_imageUrl($this->imageDefault);
102
    }
103
104
    /**
105
     * Get absolute team image path in filesystem
106
     * @return string
107
     */
108 3
    public function getImageAbsolutePath()
109
    {
110 3
        if ($this->_imageAbsolutePath === null) {
111 3
            $this->_imageAbsolutePath = Yii::getAlias('@webroot') .
112 3
                '/' . (defined('IS_BACKEND') ? '../' : '') .
113 3
                ltrim($this->getImagePath(), '/');
114 3
            if (!file_exists($this->_imageAbsolutePath)) {
115
                yii\helpers\FileHelper::createDirectory($this->_imageAbsolutePath);
116
            }
117 3
        }
118 3
        return $this->_imageAbsolutePath;
119
    }
120
121
    /**
122
     * Check team image
123
     * @return bool
124
     * @throws yii\base\InvalidConfigException
125
     */
126 3
    public function hasImage()
127
    {
128 3
        $image = $this->owner->getAttribute($this->imageAttribute);
129 3
        return !empty($image) && $image != $this->imageDefault;
130
    }
131
132
    /**
133
     * Check that image file exists
134
     */
135
    public function imageFileExists()
136
    {
137
        return file_exists($this->getImageFile());
138
    }
139
140
    /**
141
     * Get team image URL
142
     * @return string
143
     * @throws yii\base\InvalidConfigException
144
     */
145
    public function getImageUrl()
146
    {
147
        return !$this->hasImage() ?
148
            $this->getImageDefaultUrl() :
149
            $this->_imageUrl($this->owner->getAttribute($this->imageAttribute));
150
    }
151
152
    /**
153
     * Return filename in filesystem
154
     * @return string
155
     */
156 3
    public function getImageFile()
157
    {
158 3
        return $this->getImageAbsolutePath() . '/' . $this->owner->getAttribute($this->imageAttribute);
159
    }
160
161
    /**
162
     * Change image by uploaded file
163
     */
164 2
    public function imageChangeByUpload()
0 ignored issues
show
Coding Style introduced by
imageChangeByUpload uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
165
    {
166 2
        $formName = $this->owner->formName();
167 2
        if (!empty($_FILES[$formName]['tmp_name'][$this->imageAttribute])) {
168
            $this->imageChange(
169
                [$_FILES[$formName]['name'][$this->imageAttribute] => $_FILES[$formName]['tmp_name'][$this->imageAttribute]]
170
            );
171
        }
172 2
    }
173
174
    /**
175
     * Change image
176
     * @param string|array $sourceFile source file. if set as array ['fileName' => 'file_in_filesystem']
177
     * @return bool true, if image was changed and old image file was deleted. false, if image not changed
178
     * @throws yii\base\InvalidConfigException
179
     */
180 3
    public function imageChange($sourceFile)
181
    {
182 3
        if (is_array($sourceFile)) {
183
            $fileName = key($sourceFile);
184
            $sourceFile = current($sourceFile);
185
        } else {
186 3
            $fileName = $sourceFile;
187
        }
188 3
        if (!file_exists($sourceFile)) {
189 1
            return false;
190
        }
191 3
        $imageName = $this->imageAttribute . '_' .
192 3
            md5(implode('-', (array)$this->owner->getPrimaryKey()) . microtime(true) . rand()) .
193 3
            '.' . pathinfo($fileName)['extension'];
194 3
        $destinationFile = $this->getImageAbsolutePath() . '/' . $imageName;
195 3
        if (!copy($sourceFile, $destinationFile)) {
196
            return false;
197
        }
198 3
        $this->imageRemoveFile();
199 3
        if (!empty($this->imageSize)) {
200 1
            $size = $this->imageSize;
201 1
            if (!is_array($size)) {
202 1
                $size = [$size, $size];
203 1
            }
204 1
            yii\imagine\Image::getImagine()
205 1
                ->open($destinationFile)
206 1
                ->resize(new Box($size[0], $size[1]))
207 1
                ->save($destinationFile);
208 1
        }
209 3
        $this->owner->setAttribute($this->imageAttribute, $imageName);
210 3
        $this->owner->updateAttributes([$this->imageAttribute]);
211 3
        return true;
212
    }
213
214
    /**
215
     * Reset image to default
216
     * @throws yii\base\InvalidConfigException
217
     */
218 1
    public function imageReset()
219
    {
220 1
        $this->imageRemoveFile();
221 1
        $this->owner->setAttribute($this->imageAttribute, null);
222 1
        $this->owner->updateAttributes([$this->imageAttribute]);
223 1
    }
224
225
    /**
226
     * Remove current image
227
     * @throws yii\base\InvalidConfigException
228
     */
229 3
    protected function imageRemoveFile()
230
    {
231 3
        if ($this->hasImage()) {
232 2
            @unlink($this->getImageFile());
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
233 2
        }
234 3
    }
235
236
    /**
237
     * Make image URL
238
     * @param string $imageFileName image filename
239
     * @return string
240
     * @throws yii\base\InvalidConfigException
241
     */
242
    protected function _imageUrl($imageFileName)
243
    {
244
        return $this->getImagePath() . '/' . $imageFileName;
245
    }
246
247
}
248