-
-
Notifications
You must be signed in to change notification settings - Fork 161
/
MediaFactory.php
119 lines (92 loc) · 3.58 KB
/
MediaFactory.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
declare(strict_types=1);
namespace Bolt\Factory;
use Bolt\Configuration\Config;
use Bolt\Configuration\FileLocations;
use Bolt\Controller\UserTrait;
use Bolt\Entity\Media;
use Bolt\Repository\MediaRepository;
use Carbon\Carbon;
use PHPExif\Exif;
use PHPExif\Reader\Reader;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Tightenco\Collect\Support\Collection;
use Webmozart\PathUtil\Path;
class MediaFactory
{
use UserTrait;
/** @var MediaRepository */
private $mediaRepository;
/** @var Config */
private $config;
/** @var Reader */
private $exif;
/** @var Collection */
private $allowedFileTypes;
/** @var FileLocations */
private $fileLocations;
public function __construct(Config $config, FileLocations $fileLocations, MediaRepository $mediaRepository, TokenStorageInterface $tokenStorage)
{
$this->config = $config;
$this->mediaRepository = $mediaRepository;
$this->tokenStorage = $tokenStorage;
$this->exif = Reader::factory(Reader::TYPE_NATIVE);
$this->allowedFileTypes = $config->getMediaTypes()->merge($config->getFileTypes());
$this->fileLocations = $fileLocations;
}
public function createOrUpdateMedia(SplFileInfo $file, string $fileLocation, ?string $title = null): Media
{
$path = Path::makeRelative($file->getPath() . '/', $this->fileLocations->get($fileLocation)->getBasepath());
$media = $this->mediaRepository->findOneBy([
'location' => $fileLocation,
'path' => $path,
'filename' => $file->getFilename(),
]);
if ($media === null) {
$media = new Media();
$media->setFilename($file->getFilename())
->setPath($path)
->setLocation($fileLocation);
}
if ($this->allowedFileTypes->contains($file->getExtension()) === false) {
throw new UnsupportedMediaTypeHttpException("{$file->getExtension()} files are not accepted");
}
$media->setType($file->getExtension())
->setModifiedAt(Carbon::createFromTimestamp($file->getMTime()))
->setCreatedAt(Carbon::createFromTimestamp($file->getCTime()))
->setFilesize($file->getSize())
->setTitle($title ?? $file->getFilename())
->setAuthor($this->getUser());
if ($this->isImage($media)) {
$this->updateImageDimensions($media, $file);
}
return $media;
}
private function updateImageDimensions(Media $media, SplFileInfo $file): void
{
$exif = $this->exif->read($file->getRealPath());
if ($exif instanceof Exif) {
$media->setWidth($exif->getWidth())
->setHeight($exif->getHeight());
return;
}
$size = @getimagesize($file->getRealpath());
if ($size !== false) {
$media->setWidth($size[0])
->setHeight($size[1]);
return;
}
}
public function isImage(Media $media): bool
{
return in_array($media->getType(), ['gif', 'png', 'jpg', 'jpeg', 'svg', 'webp', 'avif'], true);
}
public function createFromFilename(string $locationName, string $path, string $filename): Media
{
$target = $this->config->getPath($locationName, true, [$path, $filename]);
$file = new SplFileInfo($target, $path, $filename);
return $this->createOrUpdateMedia($file, $locationName);
}
}