mirror of
https://github.com/jbcr/core.git
synced 2026-04-02 14:22:22 +02:00
120 lines
3.5 KiB
PHP
120 lines
3.5 KiB
PHP
<?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 $mediaTypes;
|
|
|
|
/** @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->mediaTypes = $config->getMediaTypes();
|
|
$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->mediaTypes->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;
|
|
}
|
|
}
|
|
|
|
private function isImage(Media $media): bool
|
|
{
|
|
return in_array($media->getType(), ['gif', 'png', 'jpg', 'svg'], 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);
|
|
}
|
|
}
|