core/lib/Thelia/Action/File.php line 38

  1. <?php
  2. /*
  3.  * This file is part of the Thelia package.
  4.  * http://www.thelia.net
  5.  *
  6.  * (c) OpenStudio <info@thelia.net>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. namespace Thelia\Action;
  12. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\HttpFoundation\File\UploadedFile;
  15. use Thelia\Core\Event\File\FileCreateOrUpdateEvent;
  16. use Thelia\Core\Event\Product\ProductCloneEvent;
  17. use Thelia\Core\Event\TheliaEvents;
  18. use Thelia\Core\Translation\Translator;
  19. use Thelia\Log\Tlog;
  20. use Thelia\Model\ProductDocument;
  21. use Thelia\Model\ProductDocumentI18n;
  22. use Thelia\Model\ProductDocumentI18nQuery;
  23. use Thelia\Model\ProductDocumentQuery;
  24. use Thelia\Model\ProductImage;
  25. use Thelia\Model\ProductImageI18nQuery;
  26. use Thelia\Model\ProductImageQuery;
  27. /**
  28.  * Class File.
  29.  *
  30.  * @author Etienne Perriere <eperriere@openstudio.fr>
  31.  */
  32. class File extends BaseAction implements EventSubscriberInterface
  33. {
  34.     public function cloneFile(ProductCloneEvent $event$eventNameEventDispatcherInterface $dispatcher): void
  35.     {
  36.         $originalProductId $event->getOriginalProduct()->getId();
  37.         $clonedProduct $event->getClonedProduct();
  38.         foreach ($event->getTypes() as $type) {
  39.             if (!\in_array($type, ['images''documents'])) {
  40.                 throw new \Exception(Translator::getInstance()->trans('Cloning files of type %type is not allowed.', ['%type' => $type], 'core'));
  41.             }
  42.             $originalProductFiles = [];
  43.             switch ($type) {
  44.                 case 'images':
  45.                     $originalProductFiles ProductImageQuery::create()
  46.                         ->findByProductId($originalProductId);
  47.                     break;
  48.                 case 'documents':
  49.                     $originalProductFiles ProductDocumentQuery::create()
  50.                         ->findByProductId($originalProductId);
  51.                     break;
  52.             }
  53.             // Set clone's files
  54.             /** @var ProductDocument|ProductImage $originalProductFile */
  55.             foreach ($originalProductFiles as $originalProductFile) {
  56.                 $srcPath $originalProductFile->getUploadDir().DS.$originalProductFile->getFile();
  57.                 if (file_exists($srcPath)) {
  58.                     $ext pathinfo($srcPath\PATHINFO_EXTENSION);
  59.                     $clonedProductFile = [];
  60.                     $fileName '';
  61.                     switch ($type) {
  62.                         case 'images':
  63.                             $fileName $clonedProduct->getRef().'.'.$ext;
  64.                             $clonedProductFile = new ProductImage();
  65.                             break;
  66.                         case 'documents':
  67.                             $fileName pathinfo($originalProductFile->getFile(), \PATHINFO_FILENAME).'-'.$clonedProduct->getRef().'.'.$ext;
  68.                             $clonedProductFile = new ProductDocument();
  69.                             break;
  70.                     }
  71.                     // Copy a temporary file of the source file as it will be deleted by IMAGE_SAVE or DOCUMENT_SAVE event
  72.                     $srcTmp $srcPath.'.tmp';
  73.                     copy($srcPath$srcTmp);
  74.                     // Get file mimeType
  75.                     $finfo = new \finfo();
  76.                     $fileMimeType $finfo->file($srcPath\FILEINFO_MIME_TYPE);
  77.                     // Get file event's parameters
  78.                     $clonedProductFile
  79.                         ->setProductId($clonedProduct->getId())
  80.                         ->setVisible($originalProductFile->getVisible())
  81.                         ->setPosition($originalProductFile->getPosition())
  82.                         ->setLocale($clonedProduct->getLocale())
  83.                         ->setTitle($clonedProduct->getTitle());
  84.                     $clonedProductCopiedFile = new UploadedFile($srcPath$fileName$fileMimeType);
  85.                     // Create and dispatch event
  86.                     $clonedProductCreateFileEvent = new FileCreateOrUpdateEvent($clonedProduct->getId());
  87.                     $clonedProductCreateFileEvent
  88.                         ->setModel($clonedProductFile)
  89.                         ->setUploadedFile($clonedProductCopiedFile)
  90.                         ->setParentName($clonedProduct->getTitle());
  91.                     $originalProductFileI18ns = [];
  92.                     switch ($type) {
  93.                         case 'images':
  94.                             $dispatcher->dispatch($clonedProductCreateFileEventTheliaEvents::IMAGE_SAVE);
  95.                             // Get original product image I18n
  96.                             $originalProductFileI18ns ProductImageI18nQuery::create()
  97.                                 ->findById($originalProductFile->getId());
  98.                             break;
  99.                         case 'documents':
  100.                             $dispatcher->dispatch($clonedProductCreateFileEventTheliaEvents::DOCUMENT_SAVE);
  101.                             // Get original product document I18n
  102.                             $originalProductFileI18ns ProductDocumentI18nQuery::create()
  103.                                 ->findById($originalProductFile->getId());
  104.                             break;
  105.                     }
  106.                     // Set temporary source file as original one
  107.                     rename($srcTmp$srcPath);
  108.                     // Clone file's I18n
  109.                     $this->cloneFileI18n($originalProductFileI18ns$clonedProductFile$type$event$dispatcher);
  110.                 } else {
  111.                     Tlog::getInstance()->addWarning("Failed to find media file $srcPath");
  112.                 }
  113.             }
  114.         }
  115.     }
  116.     public function cloneFileI18n($originalProductFileI18ns$clonedProductFile$typeProductCloneEvent $eventEventDispatcherInterface $dispatcher): void
  117.     {
  118.         // Set clone files I18n
  119.         /** @var ProductDocumentI18n $originalProductFileI18n */
  120.         foreach ($originalProductFileI18ns as $originalProductFileI18n) {
  121.             // Update file with current I18n info. Update or create I18n according to existing or absent Locale in DB
  122.             $clonedProductFile
  123.                 ->setLocale($originalProductFileI18n->getLocale())
  124.                 ->setTitle($originalProductFileI18n->getTitle())
  125.                 ->setDescription($originalProductFileI18n->getDescription())
  126.                 ->setChapo($originalProductFileI18n->getChapo())
  127.                 ->setPostscriptum($originalProductFileI18n->getPostscriptum());
  128.             // Create and dispatch event
  129.             $clonedProductUpdateFileEvent = new FileCreateOrUpdateEvent($event->getClonedProduct()->getId());
  130.             $clonedProductUpdateFileEvent->setModel($clonedProductFile);
  131.             switch ($type) {
  132.                 case 'images':
  133.                     $dispatcher->dispatch($clonedProductUpdateFileEventTheliaEvents::IMAGE_UPDATE);
  134.                     break;
  135.                 case 'documents':
  136.                     $dispatcher->dispatch($clonedProductUpdateFileEventTheliaEvents::DOCUMENT_UPDATE);
  137.                     break;
  138.             }
  139.         }
  140.     }
  141.     /**
  142.      * {@inheritdoc}
  143.      */
  144.     public static function getSubscribedEvents()
  145.     {
  146.         return [
  147.             TheliaEvents::FILE_CLONE => ['cloneFile'128],
  148.         ];
  149.     }
  150. }