src/EventSubscriber/Account/AvatarSubscriber.php line 93

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the adrec-platform package.
  4. *
  5. * (c) Benjamin Georgeault <https://www.pressop.eu>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace App\EventSubscriber\Account;
  11. use App\Entity\Channel\Channel;
  12. use App\Entity\Channel\Image;
  13. use App\Entity\Account\User;
  14. use App\Repository\Account\UserRepository;
  15. use App\Repository\Channel\ChannelRepository;
  16. use App\Service\Account\UserAvatar;
  17. use Doctrine\ORM\EntityManagerInterface;
  18. use Liip\ImagineBundle\Imagine\Cache\CacheManager;
  19. use Liip\ImagineBundle\Imagine\Data\DataManager;
  20. use Liip\ImagineBundle\Imagine\Filter\FilterManager;
  21. use Oneup\UploaderBundle\Event\PostPersistEvent;
  22. use Oneup\UploaderBundle\Event\PreUploadEvent;
  23. use Oneup\UploaderBundle\UploadEvents;
  24. use Ramsey\Uuid\Uuid;
  25. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  26. use Symfony\Component\Filesystem\Filesystem;
  27. use Symfony\Component\Finder\Finder;
  28. use Symfony\Component\Finder\SplFileInfo;
  29. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  30. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  31. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  32. use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
  33. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  34. use Symfony\Component\Security\Core\Security;
  35. /**
  36. * Class AvatarSubscriber
  37. *
  38. */
  39. class AvatarSubscriber implements EventSubscriberInterface
  40. {
  41. /**
  42. * @var string[]
  43. */
  44. private static $filters = [
  45. 'avatar_thumbnail',
  46. ];
  47. private EntityManagerInterface $em;
  48. private TokenStorageInterface $token;
  49. private Filesystem $filesystem;
  50. private string $avatarUploadDir;
  51. private string $avatarUploadUri;
  52. private CacheManager $cacheManager;
  53. private DataManager $dataManager;
  54. private FilterManager $filterManager;
  55. private UserAvatar $userAvatar;
  56. private UserRepository $userRepository;
  57. private Security $security;
  58. public function __construct(EntityManagerInterface $em, TokenStorageInterface $token, Filesystem $filesystem, string $avatarUploadDir, string $avatarUploadUri, CacheManager $cacheManager, DataManager $dataManager, FilterManager $filterManager, UserAvatar $userAvatar, UserRepository $userRepository, Security $security)
  59. {
  60. $this->em = $em;
  61. $this->token = $token;
  62. $this->filesystem = $filesystem;
  63. $this->avatarUploadDir = $avatarUploadDir;
  64. $this->avatarUploadUri = $avatarUploadUri;
  65. $this->cacheManager = $cacheManager;
  66. $this->dataManager = $dataManager;
  67. $this->filterManager = $filterManager;
  68. $this->userAvatar = $userAvatar;
  69. $this->userRepository = $userRepository;
  70. $this->security = $security;
  71. }
  72. /**
  73. * @return string[]
  74. */
  75. public static function getSubscribedEvents(): array
  76. {
  77. return [
  78. UploadEvents::PRE_UPLOAD.'.user_avatar' => 'onPreUpload',
  79. UploadEvents::POST_PERSIST.'.user_avatar' => 'onFinishedUpload',
  80. ];
  81. }
  82. /**
  83. * @param PreUploadEvent $event
  84. */
  85. public function onPreUpload(PreUploadEvent $event)
  86. {
  87. $request = $event->getRequest();
  88. if (!$request->headers->has('user-id')) {
  89. throw new BadRequestHttpException();
  90. }
  91. $user = $this->getUser();
  92. $userFromQuery = $request->headers->get('user-id');
  93. if ($user->getId() !== $userFromQuery && !$this->security->isGranted('ROLE_ADMIN')) {
  94. throw new AccessDeniedHttpException();
  95. }
  96. if (null === $user = $this->userRepository->find($userFromQuery)) {
  97. throw new NotFoundHttpException(sprintf('Cannot found user for id "%s".', $userFromQuery));
  98. }
  99. if (null !== $fileName = $this->userAvatar->getAvatarUrl($user)) {
  100. $finder = new Finder();
  101. $files = $finder->name($fileName)->files()->in($this->avatarUploadDir);
  102. /** @var SplFileInfo $file */
  103. foreach ($files as $file) {
  104. $this->filesystem->remove($file->getPathname());
  105. $this->cacheManager->remove(sprintf(
  106. '%s/%s',
  107. $this->avatarUploadUri,
  108. $fileName
  109. ), self::$filters);
  110. }
  111. }
  112. }
  113. /**
  114. * @param PostPersistEvent $event
  115. */
  116. public function onFinishedUpload(PostPersistEvent $event)
  117. {
  118. /** @var \Oneup\UploaderBundle\Uploader\File\FileInterface $file */
  119. $file = $event->getFile();
  120. $request = $event->getRequest();
  121. if (!$request->headers->has('user-id')) {
  122. throw new BadRequestHttpException();
  123. }
  124. $user = $this->getUser();
  125. $userFromQuery = $request->headers->get('user-id');
  126. if ($user->getId() !== $userFromQuery && !$this->security->isGranted('ROLE_ADMIN')) {
  127. throw new AccessDeniedHttpException();
  128. }
  129. if (null === $user = $this->userRepository->find($userFromQuery)) {
  130. throw new NotFoundHttpException(sprintf('Cannot found user for id "%s".', $userFromQuery));
  131. }
  132. $user->setAvatar(true)->setAvatarFile($file->getBasename());
  133. $this->em->persist($user);
  134. $this->em->flush();
  135. $uri = sprintf(
  136. '%s/%s',
  137. $this->avatarUploadUri,
  138. $file->getBasename()
  139. );
  140. $response = $event->getResponse();
  141. $response['image'] = $uri;
  142. $thumbnails = [];
  143. foreach (self::$filters as $filter) {
  144. try {
  145. $this->cacheManager->store($this->filterManager->applyFilter(
  146. $this->dataManager->find($filter, $uri), $filter), $uri, $filter
  147. );
  148. $thumbnails[$filter] = $this->cacheManager->getBrowserPath($uri, $filter);
  149. } catch (\Exception $e) {
  150. }
  151. }
  152. $response['thumbnails'] = $thumbnails;
  153. }
  154. /**
  155. * @return User|null
  156. */
  157. private function getUser(): ?User
  158. {
  159. if (null === $token = $this->token->getToken()) {
  160. return null;
  161. }
  162. if (null === $user = $token->getUser()) {
  163. return null;
  164. }
  165. if (!($user instanceof User)) {
  166. throw new ServiceUnavailableHttpException();
  167. }
  168. return $user;
  169. }
  170. }