Completed
Push — master ( ab1c63...7944b2 )
by Igor
06:51
created

File::getExtensionByMimeType()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.7286

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 21
ccs 9
cts 14
cp 0.6429
rs 9.0534
cc 4
eloc 14
nc 6
nop 1
crap 4.7286
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 35
    public function behaviors()
86
    {
87
        return [
88
            [
89 35
                'class' => TimestampBehavior::className(),
90 35
                'createdAtAttribute' => 'date_create',
91 35
                'updatedAtAttribute' => 'date_update',
92 35
                'value' => new \yii\db\Expression('NOW()'),
93 35
            ],
94 35
        ];
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 32
    public function beforeSave($insert)
113
    {
114 32
        if (parent::beforeSave($insert)) {
115 32
            if ($insert) {
116 32
                if (!file_exists($this->path)) {
117 1
                    return false;
118
                }
119 31
                if (!Yii::$app instanceof \yii\console\Application) {
120
                    $this->user_id = Yii::$app->user->isGuest ? 0 : Yii::$app->user->id; // @codeCoverageIgnore
121
                    $this->ip = ip2long(Yii::$app->request->getUserIP()); // @codeCoverageIgnore
122
                } // @codeCoverageIgnore
123
124 31
                $this->fillMetaInfo();
125
126 31
                if ($this->owner_id === null) {
127 31
                    $this->owner_id = 0;
128 31
                }
129 31
            }
130
131 31
            return true;
132
        }
133
134
        return false; // @codeCoverageIgnore
135
    }
136
137 31
    private function fillMetaInfo()
138
    {
139 31
        $pathInfo = pathinfo($this->path);
140
141 31
        if ($this->title === null) {
142 6
            $this->title = $pathInfo['filename'];
143 6
        }
144
145 31
        $this->size = filesize($this->path);
146 31
        $this->mime = FileHelper::getMimeType($this->path);
147 31
        $this->extension = $this->getExtensionByMimeType($this->mime);
148 31
        $this->name = $this->generateName();
149 31
    }
150
151 31
    private function getExtensionByMimeType($mimeType)
152
    {
153 31
        $extensions = FileHelper::getExtensionsByMimeType($mimeType);
154 31
        $pathInfo = pathinfo($this->path);
155 31
        $titleInfo = pathinfo($this->title);
156
157 31
        if (isset($pathInfo['extension'])) {
158 31
            $extension = $pathInfo['extension'];
159 31
        } elseif (isset($titleInfo['extension'])) {
160
            $extension = $titleInfo['extension'];
161
        } else {
162
            $extension = explode('/', $mimeType);
163
            $extension = end($extension);
164
        }
165
166 31
        if (array_search($extension, $extensions) !== false) {
167 31
            return $extension;
168
        }
169
170
        return current($extensions);
171
    }
172
173
    /**
174
     * Set a storage
175
     *
176
     * @param Storage $storage The Strorage for the file
177
     * @return string
178
     */
179 32
    public function setStorage(Storage $storage)
180
    {
181 32
        $this->storage = $storage;
182 32
        $this->storage->setFile($this);
183
184 32
        return $this;
185
    }
186
187
    /**
188
     * Get a storage
189
     *
190
     * @return string
191
     * @throws InvalidParamException
192
     */
193 33
    public function getStorage()
194
    {
195 33
        if ($this->storage === null) {
196 1
            throw new InvalidParamException('The storage is not initialized');
197
        }
198
199 32
        return $this->storage;
200
    }
201
202
    /**
203
     * Generate a name
204
     *
205
     * @return string
206
     */
207 31
    public function generateName()
208
    {
209 31
        $name = date('YmdHis') . substr(md5(microtime() . uniqid()), 0, 10);
210 31
        return $name . '.' . $this->extension;
211
    }
212
213
    /**
214
     * Checks whether the file is protected
215
     *
216
     * @return bool
217
     */
218 32
    public function isProtected()
219
    {
220 32
        return (bool)$this->protected;
221
    }
222
223
    /**
224
     * Checks whether the file is unprotected
225
     *
226
     * @return bool
227
     */
228 3
    public function isUnprotected()
229
    {
230 3
        return (bool)$this->protected === false;
231
    }
232
233
    /**
234
     * Checks whether the file is temp
235
     *
236
     * @return bool
237
     */
238 12
    public function isTmp()
239
    {
240 12
        return (bool)$this->tmp;
241
    }
242
243
    /**
244
     * Get date create of file in format `Ym`
245
     *
246
     * @return string
247
     */
248 31
    public function getDateOfFile()
249
    {
250 31
        if ($this->isNewRecord || is_object($this->date_create)) {
251 31
            return date('Ym');
252
        } else {
253 22
            return date_format(date_create($this->date_create), 'Ym');
254
        }
255
    }
256
257
    /**
258
     * Checks whether the owner of the file
259
     *
260
     * @param int $ownerId The id of the owner
261
     * @param int $ownerType The type of the owner
262
     * @return bool
263
     */
264 20
    public function isOwner($ownerId, $ownerType)
265
    {
266 20
        $ownerType = $this->owner_type === $ownerType;
267 20
        $ownerId = $this->owner_id === $ownerId;
268 20
        $user = $this->user_id === Yii::$app->user->id || $this->user_id === 0;
269
270 20
        return (!$this->tmp && $ownerType && $ownerId) || ($this->tmp && $ownerType && $user);
271
    }
272
273
    /**
274
     * Find all by owner
275
     *
276
     * @param int $ownerId The id of the owner
277
     * @param int $ownerType The type of the owner
278
     * @return array
279
     */
280 18
    public static function findAllByOwner($ownerId, $ownerType)
281
    {
282 18
        return static::find()
283 18
            ->where(['owner_id' => $ownerId, 'owner_type' => $ownerType])
284 18
            ->orderBy('position ASC')
285 18
            ->all();
286
    }
287
288
    /**
289
     * Find one by owner
290
     *
291
     * @param int $ownerId The id of the owner
292
     * @param int $ownerType The type of the owner
293
     * @return File|null
294
     */
295 1
    public static function findOneByOwner($ownerId, $ownerType)
296
    {
297 1
        return static::find()
298 1
            ->where(['owner_id' => $ownerId, 'owner_type' => $ownerType])
299 1
            ->one();
300
    }
301
302
    /**
303
     * Delete by owner
304
     *
305
     * @param Storage $storage The storage of the file
306
     * @param int $ownerId The id of the owner
307
     * @param int $ownerType The type of the owner
308
     */
309 3
    public function deleteByOwner($storage, $ownerId, $ownerType)
310
    {
311 3
        $files = self::findAllByOwner($ownerId, $ownerType);
312
313 3
        foreach ($files as $file) {
314 3
            $file->setStorage($storage);
315 3
            $file->delete();
316 3
        }
317 3
    }
318
319
    /**
320
     * Deleting a file from the db and from the file system
321
     * @internal
322
     *
323
     * @return bool
324
     */
325 7
    public function beforeDelete()
326
    {
327 7
        $this->getStorage()->delete();
328 7
        return true;
329
    }
330
}
331