zend-blog-3-backend
204 строки · 5.0 Кб
1<?php
2/**
3* Created by PhpStorm.
4* User: morontt
5* Date: 03.04.16
6* Time: 23:17
7*/
8
9namespace App\Service;
10
11use App\Entity\MediaFile;
12use App\Entity\Post;
13use App\Model\Image;
14use Doctrine\ORM\EntityManager;
15use Doctrine\ORM\EntityManagerInterface;
16use Symfony\Component\Filesystem\Filesystem;
17use Symfony\Component\HttpFoundation\File\UploadedFile;
18use Symfony\Component\Process\Exception\ProcessFailedException;
19use Symfony\Component\Process\Process;
20
21class ImageManager
22{
23/**
24* @var EntityManager
25*/
26protected $em;
27
28private string $imageBasepath;
29
30/**
31* @param EntityManagerInterface $em
32* @param string $cdnUrl
33*/
34public 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*/
48public 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,
62static::getUploadsDir() . '/' . $remotePath,
63true
64);
65
66$media = $this->getMediaFile($remotePath);
67$media
68->setDescription($description ?: null)
69->setFileSize($size)
70;
71
72if ($postId) {
73$post = $this->em->getRepository(Post::class)->find((int)$postId);
74if ($post) {
75$media->setPost($post);
76if ($this->em->getRepository(MediaFile::class)->getCountByPostId($postId) === 0) {
77$media->setDefaultImage(true);
78}
79}
80}
81
82if ($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
94unlink($localPath);
95}
96
97/**
98* @param MediaFile $entity
99*
100* @throws \Doctrine\ORM\Exception\ORMException
101*
102* @return void
103*/
104public 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
115public 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();
122foreach (scandir($directory) as $file) {
123if ($file === '.' || $file === '..') {
124continue;
125}
126
127if ($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*/
138public static function getUploadsDir(): string
139{
140return '/var/www/resources' . static::getImageBasePath();
141}
142
143/**
144* @return string
145*/
146public static function getImageBasePath(): string
147{
148return '/uploads';
149}
150
151public function cdnImagePath(): string
152{
153return $this->imageBasepath;
154}
155
156/**
157* @param string $path
158*/
159protected function preprocessing($path)
160{
161if (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
165if (!$process->isSuccessful()) {
166throw new ProcessFailedException($process);
167}
168}
169}
170
171/**
172* @param string $remotePath
173*
174* @return MediaFile
175*/
176protected function getMediaFile($remotePath)
177{
178$media = $this->em->getRepository(MediaFile::class)->findOneBy(['path' => $remotePath]);
179if ($media) {
180$media->setLastUpdate(new \DateTime());
181} else {
182$media = new MediaFile();
183$media->setPath($remotePath);
184}
185
186return $media;
187}
188
189/**
190* @return mixed
191*/
192protected function getPrefixPath()
193{
194return sprintf('blog/%s/', (new \DateTime())->format('Y/m'));
195}
196
197/**
198* @return mixed
199*/
200protected function getTempDirectory()
201{
202return APP_VAR_DIR . '/tmp';
203}
204}
205