<?php
/*
* This file is part of the adrec-platform package.
*
* (c) Benjamin Georgeault <https://www.pressop.eu>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\EventSubscriber\Channel;
use App\Entity\Channel\Channel;
use App\Entity\Channel\Image;
use App\Entity\Account\User;
use App\Enum\ChannelUserResourcePermission\ChannelUserAsyncPermissionEnum;
use App\Repository\Channel\ChannelRepository;
use Doctrine\ORM\EntityManagerInterface;
use Oneup\UploaderBundle\Event\PostPersistEvent;
use Oneup\UploaderBundle\Event\PreUploadEvent;
use Oneup\UploaderBundle\UploadEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
/**
* Class ImageUploaderSubscriber
*
* @author Benjamin Georgeault
*/
class ImageUploaderSubscriber implements EventSubscriberInterface
{
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var TokenStorageInterface
*/
private $token;
/**
* @var AuthorizationCheckerInterface
*/
private $authorizationChecker;
public function __construct(EntityManagerInterface $em, TokenStorageInterface $token, AuthorizationCheckerInterface $authorizationChecker)
{
$this->em = $em;
$this->token = $token;
$this->authorizationChecker = $authorizationChecker;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
UploadEvents::PRE_UPLOAD.'.channel_images' => 'onPreUpload',
UploadEvents::POST_PERSIST.'.channel_images' => 'onFinishedUpload',
];
}
/**
* @param PreUploadEvent $event
*/
public function onPreUpload(PreUploadEvent $event)
{
if (null === $this->getUser()) {
throw new AccessDeniedHttpException();
}
}
/**
* @param PostPersistEvent $event
*/
public function onFinishedUpload(PostPersistEvent $event)
{
/** @var \Oneup\UploaderBundle\Uploader\File\FileInterface $file */
$file = $event->getFile();
$request = $event->getRequest();
if (null === $user = $this->getUser()) {
throw new AccessDeniedHttpException();
}
if (!$request->headers->has('x-channel-id')) {
throw new BadRequestHttpException();
}
/** @var ChannelRepository $channelRepo */
$channelRepo = $this->em->getRepository(Channel::class);
if (null === $channel = $channelRepo->find($request->headers->get('x-channel-id'))) {
throw new NotFoundHttpException();
}
if (!$this->authorizationChecker->isGranted(ChannelUserAsyncPermissionEnum::CHANNEL_USER_PERM_ASYNC_UPLOAD_FILES, $channel)) {
throw new AccessDeniedHttpException();
}
$image = (new Image())
->setName(pathinfo($file->getBasename(), PATHINFO_FILENAME))
->setExtension($file->getExtension())
->setTitle(substr($request->request->get('qqfilename', 'IMG'), 0, 63))
->setOwnerChannel($channel)
;
$this->em->persist($image);
$this->em->flush();
}
/**
* @return User|null
*/
private function getUser(): ?User
{
if (null === $token = $this->token->getToken()) {
return null;
}
if (null === $user = $token->getUser()) {
return null;
}
if (!($user instanceof User)) {
throw new ServiceUnavailableHttpException();
}
return $user;
}
}