app/Plugin/PrivateURL42/Doctrine/EventSubscriber/PrivateSubscriber.php line 82

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of PrivateURL42
  4.  *
  5.  * Copyright(c) Akira Kurozumi <info@a-zumi.net>
  6.  *
  7.  * https://a-zumi.net
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Plugin\PrivateURL42\Doctrine\EventSubscriber;
  13. use Doctrine\Common\EventSubscriber;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use Doctrine\ORM\Event\PreUpdateEventArgs;
  16. use Doctrine\ORM\Events;
  17. use Doctrine\Persistence\Event\LifecycleEventArgs;
  18. use Eccube\Entity\Master\ProductStatus;
  19. use Eccube\Entity\Product;
  20. use Eccube\Request\Context;
  21. use Eccube\Util\StringUtil;
  22. use Plugin\PrivateURL42\Common\Constant;
  23. use Symfony\Component\HttpFoundation\RequestStack;
  24. class PrivateSubscriber implements EventSubscriber
  25. {
  26.     /**
  27.      * @var Context
  28.      */
  29.     protected Context $requestContext;
  30.     /**
  31.      * @var EntityManagerInterface
  32.      */
  33.     protected EntityManagerInterface $entityManager;
  34.     /**
  35.      * @var RequestStack
  36.      */
  37.     private RequestStack $requestStack;
  38.     public function __construct(
  39.         Context $requestContext,
  40.         EntityManagerInterface $entityManager,
  41.         RequestStack $requestStack
  42.     ) {
  43.         $this->requestContext $requestContext;
  44.         $this->entityManager $entityManager;
  45.         $this->requestStack $requestStack;
  46.     }
  47.     /**
  48.      * @return array|string[]
  49.      */
  50.     public function getSubscribedEvents(): array
  51.     {
  52.         return [
  53.             Events::postLoad,
  54.             Events::preUpdate,
  55.             Events::prePersist,
  56.         ];
  57.     }
  58.     /**
  59.      * Product読み込み時の処理
  60.      *
  61.      * @param LifecycleEventArgs $args
  62.      *
  63.      * @return void
  64.      */
  65.     public function postLoad(LifecycleEventArgs $args): void
  66.     {
  67.         $entity $args->getObject();
  68.         $entityManager $args->getObjectManager();
  69.         if ($entity instanceof Product) {
  70.             // フロント処理
  71.             if ($this->requestContext->isFront()) {
  72.                 $private_key $this->requestStack->getSession()->get(Constant::SESSION_PLG_PRIVATE_URL_PRIVATE_KEY.'_'.$entity->getId());
  73.                 // セッションに保持されているプライベートキーがDBと一致したら、商品ステータスを一時的に公開に変更
  74.                 if ($private_key && $entity->getPlgPuPrivateKey() === $private_key) {
  75.                     $productStatus $entityManager->find(ProductStatus::class, ProductStatus::DISPLAY_SHOW);
  76.                     $entity->setStatus($productStatus);
  77.                 }
  78.             }
  79.         }
  80.     }
  81.     /**
  82.      * Product更新前処理
  83.      *
  84.      * @param PreUpdateEventArgs $args
  85.      *
  86.      * @return void
  87.      */
  88.     public function preUpdate(PreUpdateEventArgs $args): void
  89.     {
  90.         $entity $args->getObject();
  91.         if ($entity instanceof Product) {
  92.             // 管理画面処理
  93.             if ($this->requestContext->isAdmin()) {
  94.                 // 限定公開URL生成に変化があった場合
  95.                 if ($args->hasChangedField('plg_pu_private')) {
  96.                     // 有効化された場合プライベートキー発行
  97.                     if ($entity->isPlgPuPrivate()) {
  98.                         $key $this->getUniquePrivateKey();
  99.                         $entity->setPlgPuPrivateKey($key);
  100.                     } else {
  101.                         // 無効化されたらプライベートキー削除
  102.                         $entity->setPlgPuPrivateKey(null);
  103.                         // セッションから削除
  104.                         $this->requestStack->getSession()->remove(Constant::SESSION_PLG_PRIVATE_URL_PRIVATE_KEY.'_'.$entity->getId());
  105.                     }
  106.                 }
  107.             }
  108.             // フロント処理
  109.             if ($this->requestContext->isFront()) {
  110.                 // postLoadで公開に変更した場合、商品ステータスを非公開に戻す
  111.                 if ($args->hasChangedField('Status')) {
  112.                     $entity->setStatus($args->getOldValue('Status'));
  113.                 }
  114.             }
  115.         }
  116.     }
  117.     /**
  118.      * 新規作成したときに限定公開URL生成が有効だったら秘密キーを生成
  119.      *
  120.      * @param LifecycleEventArgs $args
  121.      *
  122.      * @return void
  123.      */
  124.     public function prePersist(LifecycleEventArgs $args): void
  125.     {
  126.         $entity $args->getObject();
  127.         if ($entity instanceof Product) {
  128.             // 管理画面処理
  129.             if ($this->requestContext->isAdmin()) {
  130.                 // 有効化された場合プライベートキー発行
  131.                 if ($entity->isPlgPuPrivate()) {
  132.                     $key $this->getUniquePrivateKey();
  133.                     $entity->setPlgPuPrivateKey($key);
  134.                 }
  135.             }
  136.         }
  137.     }
  138.     /**
  139.      * @return string
  140.      */
  141.     private function getUniquePrivateKey(): string
  142.     {
  143.         do {
  144.             $key StringUtil::random(32);
  145.             $Product $this->entityManager->getRepository(Product::class)->findOneBy(['plg_pu_private_key' => $key]);
  146.         } while ($Product);
  147.         return $key;
  148.     }
  149. }