src/Cms/TagBundle/Doctrine/TagRepository.php line 130

Open in your IDE?
  1. <?php
  2. namespace Cms\TagBundle\Doctrine;
  3. use Cms\CoreBundle\Model\Search\SearchableTrait;
  4. use Cms\TagBundle\Entity\Tag;
  5. use Cms\CoreBundle\Util\Doctrine\EntityRepository;
  6. /**
  7.  * Class TagRepository
  8.  * @package Cms\TagBundle\Doctrine
  9.  *
  10.  * @method Tag findExact($id)
  11.  */
  12. class TagRepository extends EntityRepository
  13. {
  14.     use SearchableTrait;
  15.     const RELATION_TABLE_REGEX '#^cms__modules__\w+?__\w+?__\w+?__tag$#';
  16.     /**
  17.      * @param Tag $tag
  18.      * @param $tenantId
  19.      * @return bool
  20.      */
  21.     public function isUniqueTag(Tag $tag$tenantId)
  22.     {
  23.         $builder $this->createQueryBuilder('tags');
  24.         $builder
  25.             ->andWhere('tags.name = :name')
  26.             ->setParameter('name'$tag->getName())
  27.         ;
  28.         if ($tenantId) {
  29.             $builder
  30.                 ->andWhere('tags.tenant = :tenant')
  31.                 ->setParameter('tenant'$tenantId)
  32.             ;
  33.         }
  34.         if ($tag->getId()) {
  35.             $builder
  36.                 ->andWhere('tags.id != :id')
  37.                 ->setParameter('id'$tag->getId())
  38.             ;
  39.         }
  40.         return is_null($this->queryOne($builder));
  41.     }
  42.     /**
  43.      * Merges one tag into another
  44.      *
  45.      * @param Tag $source Tag that will be merged and removed
  46.      * @param Tag|integer $target
  47.      * return $this
  48.      */
  49.     public function mergeTag(Tag $source$target)
  50.     {
  51.         if ($target instanceof Tag) {
  52.             $target $target->getId();
  53.         }
  54.         $connection $this->getEntityManager()->getConnection();
  55.         $connection->beginTransaction();
  56.         foreach ($this->getTagRelationTables() as $table) {
  57.             $this->mergeTable($table$source->getId(), $target);
  58.         }
  59.         $this->getEntityManager()->delete($source);
  60.         $connection->commit();
  61.     }
  62.     /**
  63.      * Returns list of tag relation tables
  64.      * @return []
  65.      */
  66.     protected function getTagRelationTables()
  67.     {
  68.         $result = [];
  69.         $tables $this->getEntityManager()->getConnection()->getSchemaManager()->listTables();
  70.         foreach ($tables as $table) {
  71.             if (preg_match(self::RELATION_TABLE_REGEX$table->getName())) {
  72.                 $result[] = $table->getName();
  73.             }
  74.         }
  75.         return $result;
  76.     }
  77.     /**
  78.      * @param string $table
  79.      * @param integer $sourceId
  80.      * @param integer $targetId
  81.      * @todo reduce requests
  82.      */
  83.     public function mergeTable($table$sourceId$targetId)
  84.     {
  85.         $connection $this->getEntityManager()->getConnection();
  86.         // At first get list of proxy id from target and use it for delete statement to avoid key duplication
  87.         $query $connection->prepare('SELECT item_id FROM '.$table.' WHERE tag_id = :id');
  88.         $query->execute(array('id' => $targetId));
  89.         $targetRelations $query->fetchAll(\PDO::FETCH_COLUMN);
  90.         if (count($targetRelations)) {
  91.             // System updates only records that do not have relation with target tag.
  92.             // System uses IN condition to avoid primary key duplication.
  93.             // Records that have relation with target tag deleted inside mergeTag method due to cascade deletion.
  94.             $query $connection->prepare(
  95.                 'UPDATE '.$table.' SET tag_id = :targetId
  96.                 WHERE tag_id = :sourceId AND item_id NOT IN ('.implode(','$targetRelations).')'
  97.             );
  98.             $query->execute(array('targetId' => $targetId'sourceId' => $sourceId));
  99.         }
  100.     }
  101.     /**
  102.      * Find all tags with root level
  103.      *
  104.      * @param int $limit
  105.      * @param int $page
  106.      *
  107.      * @return array|Tag[]
  108.      */
  109.     public function findAllRoots($limit 0$page 0)
  110.     {
  111.         return $this->queryMany(
  112.             $this->createQueryBuilder('tags')
  113.                 ->andWhere('tags.parent IS NULL')
  114.                 ->addOrderBy('tags.name''ASC'),
  115.             $limit,
  116.             $page
  117.         );
  118.     }
  119.     /**
  120.      * Find all tags without current
  121.      *
  122.      * @param integer|null $tagId
  123.      * @return array
  124.      */
  125.     public function parentTagsQueryBuilder($tagId null)
  126.     {
  127.         $qb $this->createQueryBuilder('tags');
  128.         if ($tagId) {
  129.             $qb->where('tags.id != :tagId')->setParameter('tagId'$tagId);
  130.         }
  131.         return $qb;
  132.     }
  133.     /**
  134.      * @param string $name
  135.      * @return Tag
  136.      * @throws \Exception
  137.      */
  138.     public function findOneByName($name)
  139.     {
  140.         if (empty(trim($name))) {
  141.             throw new \Exception();
  142.         }
  143.         return $this->queryOne(
  144.             $this->createQueryBuilder('tag')
  145.                 ->andWhere('tag.name = :name')
  146.                 ->setParameter('name'$name)
  147.         );
  148.     }
  149. }