Passed
Push — master ( a7c195...d7c0fa )
by Evgenii
04:18
created

src/models/File.php (1 issue)

Labels
Severity
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 $href
35
 * @property string $icon
36
 * @property string $rootPath
37
 * @property string|null $watermark
38
 */
39
class File extends ActiveRecord
40
{
41
    const DIRECTORY_SEPARATOR = "/";
42
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public static function getDb()
48
    {
49
        return Yii::$app->getModule('files')->db;
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55
56
    public static function tableName()
57
    {
58
        return '{{%file}}';
59
    }
60
61
    /**
62
     * Create hash if its empty
63
     * @param bool $insert
64
     * @return bool
65
     */
66
    public function beforeSave($insert)
67
    {
68
        if (!$this->hash) {
69
            $this->changeHash();
70
        }
71
        return parent::beforeSave($insert);
72
    }
73
74
    /**
75
     * Change object hash
76
     */
77
    public function changeHash()
78
    {
79
        $this->hash = md5(time() . rand(99999, 99999999));
80
81
    }
82
83
    /**
84
     * @return string
85
     */
86
    public function getIcon()
87
    {
88
        $icon = IconHelper::FILE;
89
90
        if ($this->content_type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')
91
            $icon = IconHelper::FILE_WORD;
92
93
        if ($this->content_type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
94
            $icon = IconHelper::FILE_EXCEL;
95
96
        if ($this->content_type == 'application/vnd.openxmlformats-officedocument.presentationml.presentation')
97
            $icon = IconHelper::FILE_POWERPOINT;
98
99
        if ($this->content_type == 'application/x-zip-compressed')
100
            $icon = IconHelper::FILE_ARCHIVE;
101
102
        if ($this->content_type == 'application/octet-stream')
103
            $icon = IconHelper::FILE_ARCHIVE;
104
105
        if (preg_match('/audio/', $this->content_type))
106
            $icon = IconHelper::FILE_AUDIO;
107
108
        if (preg_match('/pdf/', $this->content_type))
109
            $icon = IconHelper::FILE_PDF;
110
111
        if ($this->type == FileType::VIDEO)
112
            $icon = IconHelper::FILE_VIDEO;
113
114
        return $icon;
115
    }
116
117
    function mime_content_type($filename)
118
    {
119
        $idx = explode('.', $filename);
120
        $count_explode = count($idx);
121
        $idx = strtolower($idx[$count_explode - 1]);
122
123
        $mimet = array(
124
            'txt' => 'text/plain',
125
            'htm' => 'text/html',
126
            'html' => 'text/html',
127
            'php' => 'text/html',
128
            'css' => 'text/css',
129
            'js' => 'application/javascript',
130
            'json' => 'application/json',
131
            'xml' => 'application/xml',
132
            'swf' => 'application/x-shockwave-flash',
133
            'flv' => 'video/x-flv',
134
135
            // images
136
            'png' => 'image/png',
137
            'jpe' => 'image/jpeg',
138
            'jpeg' => 'image/jpeg',
139
            'jpg' => 'image/jpeg',
140
            'gif' => 'image/gif',
141
            'bmp' => 'image/bmp',
142
            'ico' => 'image/vnd.microsoft.icon',
143
            'tiff' => 'image/tiff',
144
            'tif' => 'image/tiff',
145
            'svg' => 'image/svg+xml',
146
            'svgz' => 'image/svg+xml',
147
148
            // archives
149
            'zip' => 'application/zip',
150
            'rar' => 'application/x-rar-compressed',
151
            'exe' => 'application/x-msdownload',
152
            'msi' => 'application/x-msdownload',
153
            'cab' => 'application/vnd.ms-cab-compressed',
154
155
            // audio/video
156
            'mp3' => 'audio/mpeg',
157
            'qt' => 'video/quicktime',
158
            'mov' => 'video/quicktime',
159
160
            // adobe
161
            'pdf' => 'application/pdf',
162
            'psd' => 'image/vnd.adobe.photoshop',
163
            'ai' => 'application/postscript',
164
            'eps' => 'application/postscript',
165
            'ps' => 'application/postscript',
166
167
            // ms office
168
            'doc' => 'application/msword',
169
            'rtf' => 'application/rtf',
170
            'xls' => 'application/vnd.ms-excel',
171
            'ppt' => 'application/vnd.ms-powerpoint',
172
            'docx' => 'application/msword',
173
            'xlsx' => 'application/vnd.ms-excel',
174
            'pptx' => 'application/vnd.ms-powerpoint',
175
176
177
            // open office
178
            'odt' => 'application/vnd.oasis.opendocument.text',
179
            'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
180
        );
181
182
        if (isset($mimet[$idx])) {
183
            return $mimet[$idx];
184
        } else {
185
            return 'application/octet-stream';
186
        }
187
    }
188
189
    /**
190
     * @inheritdoc
191
     */
192
193
    public function rules()
194
    {
195
        return [
196
            [['class', 'field', 'filename', 'content_type', 'type'], 'required'],
197
            [['object_id', 'type', 'video_status', 'ordering'], 'integer'],
198
            [['class', 'field', 'title', 'filename', 'content_type'], 'string', 'max' => 255],
199
        ];
200
    }
201
202
    /**
203
     * @inheritdoc
204
     */
205
206
    public function attributeLabels()
207
    {
208
        return [
209
            'id' => Yii::t('app', 'ID'),
210
            'class' => Yii::t('app', 'Class'),
211
            'field' => Yii::t('app', 'Field'),
212
            'object_id' => Yii::t('app', 'Object ID'),
213
            'title' => Yii::t('app', 'Title'),
214
            'filename' => Yii::t('app', 'Filename'),
215
            'content_type' => Yii::t('app', 'Con tent Type'),
216
            'type' => Yii::t('app', 'Type'),
217
            'video_status' => Yii::t('app', 'Video Status'),
218
        ];
219
    }
220
221
    /**
222
     * Return root path of preview
223
     * @return string
224
     */
225
226
    public function getRootPreviewPath()
227
    {
228
        if ($this->isSvg())
229
            return $this->getRootPath();
230
231
        return Yii::$app->getModule('files')->storageFullPath . $this->filename . '.jpg';
232
    }
233
234
    /**
235
     * @return bool
236
     */
237
    public function isSvg()
238
    {
239
        return $this->content_type == 'image/svg+xml';
240
    }
241
242
    /**
243
     * Return root path of image
244
     * @return string
245
     */
246
247
    public function getRootPath()
248
    {
249
        return Yii::$app->getModule('files')->storageFullPath . DIRECTORY_SEPARATOR . $this->filename;
250
    }
251
252
253
    /**
254
     * Return web path
255
     * @return string
256
     */
257
258
    public function getHref()
259
    {
260
        if ($this->isImage() && Yii::$app->getModule('files')->hostStatic)
261
            return Yii::$app->getModule('files')->hostStatic . $this->filename . "?hash={$this->hash}";
0 ignored issues
show
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

261
            return /** @scrutinizer ignore-type */ Yii::$app->getModule('files')->hostStatic . $this->filename . "?hash={$this->hash}";
Loading history...
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
        if (
342
            isset($this->behaviors['files']) &&
343
            isset($this->behaviors['files']->attributes[$this->field]) &&
344
            isset($this->behaviors['files']->attributes[$this->field]['watermark'])
345
        )
346
            return $this->behaviors['files']->attributes[$this->field]['watermark'];
347
    }
348
349
    /**
350
     * @return string
351
     */
352
    public function __toString()
353
    {
354
        return $this->href;
355
    }
356
357
    /**
358
     * Return webp path to preview
359
     * @param int $width
360
     * @param bool $webp
361
     * @return string
362
     * @throws ErrorException
363
     */
364
    public function getPreviewWebPath(int $width = 0, bool $webp = false)
365
    {
366
        if (!file_exists($this->getRootPath()))
367
            return null;
368
369
        if (!$this->isVideo() && !$this->isImage())
370
            throw new ErrorException('Requiested file is not an image and its implsible to resize it.');
371
372
        if (Yii::$app->getModule('files')->hostStatic)
373
            return
374
                Yii::$app->getModule('files')->hostStatic .
375
                $this->makeNameWithSize($this->filename, $width, $webp) .
376
                "?hash={$this->hash}&width={$width}&webp=" . intval($webp);
377
378
        return Url::toRoute(['/files/default/image', 'hash' => $this->hash, 'width' => $width, 'webp' => $webp]);
379
    }
380
381
    /**
382
     * @return bool
383
     */
384
    public function isVideo(): bool
385
    {
386
        return $this->type == FileType::VIDEO;
387
    }
388
389
    /**
390
     * Creates file paths to file versions
391
     * @param $name
392
     * @param int $width
393
     * @param bool $webp
394
     * @return string
395
     */
396
    public function makeNameWithSize($name, $width = 0, $webp = false)
397
    {
398
        $extension = pathinfo($this->rootPath, PATHINFO_EXTENSION);
399
        $rootPath = str_replace(".{$extension}", '', $name) . "_w" . $width . ".{$extension}";
400
        return str_replace($extension, $webp ? 'webp' : 'jpeg', $rootPath);
401
    }
402
403
    /**
404
     * Returns full path to custom preview version
405
     * @param int $width
406
     * @param bool $webp
407
     * @return string
408
     * @throws ErrorException
409
     */
410
    public function getPreviewRootPath($width = 0, $webp = false)
411
    {
412
        if (!$this->isVideo() && !$this->isImage())
413
            throw new ErrorException('Requiested file is not an image and its implsible to resize it.');
414
        return $this->makeNameWithSize($this->rootPath, $width, $webp);
415
    }
416
417
    /**
418
     * @return bool
419
     */
420
    public function isFile(): bool
421
    {
422
        return $this->type == FileType::FILE;
423
    }
424
425
}
426