src/Cms/CoreBundle/Util/Doctrine/EntityManager.php line 266

Open in your IDE?
  1. <?php
  2. namespace Cms\CoreBundle\Util\Doctrine;
  3. use Cms\CoreBundle\Model\Interfaces\DatabaseOptimizationInterface;
  4. use Doctrine\ORM\Decorator\EntityManagerDecorator;
  5. use Doctrine\ORM\EntityManager as DoctrineEntityManager;
  6. use Doctrine\ORM\EntityRepository as DoctrineEntityRepository;
  7. /**
  8.  * Class EntityManager
  9.  * @package Cms\CoreBundle\Util\Doctrine
  10.  *
  11.  * @method EntityRepository getRepository($entityName)
  12.  */
  13. class EntityManager extends EntityManagerDecorator
  14. {
  15.     /**
  16.      * @var array
  17.      */
  18.     private array $customRepositoryCache = [];
  19.     /**
  20.      * @param iterable $entities
  21.      * @return $this
  22.      */
  23.     public function optimize(iterable $entities): self
  24.     {
  25.         $optmizations = [];
  26.         foreach ($entities as $entity) {
  27.             if ($entity instanceof DatabaseOptimizationInterface) {
  28.                 foreach ($entity->optimize() as $class => $id) {
  29.                     if ( ! array_key_exists($class$optmizations)) {
  30.                         $optmizations[$class] = [];
  31.                     }
  32.                     $optmizations[$class][] = $id;
  33.                 }
  34.             }
  35.         }
  36.         foreach ($optmizations as $type => $ids) {
  37.             $qb $this->getRepository($type)->createQueryBuilder('optimizations')
  38.                 ->andWhere('optimizations.id IN (:ids)')
  39.                 ->setParameter('ids'$ids);
  40.             $qb->getQuery()->getResult();
  41.         }
  42.         return $this;
  43.     }
  44.     /**
  45.      * @param string $class
  46.      * @param string $entity
  47.      * @return DoctrineEntityRepository
  48.      */
  49.     public function getCustomRepository(string $classstring $entity): DoctrineEntityRepository
  50.     {
  51.         if ( ! is_subclass_of($classDoctrineEntityRepository::class)) {
  52.             throw new \LogicException();
  53.         }
  54.         if ( ! array_key_exists($class$this->customRepositoryCache)) {
  55.             $this->customRepositoryCache[$class] = new $class(
  56.                 $this,
  57.                 $this->getClassMetadata($entity)
  58.             );
  59.         }
  60.         return $this->customRepositoryCache[$class];
  61.     }
  62.     /**
  63.      * @return EntityManager
  64.      */
  65.     public function clone(): EntityManager
  66.     {
  67.         return new self(
  68.             DoctrineEntityManager::create(
  69.                 $this->getConnection(),
  70.                 $this->getConfiguration(),
  71.                 $this->getEventManager(),
  72.             ),
  73.         );
  74.     }
  75.     /**
  76.      * @param mixed $entity
  77.      * @return bool
  78.      */
  79.     public function isDirty($entity): bool
  80.     {
  81.         return ($this->getUnitOfWork()->isEntityScheduled($entity) === true);
  82.     }
  83.     /**
  84.      * {@inheritdoc}
  85.      */
  86.     public function detach($object): void
  87.     {
  88.         if ($object !== null) {
  89.             parent::detach($object);
  90.         }
  91.     }
  92.     /**
  93.      * @param iterable $entities
  94.      * @return $this
  95.      */
  96.     public function persistAll(iterable $entities): self
  97.     {
  98.         // loop over all, assume some iterable type
  99.         foreach ($entities as $entity) {
  100.             // just persist
  101.             $this->persist($entity);
  102.         }
  103.         // chain
  104.         return $this;
  105.     }
  106.     /**
  107.      * @param iterable $classes
  108.      * @return $this
  109.      */
  110.     public function clearAll(iterable $classes): self
  111.     {
  112.         foreach ($classes as $class) {
  113.             if ( ! empty($class)) {
  114.                 $this->clear($class);
  115.             }
  116.         }
  117.         return $this;
  118.     }
  119.     /**
  120.      * @param iterable $entities
  121.      * @return $this
  122.      */
  123.     public function removeAll(iterable $entities): self
  124.     {
  125.         // loop over all, assume some iterable type
  126.         foreach ($entities as $entity) {
  127.             // just remove
  128.             $this->remove($entity);
  129.         }
  130.         // chain
  131.         return $this;
  132.     }
  133.     /**
  134.      * @param mixed $entity
  135.      * @return $this
  136.      */
  137.     public function save($entity): self
  138.     {
  139.         // persist and flush
  140.         $this->persist($entity);
  141.         $this->flush();
  142.         // chain
  143.         return $this;
  144.     }
  145.     /**
  146.      * @param iterable $entities
  147.      * @param bool $flushEach
  148.      * @return $this
  149.      */
  150.     public function saveAll(iterable $entitiesbool $flushEach false): self
  151.     {
  152.         // loop over entities, we assume array or iterable type
  153.         foreach ($entities as $entity) {
  154.             // branch on whether we are flushing as we go
  155.             if ($flushEach === true) {
  156.                 // use our helper, flushes on each call
  157.                 $this->save($entity);
  158.             } else {
  159.                 // just persist
  160.                 $this->persist($entity);
  161.             }
  162.         }
  163.         // if we didn't flush on each, we need to flush now
  164.         if ($flushEach === false) {
  165.             $this->flush();
  166.         }
  167.         // chain
  168.         return $this;
  169.     }
  170.     /**
  171.      * @param iterable $entities
  172.      * @param int $batch
  173.      * @return $this
  174.      */
  175.     public function saveBatches(iterable $entitiesint $batch 200): self
  176.     {
  177.         // default the batch size if it is not legit
  178.         if ($batch 0) {
  179.             $batch 1;
  180.         }
  181.         // in case we are passed an associative array or traversable, need our own counting variable
  182.         $count 0;
  183.         foreach ($entities as $entity) {
  184.             $this->persist($entity);
  185.             $count++;
  186.             if ($count $batch === 0) {
  187.                 $this->flush();
  188.             }
  189.         }
  190.         // final flush to get last incomplete set flushed out
  191.         $this->flush();
  192.         // chain
  193.         return $this;
  194.     }
  195.     /**
  196.      * @param mixed $entity
  197.      * @return $this
  198.      */
  199.     public function delete($entity): self
  200.     {
  201.         // remove and flush
  202.         $this->remove($entity);
  203.         $this->flush();
  204.         // chain
  205.         return $this;
  206.     }
  207.     /**
  208.      * @param iterable $entities
  209.      * @param bool $flushEach
  210.      * @return $this
  211.      */
  212.     public function deleteAll(iterable $entitiesbool $flushEach false): self
  213.     {
  214.         // loop over each, assume array or iterable
  215.         foreach ($entities as $entity) {
  216.             // check for flushing
  217.             if ($flushEach === true) {
  218.                 // use our helper, this flushes after each call
  219.                 $this->delete($entity);
  220.             } else {
  221.                 // schedule removal
  222.                 $this->remove($entity);
  223.             }
  224.         }
  225.         // flush if we didn't do it after each
  226.         if ($flushEach === false) {
  227.             $this->flush();
  228.         }
  229.         // chain
  230.         return $this;
  231.     }
  232.     /**
  233.      * {@inheritDoc}
  234.      */
  235.     public function wrapInTransaction(callable $func)
  236.     {
  237.         $wrappedFunc = fn () => $func($this);
  238.         return $this->wrapped->wrapInTransaction($wrappedFunc);
  239.     }
  240.     /**
  241.      * {@inheritDoc}
  242.      */
  243.     public function transactional($func)
  244.     {
  245.         return $this->wrapInTransaction($func);
  246.     }
  247. }