Completed
Push — master ( f3bd31...76e876 )
by Igor
02:26
created

File::generateName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 4
Bugs 0 Features 3
Metric Value
c 4
b 0
f 3
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
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\models;
10
11
use Yii;
12
use yii\base\InvalidParamException;
13
use yii\behaviors\TimestampBehavior;
14
use yii\helpers\FileHelper;
15
use rkit\filemanager\Storage;
16
17
/**
18
 * ActiveRecord for table "file"
19
 *
20
 * @property integer $id
21
 * @property integer $user_id
22
 * @property integer $owner_id
23
 * @property integer $owner_type
24
 * @property string $title
25
 * @property string $name
26
 * @property integer $size
27
 * @property string $extension
28
 * @property string $mime
29
 * @property string $date_create
30
 * @property string $date_update
31
 * @property integer $ip
32
 * @property integer $tmp
33
 * @property integer $position
34
 * @property integer $protected
35
 */
36
class File extends \yii\db\ActiveRecord
37
{
38
    /**
39
     * @var string
40
     */
41
    public $path;
42
    /**
43
     * @var Storage
44
     */
45
    private $storage;
46
47
    /**
48
     * @inheritdoc
49
     * @codeCoverageIgnore
50
     * @internal
51
     */
52
    public static function tableName()
53
    {
54
        return 'file';
55
    }
56
57
    /**
58
     * @inheritdoc
59
     * @codeCoverageIgnore
60
     * @internal
61
     */
62
    public function attributeLabels()
63
    {
64
        return [
65
            'id' => Yii::t('filemanager-yii2', 'ID'),
66
            'user_id' => Yii::t('filemanager-yii2', 'User'),
67
            'owner_id' => Yii::t('filemanager-yii2', 'Owner'),
68
            'owner_type' => Yii::t('filemanager-yii2', 'Owner type'),
69
            'title' => Yii::t('filemanager-yii2', 'Title'),
70
            'name' => Yii::t('filemanager-yii2', 'Name'),
71
            'size' => Yii::t('filemanager-yii2', 'Size'),
72
            'extension' => Yii::t('filemanager-yii2', 'Extension'),
73
            'mime' => Yii::t('filemanager-yii2', 'Mime'),
74
            'date_create' => Yii::t('filemanager-yii2', 'Date create'),
75
            'date_update' => Yii::t('filemanager-yii2', 'Date update'),
76
            'ip' => Yii::t('filemanager-yii2', 'IP'),
77
            'position' => Yii::t('filemanager-yii2', 'Position'),
78
        ];
79
    }
80
81
    /**
82
     * @inheritdoc
83
     * @internal
84
     */
85 38
    public function behaviors()
86
    {
87
        return [
88
            [
89 38
                'class' => TimestampBehavior::className(),
90 38
                'createdAtAttribute' => 'date_create',
91 38
                'updatedAtAttribute' => 'date_update',
92 38
                'value' => new \yii\db\Expression('NOW()'),
93 38
            ],
94 38
        ];
95
    }
96
97
    /**
98
     * @inheritdoc
99
     * @codeCoverageIgnore
100
     * @internal
101
     */
102
    public function events()
103
    {
104
        return [
105
            \yii\db\ActiveRecord::EVENT_BEFORE_DELETE => 'beforeDelete',
106
        ];
107
    }
108
109
    /**
110
     * @internal
111
     */
112 35
    public function beforeSave($insert)
113
    {
114 35
        if (parent::beforeSave($insert)) {
115 35
            if ($insert) {
116 35
                if (!file_exists($this->path)) {
117 1
                    return false;
118
                }
119
120 34
                $this->fillUserInfo();
121 34
                $this->fillMetaInfo();
122
123 34
                if ($this->owner_id === null) {
124 34
                    $this->owner_id = 0;
125 34
                }
126 34
            }
127
128 34
            return true;
129
        }
130
131
        return false; // @codeCoverageIgnore
132
    }
133
134 34
    private function fillUserInfo()
135
    {
136 34
        if (!Yii::$app instanceof \yii\console\Application) {
137
            $this->user_id = Yii::$app->user->isGuest ? 0 : Yii::$app->user->id; // @codeCoverageIgnore
138
            $this->ip = ip2long(Yii::$app->request->getUserIP()); // @codeCoverageIgnore
139
        } // @codeCoverageIgnore
140 34
    }
141
142 34
    private function fillMetaInfo()
143
    {
144 34
        $pathInfo = pathinfo($this->path);
145
146 34
        if ($this->title === null) {
147 6
            $this->title = $pathInfo['filename'];
148 6
        }
149
150 34
        $this->size = filesize($this->path);
151 34
        $this->mime = FileHelper::getMimeType($this->path);
152 34
        $this->extension = $this->getExtensionByMimeType($this->mime);
153 34
        $this->name = $this->generateName();
154 34
    }
155
156
    /**
157
     * Get extension By MimeType
158
     *
159
     * @param string $mimeType MimeType of the file
160
     * @return string
161
     */
162 34
    private function getExtensionByMimeType($mimeType)
163
    {
164 34
        $extensions = FileHelper::getExtensionsByMimeType($mimeType);
165 34
        $pathExtension = pathinfo($this->path, PATHINFO_EXTENSION);
166 34
        $titleExtension = pathinfo($this->title, PATHINFO_EXTENSION);
167
168 34
        if (array_search($pathExtension, $extensions) !== false) {
169 32
            return $pathExtension;
170 2
        } elseif (array_search($titleExtension, $extensions) !== false) {
171 1
            return $titleExtension;
172
        } else {
173 1
            $extension = explode('/', $mimeType);
174 1
            $extension = end($extension);
175 1
            if (array_search($extension, $extensions) !== false) {
176 1
                return $extension;
177
            }
178
        }
179
180
        return current($extensions); // @codeCoverageIgnore
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression current($extensions); of type integer|string|false adds false to the return on line 180 which is incompatible with the return type documented by rkit\filemanager\models\...:getExtensionByMimeType of type string. It seems like you forgot to handle an error condition.
Loading history...
181
    }
182
183
    /**
184
     * Set a storage
185
     *
186
     * @param Storage $storage The Strorage for the file
187
     * @return string
188
     */
189 35
    public function setStorage(Storage $storage)
190
    {
191 35
        $this->storage = $storage;
192 35
        $this->storage->setFile($this);
193
194 35
        return $this;
195
    }
196
197
    /**
198
     * Get a storage
199
     *
200
     * @return string
201
     * @throws InvalidParamException
202
     */
203 36
    public function getStorage()
204
    {
205 36
        if ($this->storage === null) {
206 1
            throw new InvalidParamException('The storage is not initialized');
207
        }
208
209 35
        return $this->storage;
210
    }
211
212
    /**
213
     * Generate a name
214
     *
215
     * @return string
216
     */
217 34
    public function generateName()
218
    {
219 34
        $name = date('YmdHis') . substr(md5(microtime() . uniqid()), 0, 10);
220 34
        return $name . '.' . $this->extension;
221
    }
222
223
    /**
224
     * Checks whether the file is protected
225
     *
226
     * @return bool
227
     */
228 35
    public function isProtected()
229
    {
230 35
        return (bool)$this->protected;
231
    }
232
233
    /**
234
     * Checks whether the file is unprotected
235
     *
236
     * @return bool
237
     */
238 3
    public function isUnprotected()
239
    {
240 3
        return (bool)$this->protected === false;
241
    }
242
243
    /**
244
     * Checks whether the file is temp
245
     *
246
     * @return bool
247
     */
248 12
    public function isTmp()
249
    {
250 12
        return (bool)$this->tmp;
251
    }
252
253
    /**
254
     * Get date create of file in format `Ym`
255
     *
256
     * @return string
257
     */
258 34
    public function getDateOfFile()
259
    {
260 34
        if ($this->isNewRecord || is_object($this->date_create)) {
261 34
            return date('Ym');
262
        } else {
263 23
            return date_format(date_create($this->date_create), 'Ym');
264
        }
265
    }
266
267
    /**
268
     * Checks whether the owner of the file
269
     *
270
     * @param int $ownerId The id of the owner
271
     * @param int $ownerType The type of the owner
272
     * @return bool
273
     */
274 21
    public function isOwner($ownerId, $ownerType)
275
    {
276 21
        $ownerType = $this->owner_type === $ownerType;
277 21
        $ownerId = $this->owner_id === $ownerId;
278 21
        $user = $this->user_id === Yii::$app->user->id || $this->user_id === 0;
279
280 21
        return (!$this->tmp && $ownerType && $ownerId) || ($this->tmp && $ownerType && $user);
281
    }
282
283
    /**
284
     * Find all by owner
285
     *
286
     * @param int $ownerId The id of the owner
287
     * @param int $ownerType The type of the owner
288
     * @return array
289
     */
290 19
    public static function findAllByOwner($ownerId, $ownerType)
291
    {
292 19
        return static::find()
293 19
            ->where(['owner_id' => $ownerId, 'owner_type' => $ownerType])
294 19
            ->orderBy('position ASC')
295 19
            ->all();
296
    }
297
298
    /**
299
     * Find one by owner
300
     *
301
     * @param int $ownerId The id of the owner
302
     * @param int $ownerType The type of the owner
303
     * @return File|null
304
     */
305 1
    public static function findOneByOwner($ownerId, $ownerType)
306
    {
307 1
        return static::find()
308 1
            ->where(['owner_id' => $ownerId, 'owner_type' => $ownerType])
309 1
            ->one();
310
    }
311
312
    /**
313
     * Delete by owner
314
     *
315
     * @param Storage $storage The storage of the file
316
     * @param int $ownerId The id of the owner
317
     * @param int $ownerType The type of the owner
318
     */
319 3
    public function deleteByOwner($storage, $ownerId, $ownerType)
320
    {
321 3
        $files = self::findAllByOwner($ownerId, $ownerType);
322
323 3
        foreach ($files as $file) {
324 3
            $file->setStorage($storage);
325 3
            $file->delete();
326 3
        }
327 3
    }
328
329
    /**
330
     * Deleting a file from the db and from the file system
331
     * @internal
332
     *
333
     * @return bool
334
     */
335 8
    public function beforeDelete()
336
    {
337 8
        $this->getStorage()->delete();
338 8
        return true;
339
    }
340
}
341