File::getDb()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: floor12
5
 * Date: 23.06.2016
6
 * Time: 11:23
7
 */
8
9
namespace floor12\files\models;
10
11
12
use ErrorException;
13
use floor12\files\assets\IconHelper;
14
use Yii;
15
use yii\db\ActiveRecord;
16
use yii\helpers\Url;
17
18
19
/**
20
 * @property integer $id
21
 * @property string $class
22
 * @property string $field
23
 * @property integer $object_id
24
 * @property string $title
25
 * @property string $filename
26
 * @property string $content_type
27
 * @property integer $type
28
 * @property integer $video_status
29
 * @property integer $ordering
30
 * @property integer $created
31
 * @property integer $user_id
32
 * @property integer $size
33
 * @property string $hash
34
 * @property string $alt
35
 * @property string $href
36
 * @property string $icon
37
 * @property string $rootPath
38
 * @property string|null $watermark
39
 */
40
class File extends ActiveRecord
41
{
42
    const DIRECTORY_SEPARATOR = "/";
43
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public static function getDb()
49
    {
50
        return Yii::$app->getModule('files')->db;
51
    }
52
53
    /**
54
     * @inheritdoc
55
     */
56
57
    public static function tableName()
58
    {
59
        return '{{%file}}';
60
    }
61
62
    /**
63
     * Create hash if its empty
64
     * @param bool $insert
65
     * @return bool
66
     */
67
    public function beforeSave($insert)
68
    {
69
        if (!$this->hash) {
70
            $this->changeHash();
71
        }
72
        return parent::beforeSave($insert);
73
    }
74
75
    /**
76
     * Change object hash
77
     */
78
    public function changeHash()
79
    {
80
        $this->hash = md5(time() . rand(99999, 99999999));
81
82
    }
83
84
    /**
85
     * @return string
86
     */
87
    public function getIcon()
88
    {
89
        $icon = IconHelper::FILE;
90
91
        if ($this->content_type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')
92
            $icon = IconHelper::FILE_WORD;
93
94
        if ($this->content_type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
95
            $icon = IconHelper::FILE_EXCEL;
96
97
        if ($this->content_type == 'application/vnd.openxmlformats-officedocument.presentationml.presentation')
98
            $icon = IconHelper::FILE_POWERPOINT;
99
100
        if ($this->content_type == 'application/x-zip-compressed')
101
            $icon = IconHelper::FILE_ARCHIVE;
102
103
        if ($this->content_type == 'application/octet-stream')
104
            $icon = IconHelper::FILE_ARCHIVE;
105
106
        if (preg_match('/audio/', $this->content_type))
107
            $icon = IconHelper::FILE_AUDIO;
108
109
        if (preg_match('/pdf/', $this->content_type))
110
            $icon = IconHelper::FILE_PDF;
111
112
        if ($this->type == FileType::VIDEO)
113
            $icon = IconHelper::FILE_VIDEO;
114
115
        return $icon;
116
    }
117
118
    function mime_content_type($filename)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
119
    {
120
        $idx = explode('.', $filename);
121
        $count_explode = count($idx);
122
        $idx = strtolower($idx[$count_explode - 1]);
123
124
        $mimet = array(
125
            'txt' => 'text/plain',
126
            'htm' => 'text/html',
127
            'html' => 'text/html',
128
            'php' => 'text/html',
129
            'css' => 'text/css',
130
            'js' => 'application/javascript',
131
            'json' => 'application/json',
132
            'xml' => 'application/xml',
133
            'swf' => 'application/x-shockwave-flash',
134
            'flv' => 'video/x-flv',
135
136
            // images
137
            'png' => 'image/png',
138
            'jpe' => 'image/jpeg',
139
            'jpeg' => 'image/jpeg',
140
            'jpg' => 'image/jpeg',
141
            'gif' => 'image/gif',
142
            'bmp' => 'image/bmp',
143
            'ico' => 'image/vnd.microsoft.icon',
144
            'tiff' => 'image/tiff',
145
            'tif' => 'image/tiff',
146
            'svg' => 'image/svg+xml',
147
            'svgz' => 'image/svg+xml',
148
149
            // archives
150
            'zip' => 'application/zip',
151
            'rar' => 'application/x-rar-compressed',
152
            'exe' => 'application/x-msdownload',
153
            'msi' => 'application/x-msdownload',
154
            'cab' => 'application/vnd.ms-cab-compressed',
155
156
            // audio/video
157
            'mp3' => 'audio/mpeg',
158
            'qt' => 'video/quicktime',
159
            'mov' => 'video/quicktime',
160
161
            // adobe
162
            'pdf' => 'application/pdf',
163
            'psd' => 'image/vnd.adobe.photoshop',
164
            'ai' => 'application/postscript',
165
            'eps' => 'application/postscript',
166
            'ps' => 'application/postscript',
167
168
            // ms office
169
            'doc' => 'application/msword',
170
            'rtf' => 'application/rtf',
171
            'xls' => 'application/vnd.ms-excel',
172
            'ppt' => 'application/vnd.ms-powerpoint',
173
            'docx' => 'application/msword',
174
            'xlsx' => 'application/vnd.ms-excel',
175
            'pptx' => 'application/vnd.ms-powerpoint',
176
177
178
            // open office
179
            'odt' => 'application/vnd.oasis.opendocument.text',
180
            'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
181
        );
182
183
        if (isset($mimet[$idx])) {
184
            return $mimet[$idx];
185
        } else {
186
            return 'application/octet-stream';
187
        }
188
    }
189
190
    /**
191
     * @inheritdoc
192
     */
193
194
    public function rules()
195
    {
196
        return [
197
            [['class', 'field', 'filename', 'content_type', 'type'], 'required'],
198
            [['object_id', 'type', 'video_status', 'ordering'], 'integer'],
199
            [['class', 'field', 'title', 'filename', 'content_type', 'alt'], 'string', 'max' => 255],
200
        ];
201
    }
202
203
    /**
204
     * @inheritdoc
205
     */
206
207
    public function attributeLabels()
208
    {
209
        return [
210
            'id' => Yii::t('app', 'ID'),
211
            'class' => Yii::t('app', 'Class'),
212
            'field' => Yii::t('app', 'Field'),
213
            'object_id' => Yii::t('app', 'Object ID'),
214
            'title' => Yii::t('app', 'Title'),
215
            'filename' => Yii::t('app', 'Filename'),
216
            'content_type' => Yii::t('app', 'Con tent Type'),
217
            'type' => Yii::t('app', 'Type'),
218
            'video_status' => Yii::t('app', 'Video Status'),
219
            'alt' => Yii::t('app', 'Alternative title'),
220
        ];
221
    }
222
223
    /**
224
     * Return root path of preview
225
     * @return string
226
     */
227
228
    public function getRootPreviewPath()
229
    {
230
        if ($this->isSvg())
231
            return $this->getRootPath();
232
233
        return Yii::$app->getModule('files')->storageFullPath . $this->filename . '.jpg';
0 ignored issues
show
Bug introduced by
Are you sure Yii::app->getModule('files')->storageFullPath of type mixed|null|object can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

233
        return /** @scrutinizer ignore-type */ Yii::$app->getModule('files')->storageFullPath . $this->filename . '.jpg';
Loading history...
234
    }
235
236
    /**
237
     * @return bool
238
     */
239
    public function isSvg()
240
    {
241
        return $this->content_type == 'image/svg+xml';
242
    }
243
244
    /**
245
     * Return root path of image
246
     * @return string
247
     */
248
249
    public function getRootPath()
250
    {
251
        return Yii::$app->getModule('files')->storageFullPath . DIRECTORY_SEPARATOR . $this->filename;
0 ignored issues
show
Bug introduced by
Are you sure Yii::app->getModule('files')->storageFullPath of type mixed|null|object can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

251
        return /** @scrutinizer ignore-type */ Yii::$app->getModule('files')->storageFullPath . DIRECTORY_SEPARATOR . $this->filename;
Loading history...
252
    }
253
254
255
    /**
256
     * Return web path
257
     * @return string
258
     */
259
260
    public function getHref()
261
    {
262
        return Url::to(['/files/default/get', 'hash' => $this->hash]);
263
    }
264
265
    /**
266
     * @return bool
267
     */
268
    public function isImage(): bool
269
    {
270
        return $this->type == FileType::IMAGE;
271
    }
272
273
    /**
274
     * Delete files from disk
275
     */
276
277
    public function afterDelete()
278
    {
279
        $this->deleteFiles();
280
        parent::afterDelete();
281
    }
282
283
    /**
284
     * Method to read files from any mime types
285
     * @return bool
286
     */
287
288
//    public function imageCreateFromAny()
289
//    {
290
//        $type = exif_imagetype($this->rootPath);
291
//        $allowedTypes = array(
292
//            1, // [] gif
293
//            2, // [] jpg
294
//            3, // [] png
295
//            6   // [] bmp
296
//        );
297
//        if (!in_array($type, $allowedTypes)) {
298
//            return false;
299
//        }
300
//        switch ($type) {
301
//            case 1 :
302
//                $im = imageCreateFromGif($this->rootPath);
303
//                break;
304
//            case 2 :
305
//                $im = imageCreateFromJpeg($this->rootPath);
306
//                break;
307
//            case 3 :
308
//                $im = imageCreateFromPng($this->rootPath);
309
//                break;
310
//            case 6 :
311
//                $im = imageCreateFromBmp($this->rootPath);
312
//                break;
313
//        }
314
//        return $im;
315
//    }
316
317
    /**
318
     * Delete all files
319
     */
320
    public function deleteFiles()
321
    {
322
        $extension = pathinfo($this->rootPath, PATHINFO_EXTENSION);
323
        array_map('unlink', glob(str_replace(".{$extension}", '*', $this->rootPath)));
324
    }
325
326
    /**
327
     * Set object_id to 0 to break link with object
328
     * @return void
329
     */
330
    public function setZeroObject()
331
    {
332
        $this->object_id = 0;
333
        $this->save(false);
334
    }
335
336
    /**
337
     * @return mixed|null
338
     */
339
    public function getWatermark()
340
    {
341
        $owner = new $this->class();
342
        if (
343
            isset($owner->behaviors['files']) &&
344
            isset($owner->behaviors['files']->attributes[$this->field]) &&
345
            isset($owner->behaviors['files']->attributes[$this->field]['watermark'])
346
        )
347
            return $owner->behaviors['files']->attributes[$this->field]['watermark'];
348
    }
349
350
    /**
351
     * @return string
352
     */
353
    public function __toString()
354
    {
355
        return $this->href;
356
    }
357
358
    /**
359
     * Return webp path to preview
360
     * @param int $width
361
     * @param bool $webp
362
     * @return string
363
     * @throws ErrorException
364
     */
365
    public function getPreviewWebPath(int $width = 0, bool $webp = false)
366
    {
367
        if (!file_exists($this->getRootPath()))
368
            return null;
369
370
        if (!$this->isVideo() && !$this->isImage())
371
            throw new ErrorException('Requiested file is not an image and its implsible to resize it.');
372
373
        if (Yii::$app->getModule('files')->hostStatic)
374
            return
375
                Yii::$app->getModule('files')->hostStatic .
0 ignored issues
show
Bug introduced by
Are you sure Yii::app->getModule('files')->hostStatic of type mixed|null|object can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

375
                /** @scrutinizer ignore-type */ Yii::$app->getModule('files')->hostStatic .
Loading history...
376
                $this->makeNameWithSize($this->filename, $width, $webp) .
377
                "?hash={$this->hash}&width={$width}&webp=" . intval($webp);
378
379
        return Url::toRoute(['/files/default/image', 'hash' => $this->hash, 'width' => $width, 'webp' => $webp]);
380
    }
381
382
    /**
383
     * @return bool
384
     */
385
    public function isVideo(): bool
386
    {
387
        return $this->type == FileType::VIDEO;
388
    }
389
390
    /**
391
     * Creates file paths to file versions
392
     * @param $name
393
     * @param int $width
394
     * @param bool $webp
395
     * @return string
396
     */
397
    public function makeNameWithSize($name, $width = 0, $webp = false)
398
    {
399
        $extension = pathinfo($this->rootPath, PATHINFO_EXTENSION);
400
        $rootPath = str_replace(".{$extension}", '', $name) . "_w" . $width . ".{$extension}";
401
        return str_replace($extension, $webp ? 'webp' : 'jpeg', $rootPath);
402
    }
403
404
    /**
405
     * Returns full path to custom preview version
406
     * @param int $width
407
     * @param bool $webp
408
     * @return string
409
     * @throws ErrorException
410
     */
411
    public function getPreviewRootPath($width = 0, $webp = false)
412
    {
413
        if (!$this->isVideo() && !$this->isImage())
414
            throw new ErrorException('Requiested file is not an image and its implsible to resize it.');
415
        return $this->makeNameWithSize($this->rootPath, $width, $webp);
416
    }
417
418
    /**
419
     * @return bool
420
     */
421
    public function isFile(): bool
422
    {
423
        return $this->type == FileType::FILE;
424
    }
425
426
}
427