Completed
Push — master ( 9b439e...de8363 )
by Igor
03:05
created

FileBehavior::getFileRulesDescription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 5
Bugs 0 Features 4
Metric Value
c 5
b 0
f 4
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * @link https://github.com/rkit/filemanager-yii2
5
 * @copyright Copyright (c) 2015 Igor Romanov
6
 * @license [MIT](http://opensource.org/licenses/MIT)
7
 */
8
9
namespace rkit\filemanager\behaviors;
10
11
use Yii;
12
use yii\base\Behavior;
13
use yii\db\ActiveRecord;
14
use yii\helpers\ArrayHelper;
15
use yii\base\InvalidParamException;
16
use rkit\filemanager\models\File;
17
use rkit\filemanager\helpers\FileRules;
18
use rkit\filemanager\behaviors\FileBind;
19
20
class FileBehavior extends Behavior
21
{
22
    /**
23
     * @var array
24
     */
25
    public $attributes = [];
26
    /**
27
     * @var rkit\filemanager\behaviors\FileBind
28
     */
29
    private static $bind;
30
31 41
    public function init()
32
    {
33 41
        parent::init();
34
35 41
        $this->setBind();
36 41
        Yii::$app->fileManager->registerTranslations();
37 41
    }
38
39
    /**
40
     * Set Decoder
41
     *
42
     * @return void
43
     */
44 41
    public function setBind()
45
    {
46 41
        $this->bind = new FileBind();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \rkit\filemanager\behaviors\FileBind() of type object<rkit\filemanager\behaviors\FileBind> is incompatible with the declared type object<rkit\filemanager\...ger\behaviors\FileBind> of property $bind.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
47 41
    }
48
49
    /**
50
     * @inheritdoc
51
     */
52 41
    public function events()
53
    {
54
        return [
55 41
            ActiveRecord::EVENT_AFTER_INSERT  => 'afterSave',
56 41
            ActiveRecord::EVENT_AFTER_UPDATE  => 'afterSave',
57 41
            ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave',
58 41
            ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeSave',
59 41
            ActiveRecord::EVENT_BEFORE_DELETE => 'beforeDelete',
60 41
        ];
61
    }
62
63 26
    public function beforeSave($insert)
64
    {
65 26
        foreach ($this->attributes as $attribute => $data) {
66 26
            $oldValue = $this->owner->isNewRecord ? null : $this->owner->getOldAttribute($attribute);
67 26
            $isAttributeChanged = $oldValue === null ? true : $this->owner->isAttributeChanged($attribute);
68
69 26
            $this->attributes[$attribute]['isAttributeChanged'] = $isAttributeChanged;
70 26
            $this->attributes[$attribute]['oldValue'] = $oldValue;
71 26
        }
72 26
    }
73
74 41
    public function afterSave()
75
    {
76 26
        foreach ($this->attributes as $attribute => $data) {
77 26
            $fileId = $this->owner->{$attribute};
78
79 26
            if ($data['isAttributeChanged'] === false || $fileId === null) {
80 26
                continue;
81
            }
82
83 26
            $file = $this->bind->setBind(
84 26
                $this->getFileStorage($attribute),
85 26
                $this->owner->primaryKey,
86 26
                $this->getFileOwnerType($attribute),
87
                $fileId
88 26
            );
89
90 26
            if (isset($data['saveFilePath']) && $data['saveFilePath'] === true) {
91 12
                $value = $this->prepareFilePath($file, $data['oldValue']);
92 26
            } elseif (isset($data['saveFileId']) && $data['saveFileId'] === true) {
93 17
                $value = $this->prepareFileId($file, $data['oldValue']);
94 41
            }
95
96 26
            if (isset($value)) {
97 17
                $this->owner->updateAttributes([$attribute => $value]);
98 17
            }
99 26
        }
100 26
    }
101
102 1
    public function beforeDelete()
103
    {
104 1
        foreach ($this->attributes as $attribute => $data) {
105 1
            $ownerType = $this->getFileOwnerType($attribute);
106 1
            $storage = $this->getFileStorage($attribute);
107 1
            (new File())->deleteByOwner($storage, $this->owner->primaryKey, $ownerType);
108 1
        }
109 1
    }
110
111
    /**
112
     * Prepare the path of the file
113
     *
114
     * @param mixed $file
115
     * @param mixed $oldValue
116
     * @return string
117
     */
118 12
    private function prepareFilePath($file, $oldValue)
119
    {
120 12
        if (is_object($file)) {
121 12
            return $file->getStorage()->path();
122 4
        } elseif ($file === false && $oldValue !== null) {
123 2
            return $oldValue;
124
        } else {
125 1
            return '';
126
        }
127
    }
128
129
    /**
130
     * Prepare the id of the file
131
     *
132
     * @param mixed $file
133
     * @param mixed $oldValue
134
     * @return int
135
     */
136 5
    private function prepareFileId($file, $oldValue)
137
    {
138 5
        if (is_object($file)) {
139 5
            return $file->id;
140 1
        } elseif ($file === false && $oldValue !== null) {
141 1
            return $oldValue;
142
        } else {
143 1
            return 0;
144
        }
145
    }
146
147
    /**
148
     * Get the path to the upload directory
149
     *
150
     * @param string $attribute
151
     * @return string
152
     */
153 30
    public function uploadDir($attribute)
154
    {
155 30
        if ($this->isFileProtected($attribute)) {
156 5
            return Yii::getAlias(Yii::$app->fileManager->uploadDirProtected);
157
        } else {
158 25
            return Yii::getAlias(Yii::$app->fileManager->uploadDirUnprotected);
159
        }
160
    }
161
162
    /**
163
     * Get the type of the owner in as string
164
     *
165
     * @param string $attribute
166
     * @return string
167
     */
168 30
    private function getStringOwnerType($attribute)
169
    {
170 30
        return $this->owner->tableName() . '.' . $attribute;
171
    }
172
173
    /**
174
     * Get the type of the owner
175
     *
176
     * @param string $attribute
177
     * @return int
178
     */
179 30
    public function getFileOwnerType($attribute)
180
    {
181 30
        return Yii::$app->fileManager->getOwnerType($this->getStringOwnerType($attribute));
182
    }
183
184
    /**
185
     * Get files
186
     *
187
     * @param string $attribute
188
     * @return array
189
     */
190 9
    public function getFiles($attribute)
191
    {
192 9
        $files = File::findAllByOwner($this->owner->primaryKey, $this->getFileOwnerType($attribute));
193 9
        foreach ($files as $file) {
194 9
            $file->setStorage($this->getFileStorage($attribute));
195 9
        }
196
197 9
        return $files;
198
    }
199
200
    /**
201
     * Get the file
202
     *
203
     * @param string $attribute
204
     * @return rkit\filemanager\models\File[]
205
     */
206 1
    public function getFile($attribute)
207
    {
208 1
        $file = File::findOneByOwner($this->owner->primaryKey, $this->getFileOwnerType($attribute));
209 1
        $file->setStorage($this->getFileStorage($attribute));
210 1
        return $file;
211
    }
212
213
    /**
214
     * The file is protected
215
     *
216
     * @param string $attribute
217
     * @return bool
218
     */
219 30
    public function isFileProtected($attribute)
220
    {
221 30
        return ArrayHelper::getValue($this->attributes[$attribute], 'protected', false);
222
    }
223
224
    /**
225
     * Get rules
226
     *
227
     * @param string $attribute
228
     * @return array
229
     */
230 32
    public function getFileRules($attribute)
231
    {
232 32
        return ArrayHelper::getValue($this->attributes[$attribute], 'rules', []);
233
    }
234
235
    /**
236
     * Get the presets of the file
237
     *
238
     * @param string $attribute
239
     * @return array
240
     */
241 5
    public function getFilePreset($attribute)
242
    {
243 5
        return array_keys(ArrayHelper::getValue($this->attributes[$attribute], 'preset', []));
244
    }
245
246
    /**
247
     * Get the presets of the file for apply after upload
248
     *
249
     * @param string $attribute
250
     * @return array
251
     */
252 30
    public function getFilePresetAfterUpload($attribute)
253
    {
254 30
        $preset = ArrayHelper::getValue($this->attributes[$attribute], 'applyPresetAfterUpload', false);
255 30
        if (is_string($preset) && $preset === '*') {
256 5
            return $this->getFilePreset($attribute);
257 25
        } elseif (is_array($preset)) {
258 16
            return $preset;
259
        }
260
261 9
        return [];
262
    }
263
264
    /**
265
     * Get the storage of the file
266
     *
267
     * @param string $attribute
268
     * @return Storage
269
     */
270 30
    public function getFileStorage($attribute)
271
    {
272 30
        $storage = ArrayHelper::getValue($this->attributes[$attribute], 'storage', null);
273 30
        if ($storage) {
274 30
            return new $storage();
275
        }
276
277
        throw new InvalidParamException('The storage is not defined'); // @codeCoverageIgnore
278
    }
279
280
    /**
281
     * Generate a thumb name
282
     *
283
     * @param string $path
284
     * @param string $prefix
285
     * @return string
286
     */
287 30
    public function generateThumbName($path, $prefix)
288
    {
289 30
        $fileName = pathinfo($path, PATHINFO_FILENAME);
290 30
        return str_replace($fileName, $prefix . '_' . $fileName, $path);
291
    }
292
293
    /**
294
     * Resize image
295
     *
296
     * @param string $attribute
297
     * @param string $preset
298
     * @param string $pathToFile Use this path to the file
299
     * @param bool $returnRealPath Return the real path to the file
300
     * @return string
301
     */
302 30
    public function thumb($attribute, $preset, $pathToFile = null, $returnRealPath = false)
303
    {
304 30
        $realPath = $this->uploadDir($attribute);
305 30
        $publicPath = $pathToFile ? $pathToFile : $this->owner->$attribute;
306 30
        $thumbPath = $this->generateThumbName($publicPath, $preset);
307
308 30
        if (!file_exists($realPath . $thumbPath)) {
309 30
            if (file_exists($realPath . $publicPath)) {
310 29
                $thumbInit = ArrayHelper::getValue($this->attributes[$attribute]['preset'], $preset);
311 29
                if ($thumbInit) {
312 29
                    $thumbInit($realPath, $publicPath, $thumbPath);
313 29
                }
314 29
            }
315 30
        }
316
317 30
        return $returnRealPath ? $realPath . $thumbPath : $thumbPath;
318
    }
319
320
    /**
321
     * Get description the rules of the file in as text
322
     *
323
     * @param string $attribute
324
     * @return string
325
     */
326 9
    public function getFileRulesDescription($attribute)
327
    {
328 9
        return FileRules::getDescription($this->attributes[$attribute]['rules']);
329
    }
330
}
331