zend-blog-3-backend

Форк
0
/
ImageManager.php 
204 строки · 5.0 Кб
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: morontt
5
 * Date: 03.04.16
6
 * Time: 23:17
7
 */
8

9
namespace App\Service;
10

11
use App\Entity\MediaFile;
12
use App\Entity\Post;
13
use App\Model\Image;
14
use Doctrine\ORM\EntityManager;
15
use Doctrine\ORM\EntityManagerInterface;
16
use Symfony\Component\Filesystem\Filesystem;
17
use Symfony\Component\HttpFoundation\File\UploadedFile;
18
use Symfony\Component\Process\Exception\ProcessFailedException;
19
use Symfony\Component\Process\Process;
20

21
class ImageManager
22
{
23
    /**
24
     * @var EntityManager
25
     */
26
    protected $em;
27

28
    private string $imageBasepath;
29

30
    /**
31
     * @param EntityManagerInterface $em
32
     * @param string $cdnUrl
33
     */
34
    public function __construct(EntityManagerInterface $em, string $cdnUrl)
35
    {
36
        $this->em = $em;
37
        $this->imageBasepath = $cdnUrl . self::getImageBasePath() . '/';
38
    }
39

40
    /**
41
     * @param $description
42
     * @param $postId
43
     * @param UploadedFile $file
44
     *
45
     * @throws \Doctrine\ORM\Exception\NotSupported
46
     * @throws \Doctrine\ORM\Exception\ORMException
47
     */
48
    public function uploadImage($description, $postId, UploadedFile $file): void
49
    {
50
        $fileName = $file->getClientOriginalName();
51
        $file->move($this->getTempDirectory(), $fileName);
52

53
        $localPath = $this->getTempDirectory() . '/' . $fileName;
54
        $this->preprocessing($localPath);
55

56
        $remotePath = $this->getPrefixPath() . $fileName;
57
        $size = filesize($localPath);
58

59
        $fs = new Filesystem();
60
        $fs->copy(
61
            $localPath,
62
            static::getUploadsDir() . '/' . $remotePath,
63
            true
64
        );
65

66
        $media = $this->getMediaFile($remotePath);
67
        $media
68
            ->setDescription($description ?: null)
69
            ->setFileSize($size)
70
        ;
71

72
        if ($postId) {
73
            $post = $this->em->getRepository(Post::class)->find((int)$postId);
74
            if ($post) {
75
                $media->setPost($post);
76
                if ($this->em->getRepository(MediaFile::class)->getCountByPostId($postId) === 0) {
77
                    $media->setDefaultImage(true);
78
                }
79
            }
80
        }
81

82
        if ($media->isImage()) {
83
            $image = new Image($media);
84
            $geometry = $image->getImageGeometry();
85
            $media
86
                ->setWidth($geometry->width)
87
                ->setHeight($geometry->height)
88
            ;
89
        }
90

91
        $this->em->persist($media);
92
        $this->em->flush();
93

94
        unlink($localPath);
95
    }
96

97
    /**
98
     * @param MediaFile $entity
99
     *
100
     * @throws \Doctrine\ORM\Exception\ORMException
101
     *
102
     * @return void
103
     */
104
    public function remove(MediaFile $entity): void
105
    {
106
        $this->removeAllPreview($entity);
107

108
        $fs = new Filesystem();
109
        $fs->remove(static::getUploadsDir() . '/' . $entity->getPath());
110

111
        $this->em->remove($entity);
112
        $this->em->flush();
113
    }
114

115
    public function removeAllPreview(MediaFile $entity)
116
    {
117
        $pathInfo = pathinfo(static::getUploadsDir() . '/' . $entity->getPath());
118
        $directory = $pathInfo['dirname'];
119
        $baseName = $pathInfo['basename'];
120

121
        $fs = new Filesystem();
122
        foreach (scandir($directory) as $file) {
123
            if ($file === '.' || $file === '..') {
124
                continue;
125
            }
126

127
            if ($file !== $baseName
128
                && preg_match('/(?:^\d+_\d+_)?' . $pathInfo['filename'] . '(?:_\d+(?:w|h))?\./', $file)
129
            ) {
130
                $fs->remove($directory . '/' . $file);
131
            }
132
        }
133
    }
134

135
    /**
136
     * @return string
137
     */
138
    public static function getUploadsDir(): string
139
    {
140
        return '/var/www/resources' . static::getImageBasePath();
141
    }
142

143
    /**
144
     * @return string
145
     */
146
    public static function getImageBasePath(): string
147
    {
148
        return '/uploads';
149
    }
150

151
    public function cdnImagePath(): string
152
    {
153
        return $this->imageBasepath;
154
    }
155

156
    /**
157
     * @param string $path
158
     */
159
    protected function preprocessing($path)
160
    {
161
        if (strtolower(pathinfo($path, PATHINFO_EXTENSION)) === 'png') {
162
            $process = new Process('/usr/bin/pngquant -s1 --quality=60-80 --ext .png -f ' . escapeshellarg($path));
163
            $process->run();
164

165
            if (!$process->isSuccessful()) {
166
                throw new ProcessFailedException($process);
167
            }
168
        }
169
    }
170

171
    /**
172
     * @param string $remotePath
173
     *
174
     * @return MediaFile
175
     */
176
    protected function getMediaFile($remotePath)
177
    {
178
        $media = $this->em->getRepository(MediaFile::class)->findOneBy(['path' => $remotePath]);
179
        if ($media) {
180
            $media->setLastUpdate(new \DateTime());
181
        } else {
182
            $media = new MediaFile();
183
            $media->setPath($remotePath);
184
        }
185

186
        return $media;
187
    }
188

189
    /**
190
     * @return mixed
191
     */
192
    protected function getPrefixPath()
193
    {
194
        return sprintf('blog/%s/', (new \DateTime())->format('Y/m'));
195
    }
196

197
    /**
198
     * @return mixed
199
     */
200
    protected function getTempDirectory()
201
    {
202
        return APP_VAR_DIR . '/tmp';
203
    }
204
}
205

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.