SaveProcessor::isPowerPoint()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Itstructure\MFU\Processors;
4
5
use Exception;
6
use Illuminate\Http\UploadedFile;
7
use Illuminate\Support\Str;
8
use Illuminate\Support\Facades\{
9
    Storage, Validator
10
};
11
use Itstructure\MFU\Classes\ThumbConfig;
12
use Itstructure\MFU\Helpers\{
13
    ImageHelper, ThumbHelper
14
};
15
16
/**
17
 * Class SaveProcessor
18
 * @package Itstructure\MFU\Processors
19
 * @author Andrey Girnik <[email protected]>
20
 */
21
abstract class SaveProcessor extends BaseProcessor
22
{
23
    const FILE_TYPE_IMAGE = 'image';
24
    const FILE_TYPE_AUDIO = 'audio';
25
    const FILE_TYPE_VIDEO = 'video';
26
    const FILE_TYPE_APP = 'application';
27
    const FILE_TYPE_APP_WORD = 'word';
28
    const FILE_TYPE_APP_EXCEL = 'excel';
29
    const FILE_TYPE_APP_VISIO = 'visio';
30
    const FILE_TYPE_APP_PPT = 'powerpoint';
31
    const FILE_TYPE_APP_PDF = 'pdf';
32
    const FILE_TYPE_TEXT = 'text';
33
    const FILE_TYPE_OTHER = 'other';
34
    const FILE_TYPE_THUMB = 'thumbnail';
35
36
    const THUMB_ALIAS_DEFAULT = 'default';
37
    const THUMB_ALIAS_ORIGINAL = 'original';
38
    const THUMB_ALIAS_SMALL = 'small';
39
    const THUMB_ALIAS_MEDIUM = 'medium';
40
    const THUMB_ALIAS_LARGE = 'large';
41
42
    const DIR_LENGTH_FIRST = 2;
43
    const DIR_LENGTH_SECOND = 4;
44
45
    const VISIBILITY_PUBLIC = 'public';
46
    const VISIBILITY_PRIVARE = 'private';
47
48
    public static $defaultBaseUploadDirectory = 'default';
49
50
    /************************* CONFIG ATTRIBUTES *************************/
51
    /**
52
     * @var string
53
     */
54
    protected $baseUrl;
55
56
    /**
57
     * @var bool
58
     */
59
    protected $renameFiles;
60
61
    /**
62
     * @var bool
63
     */
64
    protected $checkExtensionByFileType;
65
66
    /**
67
     * @var int
68
     */
69
    protected $maxFileSize;
70
71
    /**
72
     * @var array
73
     */
74
    protected $fileExtensions;
75
76
    /**
77
     * @var array
78
     */
79
    protected $thumbSizes;
80
81
    /**
82
     * @var string
83
     */
84
    protected $thumbFilenameTemplate;
85
86
    /**
87
     * @var array
88
     */
89
    protected $baseUploadDirectories = [];
90
91
    /**
92
     * @var array
93
     */
94
    protected $metaDataValidationRules = [];
95
96
    /**
97
     * @var array
98
     */
99
    protected $metaDataValidationMessageTranslations = [];
100
101
    /**
102
     * @var array
103
     */
104
    protected $metaDataValidationAttributeTranslations = [];
105
106
    /**
107
     * @var array
108
     */
109
    protected $fileValidationMessageTranslations = [];
110
111
    /**
112
     * @var array
113
     */
114
    protected $fileValidationAttributeTranslations = [];
115
116
    /**
117
     * @var string
118
     */
119
    protected $visibility;
120
121
122
    /************************* PROCESS ATTRIBUTES *************************/
123
    /**
124
     * @var array
125
     */
126
    protected $data = [];
127
128
    /**
129
     * @var UploadedFile
130
     */
131
    protected $file;
132
133
    /**
134
     * @var string
135
     */
136
    protected $outFileName;
137
138
    /**
139
     * @var string
140
     */
141
    protected $path;
142
143
144
    /************************* ABSTRACT METHODS ***************************/
145
    abstract protected function isFileRequired(): bool;
146
147
148
    /************************* CONFIG SETTERS *****************************/
149
    /**
150
     * @param string $baseUrl
151
     * @return $this
152
     */
153
    public function setBaseUrl(string $baseUrl)
154
    {
155
        $this->baseUrl = $baseUrl;
156
        return $this;
157
    }
158
159
    /**
160
     * @param bool $renameFiles
161
     * @return $this
162
     */
163
    public function setRenameFiles(bool $renameFiles)
164
    {
165
        $this->renameFiles = $renameFiles;
166
        return $this;
167
    }
168
169
    /**
170
     * @param bool $checkExtensionByFileType
171
     * @return $this
172
     */
173
    public function setCheckExtensionByFileType(bool $checkExtensionByFileType)
174
    {
175
        $this->checkExtensionByFileType = $checkExtensionByFileType;
176
        return $this;
177
    }
178
179
    /**
180
     * @param int $maxFileSize
181
     * @return $this
182
     */
183
    public function setMaxFileSize(int $maxFileSize)
184
    {
185
        $this->maxFileSize = $maxFileSize;
186
        return $this;
187
    }
188
189
    /**
190
     * @param array $fileExtensions
191
     * @return $this
192
     */
193
    public function setFileExtensions(array $fileExtensions)
194
    {
195
        $this->fileExtensions = $fileExtensions;
196
        return $this;
197
    }
198
199
    /**
200
     * @param array $thumbSizes
201
     * @return $this
202
     */
203
    public function setThumbSizes(array $thumbSizes)
204
    {
205
        $this->thumbSizes = $thumbSizes;
206
        return $this;
207
    }
208
209
    /**
210
     * @param string $thumbFilenameTemplate
211
     * @return $this
212
     */
213
    public function setThumbFilenameTemplate(string $thumbFilenameTemplate)
214
    {
215
        $this->thumbFilenameTemplate = $thumbFilenameTemplate;
216
        return $this;
217
    }
218
219
    /**
220
     * @param array $baseUploadDirectories
221
     * @return $this
222
     */
223
    public function setBaseUploadDirectories(array $baseUploadDirectories)
224
    {
225
        $this->baseUploadDirectories = $baseUploadDirectories;
226
        return $this;
227
    }
228
229
    /**
230
     * @param array $metaDataValidationRules
231
     * @return $this
232
     */
233
    public function setMetaDataValidationRules(array $metaDataValidationRules)
234
    {
235
        $this->metaDataValidationRules = $metaDataValidationRules;
236
        return $this;
237
    }
238
239
    /**
240
     * @param array $metaDataValidationMessageTranslations
241
     * @return $this
242
     */
243
    public function setMetaDataValidationMessageTranslations(array $metaDataValidationMessageTranslations)
244
    {
245
        $this->metaDataValidationMessageTranslations = $metaDataValidationMessageTranslations;
246
        return $this;
247
    }
248
249
    /**
250
     * @param array $metaDataValidationAttributeTranslations
251
     * @return $this
252
     */
253
    public function setMetaDataValidationAttributeTranslations(array $metaDataValidationAttributeTranslations)
254
    {
255
        $this->metaDataValidationAttributeTranslations = $metaDataValidationAttributeTranslations;
256
        return $this;
257
    }
258
259
    /**
260
     * @param array $fileValidationMessageTranslations
261
     * @return $this
262
     */
263
    public function setFileValidationMessageTranslations(array $fileValidationMessageTranslations)
264
    {
265
        $this->fileValidationMessageTranslations = $fileValidationMessageTranslations;
266
        return $this;
267
    }
268
269
    /**
270
     * @param array $fileValidationAttributeTranslations
271
     * @return $this
272
     */
273
    public function setFileValidationAttributeTranslations(array $fileValidationAttributeTranslations)
274
    {
275
        $this->fileValidationAttributeTranslations = $fileValidationAttributeTranslations;
276
        return $this;
277
    }
278
279
    /**
280
     * @param string $visibility
281
     * @return $this
282
     */
283
    public function setVisibility(string $visibility)
284
    {
285
        $this->visibility = $visibility;
286
        return $this;
287
    }
288
289
290
    /********************** PROCESS PUBLIC METHODS ***********************/
291
    /**
292
     * @throws Exception
293
     * @return bool
294
     */
295
    public function run(): bool
296
    {
297
        if (!$this->validate()) {
298
            return false;
299
        }
300
        return parent::run();
301
    }
302
303
    /**
304
     * @param array $data
305
     * @return $this
306
     */
307
    public function setData(array $data)
308
    {
309
        $this->data = $data;
310
        return $this;
311
    }
312
313
    /**
314
     * @param UploadedFile|null $file
315
     * @return $this
316
     */
317
    public function setFile(UploadedFile $file = null)
318
    {
319
        $this->file = $file;
320
        return $this;
321
    }
322
323
    /**
324
     * @return UploadedFile|null
325
     */
326
    public function getFile(): ?UploadedFile
327
    {
328
        return $this->file;
329
    }
330
331
    /**
332
     * @throws Exception
333
     * @return bool
334
     */
335
    public function createThumbs(): bool
336
    {
337
        $thumbs = [];
338
339
        ImageHelper::$driver = [ImageHelper::DRIVER_GD2, ImageHelper::DRIVER_GMAGICK, ImageHelper::DRIVER_IMAGICK];
340
341
        foreach ($this->thumbSizes as $alias => $preset) {
342
            $thumbs[$alias] = $this->createThumb(ThumbHelper::configureThumb($alias, $preset));
343
        }
344
345
        // Create default thumb.
346
        if (!array_key_exists(self::THUMB_ALIAS_DEFAULT, $this->thumbSizes)) {
347
            $defaultThumbConfig = ThumbHelper::configureThumb(self::THUMB_ALIAS_DEFAULT, ThumbHelper::getDefaultSizes());
348
            $thumbs[self::THUMB_ALIAS_DEFAULT] = $this->createThumb($defaultThumbConfig);
349
        }
350
351
        $this->mediafileModel->thumbs = $thumbs;
352
353
        return $this->mediafileModel->save();
354
    }
355
356
    /**
357
     * @param string $mimeType
358
     * @return bool
359
     */
360
    public static function isImage(string $mimeType): bool
361
    {
362
        return strpos($mimeType, self::FILE_TYPE_IMAGE) !== false;
363
    }
364
365
    /**
366
     * @param string $mimeType
367
     * @return bool
368
     */
369
    public static function isAudio(string $mimeType): bool
370
    {
371
        return strpos($mimeType, self::FILE_TYPE_AUDIO) !== false;
372
    }
373
374
    /**
375
     * @param string $mimeType
376
     * @return bool
377
     */
378
    public static function isVideo(string $mimeType): bool
379
    {
380
        return strpos($mimeType, self::FILE_TYPE_VIDEO) !== false;
381
    }
382
383
    /**
384
     * @param string $mimeType
385
     * @return bool
386
     */
387
    public static function isText(string $mimeType): bool
388
    {
389
        return strpos($mimeType, self::FILE_TYPE_TEXT) !== false;
390
    }
391
392
    /**
393
     * @param string $mimeType
394
     * @return bool
395
     */
396
    public static function isApp(string $mimeType): bool
397
    {
398
        return strpos($mimeType, self::FILE_TYPE_APP) !== false;
399
    }
400
401
    /**
402
     * @param string $mimeType
403
     * @return bool
404
     */
405
    public static function isWord(string $mimeType): bool
406
    {
407
        return strpos($mimeType, self::FILE_TYPE_APP_WORD) !== false;
408
    }
409
410
    /**
411
     * @param string $mimeType
412
     * @return bool
413
     */
414
    public static function isExcel(string $mimeType): bool
415
    {
416
        return strpos($mimeType, self::FILE_TYPE_APP_EXCEL) !== false
417
        || strpos($mimeType, 'spreadsheet') !== false;
418
    }
419
420
    /**
421
     * @param string $mimeType
422
     * @return bool
423
     */
424
    public static function isVisio(string $mimeType): bool
425
    {
426
        return strpos($mimeType, self::FILE_TYPE_APP_VISIO) !== false;
427
    }
428
429
    /**
430
     * @param string $mimeType
431
     * @return bool
432
     */
433
    public static function isPowerPoint(string $mimeType): bool
434
    {
435
        return strpos($mimeType, self::FILE_TYPE_APP_PPT) !== false
436
        || strpos($mimeType, 'presentation') !== false;
437
    }
438
439
    /**
440
     * @param string $mimeType
441
     * @return bool
442
     */
443
    public static function isPdf(string $mimeType): bool
444
    {
445
        return strpos($mimeType, self::FILE_TYPE_APP_PDF) !== false;
446
    }
447
448
449
    /********************** PROCESS INTERNAL METHODS *********************/
450
    /**
451
     * @return bool
452
     */
453
    protected function validate(): bool
454
    {
455
        $resultMetaData = $this->validateMetaData();
456
        $resultFile = $this->validateFile();
457
        return $resultMetaData && $resultFile;
458
    }
459
460
    protected function validateMetaData(): bool
461
    {
462
        $metaDataValidator = Validator::make(
463
            $this->data,
464
            $this->metaDataValidationRules,
465
            $this->prepareValidationTranslations($this->metaDataValidationMessageTranslations),
466
            $this->prepareValidationTranslations($this->metaDataValidationAttributeTranslations)
467
        );
468
        if ($this->checkExtensionByFileType) {
469
            $metaDataValidator->addRules(['needed_file_type' => 'required']);
470
        }
471
        if ($metaDataValidator->fails()) {
472
            $this->errors = !is_null($this->errors)
473
                ? $this->errors->merge($metaDataValidator->getMessageBag())
474
                : $metaDataValidator->getMessageBag();
475
            return false;
476
        }
477
        return true;
478
    }
479
480
    protected function validateFile(): bool
481
    {
482
        $fileValidator = Validator::make(['file' => $this->file], [
483
                'file' => [
484
                    $this->isFileRequired() ? 'required' : 'nullable',
485
                    'max:' . $this->maxFileSize
486
                ]
487
            ],
488
            $this->prepareValidationTranslations($this->fileValidationMessageTranslations),
489
            $this->prepareValidationTranslations($this->fileValidationAttributeTranslations)
490
        );
491
        if ($this->checkExtensionByFileType && !empty($this->data['needed_file_type'])
492
            && !empty($this->fileExtensions[$this->data['needed_file_type']])) {
493
            $fileValidator->addRules([
494
                'file' => [
495
                    'mimes:' . implode(',', $this->fileExtensions[$this->data['needed_file_type']]),
496
                ]
497
            ]);
498
        }
499
        if ($fileValidator->fails()) {
500
            $this->errors = !is_null($this->errors)
501
                ? $this->errors->merge($fileValidator->getMessageBag())
502
                : $fileValidator->getMessageBag();
503
            return false;
504
        }
505
        return true;
506
    }
507
508
    protected function prepareValidationTranslations(array $translations): array
509
    {
510
        foreach ($translations as $key => $value) {
511
            $translations[$key] = __($value);
512
        }
513
        return $translations;
514
    }
515
516
517
    /**
518
     * @return bool
519
     */
520
    protected function sendFile(): bool
521
    {
522
        Storage::disk($this->currentDisk)->putFileAs($this->processDirectory, $this->file, $this->outFileName, [
523
            'visibility' => $this->data['visibility'] ?? $this->visibility
524
        ]);
525
526
        return Storage::disk($this->currentDisk)->fileExists($this->processDirectory . '/' . $this->outFileName);
0 ignored issues
show
Bug introduced by
The method fileExists() does not exist on Illuminate\Contracts\Filesystem\Filesystem. It seems like you code against a sub-type of Illuminate\Contracts\Filesystem\Filesystem such as Illuminate\Filesystem\FilesystemAdapter. ( Ignorable by Annotation )

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

526
        return Storage::disk($this->currentDisk)->/** @scrutinizer ignore-call */ fileExists($this->processDirectory . '/' . $this->outFileName);
Loading history...
527
    }
528
529
    /**
530
     * @param string|null $mimeType
531
     * @throws Exception
532
     * @return string
533
     */
534
    protected function getBaseUploadDirectory(?string $mimeType): string
535
    {
536
        if (empty($mimeType)) {
537
            throw new Exception('The mimeType attribute is empty.');
538
        }
539
540
        if (empty($this->baseUploadDirectories)) {
541
            throw new Exception('The baseUploadDirectories attribute is not defined correctly.');
542
        }
543
544
        if (self::isImage($mimeType)) {
545
            return $this->baseUploadDirectories[self::FILE_TYPE_IMAGE] ?? static::$defaultBaseUploadDirectory;
546
547
        } elseif (self::isAudio($mimeType)) {
548
            return $this->baseUploadDirectories[self::FILE_TYPE_AUDIO] ?? static::$defaultBaseUploadDirectory;
549
550
        } elseif (self::isVideo($mimeType)) {
551
            return $this->baseUploadDirectories[self::FILE_TYPE_VIDEO] ?? static::$defaultBaseUploadDirectory;
552
553
        } elseif (self::isApp($mimeType)) {
554
            if (self::isWord($mimeType)) {
555
                return $this->baseUploadDirectories[self::FILE_TYPE_APP_WORD] ?? static::$defaultBaseUploadDirectory;
556
557
            } elseif (self::isExcel($mimeType)) {
558
                return $this->baseUploadDirectories[self::FILE_TYPE_APP_EXCEL] ?? static::$defaultBaseUploadDirectory;
559
560
            } elseif (self::isVisio($mimeType)) {
561
                return $this->baseUploadDirectories[self::FILE_TYPE_APP_VISIO] ?? static::$defaultBaseUploadDirectory;
562
563
            } elseif (self::isPowerPoint($mimeType)) {
564
                return $this->baseUploadDirectories[self::FILE_TYPE_APP_PPT] ?? static::$defaultBaseUploadDirectory;
565
566
            } elseif (self::isPdf($mimeType)) {
567
                return $this->baseUploadDirectories[self::FILE_TYPE_APP_PDF] ?? static::$defaultBaseUploadDirectory;
568
569
            } else {
570
                return $this->baseUploadDirectories[self::FILE_TYPE_APP] ?? static::$defaultBaseUploadDirectory;
571
            }
572
573
        } elseif (self::isText($mimeType)) {
574
            return $this->baseUploadDirectories[self::FILE_TYPE_TEXT] ?? static::$defaultBaseUploadDirectory;
575
576
        } else {
577
            return $this->baseUploadDirectories[self::FILE_TYPE_OTHER] ?? static::$defaultBaseUploadDirectory;
578
        }
579
    }
580
581
    /**
582
     * @return string
583
     * @throws Exception
584
     */
585
    protected function getNewProcessDirectory(): string
586
    {
587
        $processDirectory = rtrim(rtrim($this->getBaseUploadDirectory($this->file->getMimeType()), '/'), '\\');
588
589
        if (!empty($this->data['sub_dir'])) {
590
            $processDirectory .= '/' . trim(trim($this->data['sub_dir'], '/'), '\\');
591
        }
592
593
        return $processDirectory .
594
            '/' . substr(md5(time()), 0, self::DIR_LENGTH_FIRST) .
595
            '/' . substr(md5(microtime() . $this->file->getBasename()), 0, self::DIR_LENGTH_SECOND);
596
    }
597
598
    /**
599
     * @return string
600
     */
601
    protected function getNewOutFileName(): string
602
    {
603
        return $this->renameFiles ?
604
            Str::uuid()->toString() . '.' . $this->file->extension() :
605
            Str::slug($this->file->getClientOriginalName(), '.');
606
    }
607
608
    /**
609
     * @param ThumbConfig $thumbConfig
610
     * @return string
611
     */
612
    protected function createThumb(ThumbConfig $thumbConfig)
613
    {
614
        $originalPathInfo = pathinfo($this->mediafileModel->getPath());
615
616
        $thumbPath = $originalPathInfo['dirname'] .
617
            '/' .
618
            $this->getThumbFilename($originalPathInfo['filename'],
619
                $originalPathInfo['extension'],
620
                $thumbConfig->getAlias(),
621
                $thumbConfig->getWidth(),
622
                $thumbConfig->getHeight()
623
            );
624
625
        $thumbContent = ImageHelper::thumbnail(
626
            ImageHelper::getImagine()->load(Storage::disk($this->currentDisk)->get($this->mediafileModel->getPath())),
627
            $thumbConfig->getWidth(),
628
            $thumbConfig->getHeight(),
629
            $thumbConfig->getMode()
630
        )->get($originalPathInfo['extension']);
631
632
        Storage::disk($this->currentDisk)->put($thumbPath, $thumbContent);
633
634
        return $thumbPath;
635
    }
636
637
    /**
638
     * @param $original
639
     * @param $extension
640
     * @param $alias
641
     * @param $width
642
     * @param $height
643
     * @return string
644
     */
645
    protected function getThumbFilename($original, $extension, $alias, $width, $height)
646
    {
647
        return strtr($this->thumbFilenameTemplate, [
648
            '{original}' => $original,
649
            '{extension}' => $extension,
650
            '{alias}' => $alias,
651
            '{width}' => $width,
652
            '{height}' => $height,
653
        ]);
654
    }
655
656
    protected function setMediafileBaseData(): void
657
    {
658
        $this->mediafileModel->path = $this->path;
659
        $this->mediafileModel->file_name = $this->outFileName;
660
        $this->mediafileModel->size = $this->file->getSize();
661
        $this->mediafileModel->mime_type = $this->file->getMimeType();
662
        $this->mediafileModel->disk = $this->currentDisk;
663
    }
664
665
    protected function setMediafileMetaData(): void
666
    {
667
        $this->mediafileModel->alt = $this->data['alt'] ?? '';
668
        $this->mediafileModel->title = $this->data['title'] ?? '';
669
        $this->mediafileModel->description = $this->data['description'] ?? '';
670
    }
671
}
672