vendor/coreshop/optimistic-entity-lock-bundle/EventListener/LockListener.php line 66

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * CoreShop
  5.  *
  6.  * This source file is available under two different licenses:
  7.  *  - GNU General Public License version 3 (GPLv3)
  8.  *  - CoreShop Commercial License (CCL)
  9.  * Full copyright and license information is available in
  10.  * LICENSE.md which is distributed with this source code.
  11.  *
  12.  * @copyright  Copyright (c) CoreShop GmbH (https://www.coreshop.org)
  13.  * @license    https://www.coreshop.org/license     GPLv3 and CCL
  14.  *
  15.  */
  16. namespace CoreShop\Bundle\OptimisticEntityLockBundle\EventListener;
  17. use CoreShop\Bundle\OptimisticEntityLockBundle\Exception\OptimisticLockException;
  18. use CoreShop\Bundle\OptimisticEntityLockBundle\Manager\EntityLockManager;
  19. use CoreShop\Bundle\OptimisticEntityLockBundle\Model\OptimisticLockedInterface;
  20. use Doctrine\DBAL\Connection;
  21. use Pimcore\Event\DataObjectEvents;
  22. use Pimcore\Event\Model\DataObjectEvent;
  23. use Pimcore\Model\DataObject\Concrete;
  24. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  25. class LockListener implements EventSubscriberInterface
  26. {
  27.     public function __construct(
  28.         protected EntityLockManager $lockManager,
  29.         protected Connection $connection,
  30.     ) {
  31.     }
  32.     public static function getSubscribedEvents(): array
  33.     {
  34.         return [
  35.             DataObjectEvents::PRE_ADD => 'preAddLock',
  36.             DataObjectEvents::PRE_UPDATE => 'checkLock',
  37.             DataObjectEvents::POST_UPDATE => 'postUpdateLock',
  38.         ];
  39.     }
  40.     public function preAddLock(DataObjectEvent $dataObjectEvent): void
  41.     {
  42.         $object $dataObjectEvent->getObject();
  43.         if (!$object instanceof OptimisticLockedInterface) {
  44.             return;
  45.         }
  46.         if (!$object instanceof Concrete) {
  47.             return;
  48.         }
  49.         /**
  50.          * @var Concrete $object
  51.          * @var OptimisticLockedInterface $object
  52.          */
  53.         $object->setOptimisticLockVersion(1);
  54.     }
  55.     public function postUpdateLock(DataObjectEvent $dataObjectEvent): void
  56.     {
  57.         $object $dataObjectEvent->getObject();
  58.         if (!$object instanceof OptimisticLockedInterface) {
  59.             return;
  60.         }
  61.         if (!$object instanceof Concrete) {
  62.             return;
  63.         }
  64.         /**
  65.          * @var Concrete $object
  66.          */
  67.         $this->lockManager->updateLock($object);
  68.     }
  69.     public function checkLock(DataObjectEvent $dataObjectEvent): void
  70.     {
  71.         $object $dataObjectEvent->getObject();
  72.         if (!$object instanceof OptimisticLockedInterface) {
  73.             return;
  74.         }
  75.         if (!$object instanceof Concrete) {
  76.             return;
  77.         }
  78.         $this->ensureVersionMatch($object);
  79.         /**
  80.          * @var Concrete $object
  81.          * @var OptimisticLockedInterface $object
  82.          */
  83.         $object->setOptimisticLockVersion(($object->getOptimisticLockVersion() ?? 1) + 1);
  84.     }
  85.     private function ensureVersionMatch(Concrete $object): void
  86.     {
  87.         if (!$object instanceof OptimisticLockedInterface) {
  88.             return;
  89.         }
  90.         $queryBuilder $this->connection->createQueryBuilder();
  91.         $queryBuilder->from('object_store_' $object->getClassId())
  92.             ->select('optimisticLockVersion')
  93.             ->where('oo_id = :id')
  94.             ->setMaxResults(1)
  95.             ->setParameter('id'$object->getId())
  96.         ;
  97.         $currentVersion = (int) $this->connection->fetchOne($queryBuilder->getSQL(), $queryBuilder->getParameters());
  98.         if ($currentVersion === $object->getOptimisticLockVersion()) {
  99.             return;
  100.         }
  101.         throw OptimisticLockException::lockFailedVersionMismatch(
  102.             $object,
  103.             $object->getOptimisticLockVersion(),
  104.             $currentVersion,
  105.         );
  106.     }
  107. }