Completed
Push — feature/6.x ( db50a0...aa9894 )
by Schlaefer
03:28
created

UploadStorage::upload()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 16
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 25
rs 9.7333
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * Saito - The Threaded Web Forum
6
 *
7
 * @copyright Copyright (c) the Saito Project Developers
8
 * @link https://github.com/Schlaefer/Saito
9
 * @license http://opensource.org/licenses/MIT
10
 */
11
12
namespace ImageUploader\Lib;
13
14
use Cake\Core\Configure;
15
use ImageUploader\Model\Entity\Upload;
16
use League\Flysystem\FilesystemInterface;
17
use League\Flysystem\MountManager;
18
19
class UploadStorage
20
{
21
    /**
22
     * Filesystem where to store the uploads
23
     * @var \League\Flysystem\FilesystemInterface
24
     */
25
    protected FilesystemInterface $targetFilesystem;
26
27
    /**
28
     * Constructor
29
     * @param \League\Flysystem\FilesystemInterface $targetFilesystem Target file system
30
     * @return void
31
     */
32
    public function __construct(FilesystemInterface $targetFilesystem)
33
    {
34
        $this->targetFilesystem = $targetFilesystem;
35
    }
36
37
    /**
38
     * Process the upload: type conversion, copying to target filesystem, …
39
     * @param \ImageUploader\Model\Entity\Upload $entity Upload entity
40
     * @return void
41
     */
42
    public function upload(Upload $entity): void
43
    {
44
        $file = new File($entity->get('tmp_name'));
45
        if (!$file->exists()) {
46
            throw new \RuntimeException('Uploaded file not found.');
47
        }
48
49
        $mime = $file->getMime();
50
        switch ($mime) {
51
            case 'image/png':
52
                ImageProcessor::convertToJpeg($file->getPath());
53
                $this->changeExtention($entity, 'jpg');
54
                // fall through: png is further processed as jpeg
55
                // no break
56
            case 'image/jpeg':
57
                ImageProcessor::fixOrientation($file->getPath());
58
                /** @var \ImageUploader\Lib\UploaderConfig $UploaderConfig */
59
                $UploaderConfig = Configure::read('Saito.Settings.uploader');
60
                ImageProcessor::resize($file, $UploaderConfig->getMaxResize());
61
                break;
62
            default:
63
        }
64
65
        $this->updateMeta($file, $entity);
66
        $this->store($file, $entity);
67
    }
68
69
    /**
70
     * Move Upload to target file system
71
     * @param \ImageUploader\Lib\File $file file
72
     * @param \ImageUploader\Model\Entity\Upload $entity entity
73
     * @return void
74
     */
75
    protected function store(File $file, Upload $entity): void
76
    {
77
        try {
78
            $manager = new MountManager([
79
                'source' => $file->getFs(),
80
                'target' => $this->targetFilesystem,
81
            ]);
82
            $isCopied = $manager->copy(
83
                'source://' . $file->getBasename(),
84
                'target://' . $entity->get('name')
85
            );
86
            if (!$isCopied) {
87
                throw new \RuntimeException('Uploaded file could not be moved');
88
            }
89
        } catch (\Throwable $e) {
90
            if ($this->targetFilesystem->has($entity->get('name'))) {
91
                $this->targetFilesystem->delete($entity->get('name'));
92
            }
93
            throw $e;
94
        }
95
    }
96
97
    /**
98
     * Delete a file from storage
99
     * @param \ImageUploader\Model\Entity\Upload $entity UploadEntity
100
     * @return void
101
     */
102
    public function delete(Upload $entity): void
103
    {
104
        $file = new File($entity->get('name'), $this->targetFilesystem);
105
        if ($file->exists()) {
106
            $file->delete();
107
        }
108
    }
109
110
    /**
111
     * Change file extension on target file name
112
     * @param \ImageUploader\Model\Entity\Upload $entity Entity with target file name
113
     * @param string $ext New file extension
114
     * @return void
115
     */
116
    protected function changeExtention(Upload $entity, string $ext)
117
    {
118
        $newName = pathinfo($entity->get('name'))['filename'] . '.' . $ext;
119
        $entity->set('name', $newName);
120
    }
121
122
    /**
123
     * Update entity metadata from storage
124
     * @param \ImageUploader\Lib\File $file file
125
     * @param \ImageUploader\Model\Entity\Upload $entity Entity with target file name
126
     * @return void
127
     */
128
    protected function updateMeta(File $file, Upload $entity): void
129
    {
130
        $entity->set('type', $file->getMime());
131
        $entity->set('size', $file->getSize());
132
    }
133
}
134