src/Repository/BaseRepository.php line 558

Open in your IDE?
  1. <?php
  2. namespace App\Repository;
  3. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  4. use Doctrine\ORM\QueryBuilder;
  5. use Doctrine\ORM\Tools\Pagination\Paginator;
  6. use Doctrine\Persistence\ManagerRegistry;
  7. use Symfony\Component\HttpFoundation\Request;
  8. use Symfony\Component\DependencyInjection\ContainerInterface;
  9. use Symfony\Contracts\Cache\CacheInterface;
  10. use App\Misc\CustomEntityManager;
  11. use App\Service\CommonService;
  12. use AutoMapperPlus\AutoMapperInterface;
  13. use Gedmo\Translatable\Query\TreeWalker\TranslationWalker;
  14. /**
  15.  * @property AutoMapperInterface autoMapper
  16.  */
  17. class BaseRepository extends ServiceEntityRepository
  18. {
  19.     public function __construct(
  20.         ManagerRegistry $registry,
  21.         CustomEntityManager $customEntityManager,
  22.         CommonService $commonService,
  23.         CacheInterface $appCache,
  24.         AutoMapperInterface $autoMapper,
  25.         ContainerInterface $container
  26.     ) {
  27.         $this->commonService $commonService;
  28.         $thisName $this->commonService->getClassName($thistrue);
  29.         if ($thisName !== 'Base') {
  30.             parent::__construct($registry'App\Entity\\' $thisName);
  31.         }
  32.         $this->_em $customEntityManager;
  33.         $this->autoMapper $autoMapper;
  34.         $this->container $container;
  35.         $this->cache $appCache;
  36.     }
  37.     public function getEntityManager()
  38.     {
  39.         return $this->_em;
  40.     }
  41.     public function save($entity$inTransaction false)
  42.     {
  43.         $this->getEntityManager()->persist($entity);
  44.         if (!$inTransaction) {
  45.             $this->getEntityManager()->flush();
  46.         }
  47.         return $entity;
  48.     }
  49.     public function persist($entity)
  50.     {
  51.         $this->getEntityManager()->persist($entity);
  52.     }
  53.     public function flush()
  54.     {
  55.         $this->getEntityManager()->flush();
  56.     }
  57.     public function clear()
  58.     {
  59.         $this->getEntityManager()->clear();
  60.     }
  61.     public function delete($entities$inTransaction false)
  62.     {
  63.         if (!is_array($entities)) {
  64.             $entities = [$entities];
  65.         }
  66.         foreach ($entities as $entity) {
  67.             $this->getEntityManager()->remove($entity);
  68.         }
  69.         if (!$inTransaction) {
  70.             $this->getEntityManager()->flush();
  71.         }
  72.     }
  73.     /**
  74.      * @return \Doctrine\DBAL\Connection
  75.      */
  76.     public function getConnection()
  77.     {
  78.         return $this->getEntityManager()->getConnection();
  79.     }
  80.     public function __get($propertyName)
  81.     {
  82.         if($propertyName == '_entityName') {
  83.             return parent::__get('_entityName');
  84.         }
  85.         preg_match('/([a-zA-Z0-9]+)Service/i'$propertyName$serviceMatches);
  86.         if (count($serviceMatches) > 0) {
  87.             return $this
  88.                 ->container
  89.                 ->get('App\Service\\' ucfirst($serviceMatches[1]) . 'Service');
  90.         }
  91.         preg_match('/([a-zA-Z0-9]+)Repo/i'$propertyName$repositoryMatches);
  92.         if (count($repositoryMatches) > 0) {
  93.             return $this
  94.                 ->container
  95.                 ->get('App\Service\\' ucfirst($repositoryMatches[1]) . 'Service')
  96.                 ->repository;
  97.         }
  98.         $entityName $this->commonService->getClassName($thistrue);
  99.         $cacheKey 'Const.' $entityName '.' $propertyName;
  100.         $cachedConstantItem $this->cache->getItem($cacheKey);
  101.         if ($cachedConstantItem->isHit()) {
  102.             return $cachedConstantItem->get();
  103.         }
  104.         if($propertyName !== '_entityName') {
  105.             $constant null;
  106.             if(defined('App\Entity\\' $entityName '::' $propertyName)) {
  107.                 $constant constant('App\Entity\\' $entityName '::' $propertyName);
  108.             }
  109.             if (!is_null($constant)) {
  110.                 $cachedConstantItem->set($constant);
  111.                 $this->cache->save($cachedConstantItem);
  112.                 return $constant;
  113.             }
  114.         }
  115.         
  116.         $metas $this->_em->getMetadataFactory()->getAllMetadata();
  117.         foreach ($metas as $meta) {
  118.             $classPath $meta->getName();
  119.             $name strtoupper($this->commonService->toSnakeCase(str_replace('App\Entity\\'''$classPath)));
  120.             preg_match('/(' $name ')_(.+)/i'$propertyName$matches);
  121.             if (count($matches) > 0) {
  122.                 $prop $matches[2];
  123.                 if(defined($classPath '::' $prop)) {
  124.                     $constant = @constant($classPath '::' $prop);
  125.                 }
  126.                 if (!is_null($constant)) {
  127.                     $cachedConstantItem->set($constant);
  128.                     $this->cache->save($cachedConstantItem);
  129.                     return $constant;
  130.                 }
  131.             }
  132.         }
  133.         trigger_error('Could not found property ' $propertyName ' in ' $this->commonService->getClassName($this), E_USER_ERROR);
  134.     }
  135.     public function getPagingData($queryBuilder$paging null$DTO null$fetchJoinCollection)
  136.     {
  137.         if (is_null($paging)) {
  138.             $paging = [
  139.                 'page' => 1,
  140.                 'limit' => 50
  141.             ];
  142.         }
  143.         if (!isset($paging['page'])) {
  144.             $paging['page'] = 1;
  145.         }
  146.         if (!isset($paging['limit'])) {
  147.             $paging['limit'] = 50;
  148.         } else if (((int)$paging['limit']) <= 0) {
  149.             $paging['limit'] = pow(1012);
  150.         }
  151.         $queryBuilder
  152.             ->setFirstResult(($paging['page'] - 1) * $paging['limit'])
  153.             ->setMaxResults($paging['limit']);
  154.         $paginator = new Paginator($queryBuilder$fetchJoinCollection);
  155.         $paginatorQuery $paginator->getQuery();
  156.         $this->addTranslationWalkerToQuery($paginatorQuery);
  157.         $total count($paginator);
  158.         $list = [];
  159.         foreach ($paginator as $entity) {
  160.             if (is_null($DTO)) {
  161.                 $outputDTO 'App\DTO\\' $this->getEntityName() . '\\' $this->getEntityName() . 'Output';
  162.                 if (class_exists($outputDTO)) {
  163.                     $DTO $outputDTO;
  164.                 }
  165.             }
  166.             if (is_null($DTO) || $DTO === 'ENTITY') {
  167.                 $list[] = $entity;
  168.             } else {
  169.                 $array = (array)$this->autoMapper->map($entity$DTO);
  170.                 foreach ($array as $key => $value) {
  171.                     if (is_string($value)) {
  172.                         $array[$key] = mb_convert_encoding($value"UTF-8");
  173.                     }
  174.                 }
  175.                 $list[] = $array;
  176.             }
  177.         }
  178.         return [
  179.             'total' => $total,
  180.             'totalPages' => ceil($total $paging['limit']),
  181.             'list' => $list,
  182.             'currentPage' => $paging['page']
  183.         ];
  184.     }
  185.     public function setFilter(QueryBuilder $queryBuilder$requestData)
  186.     {
  187.         foreach ($requestData as $key => $value) {
  188.             if ($value === '') {
  189.                 continue;
  190.             }
  191.             if (strpos($key'filter_') === 0) {
  192.                 $filter str_replace('filter_'''$key);
  193.                 if (strpos($filter'_like') !== false) {
  194.                     $filter str_replace('_like'''$filter);
  195.                     if ($filter === 'namefull') {
  196.                         $queryBuilder
  197.                             ->andWhere(
  198.                                 $queryBuilder
  199.                                     ->expr()
  200.                                     ->orX(
  201.                                         $queryBuilder
  202.                                             ->expr()
  203.                                             ->like($this->getEntityName() . '.firstName'':firstName'),
  204.                                         $queryBuilder
  205.                                             ->expr()
  206.                                             ->like($this->getEntityName() . '.lastName'':lastName')
  207.                                     )
  208.                             )
  209.                             ->setParameter(':firstName'$value)
  210.                             ->setParameter(':lastName'$value);
  211.                     } else {
  212.                         // or like
  213.                         if (strpos($filter'_or_') !== -1) {
  214.                             $orx $queryBuilder->expr()->orX();
  215.                             foreach (explode('_or_'$filter) as $orFilter) {
  216.                                 $orx->add(
  217.                                     $queryBuilder
  218.                                         ->expr()
  219.                                         ->like($this->getEntityName() . '.' $orFilter':' $orFilter)
  220.                                 );
  221.                                 $queryBuilder->setParameter($orFilter'%' $value '%');
  222.                             }
  223.                             $queryBuilder->andWhere($orx);
  224.                         } else {
  225.                             $fieldName $this->getEntityName() . '.' $filter;
  226.                             $queryBuilder->andWhere(
  227.                                 $queryBuilder
  228.                                     ->expr()
  229.                                     ->like($fieldName':' $filter)
  230.                             );
  231.                             $queryBuilder->setParameter($filter'%' $value '%');
  232.                         }
  233.                     }
  234.                 } else {
  235.                     $fieldName $this->getEntityName() . '.' $filter;
  236.                     if (is_array($value)) {
  237.                         $queryBuilder
  238.                             ->andWhere(
  239.                                 $queryBuilder
  240.                                     ->expr()
  241.                                     ->in($fieldName':in' $filter)
  242.                             )
  243.                             ->setParameter(
  244.                                 'in' $filter,
  245.                                 $value,
  246.                                 \Doctrine\DBAL\Connection::PARAM_INT_ARRAY
  247.                             );
  248.                     } else if ($value === 'falseOrNull') {
  249.                         $queryBuilder->andWhere($fieldName ' = 0 or ' $fieldName ' is NULL');
  250.                     } else if ($value === 'isNull') {
  251.                         $queryBuilder->andWhere($fieldName ' is NULL');
  252.                     } else if ($value === 'true' || $value === 'false') {
  253.                         $queryBuilder->andWhere(
  254.                             $queryBuilder->expr()->eq($fieldName':' $filter)
  255.                         );
  256.                         $queryBuilder->setParameter($filter$value === 'true');
  257.                     } else if ($value === 'notNull') {
  258.                         $queryBuilder->andWhere(
  259.                             $queryBuilder->expr()->isNotNull($fieldName)
  260.                         );
  261.                     } else {
  262.                         $queryBuilder->andWhere(
  263.                             $queryBuilder->expr()->eq($fieldName':' $filter)
  264.                         );
  265.                         $queryBuilder->setParameter($filter$value);
  266.                     }
  267.                 }
  268.             } else if (strpos($key'except_') === 0) {
  269.                 $except str_replace('except_'''$key);
  270.                 $isInt is_int(explode(','$value)[0]);
  271.                 if ($isInt) {
  272.                     $value array_map('intval'explode(','$value));
  273.                 } else {
  274.                     $value array_map('strval'explode(','$value));
  275.                 }
  276.                 $fieldName $this->getEntityName() . '.' $except;
  277.                 $queryBuilder
  278.                     ->andWhere(
  279.                         $queryBuilder
  280.                             ->expr()
  281.                             ->orX(
  282.                                 $queryBuilder->expr()->isNull($fieldName),
  283.                                 $queryBuilder
  284.                                     ->expr()
  285.                                     ->notIn($fieldName':notIn' $except)
  286.                             )
  287.                     )
  288.                     ->setParameter(
  289.                         'notIn' $except,
  290.                         $value,
  291.                         $isInt
  292.                             \Doctrine\DBAL\Connection::PARAM_INT_ARRAY
  293.                             \Doctrine\DBAL\Connection::PARAM_STR_ARRAY
  294.                     );
  295.             } else if (strpos($key'has_') === 0) {
  296.                 $paramName 'p' bin2hex(random_bytes(5));
  297.                 $has str_replace('has_'''$key);
  298.                 $relationName explode('_'$has)[0];
  299.                 $relationProperty explode('_'$has)[1];
  300.                 $fieldName $this->getEntityName() . '.' $relationName;
  301.                 $queryBuilder
  302.                     ->leftJoin($fieldName$paramName)
  303.                     ->andWhere($paramName '.' $relationProperty ' = :' $paramName)
  304.                     ->setParameter($paramName$value);
  305.             } else if (strpos($key'hasAny_') === 0) {
  306.                 $paramName 'p' bin2hex(random_bytes(5));
  307.                 $has str_replace('hasAny_'''$key);
  308.                 $relationName explode('_'$has)[0];
  309.                 $relationProperty explode('_'$has)[1];
  310.                 $fieldName $this->getEntityName() . '.' $relationName;
  311.                 $queryBuilder
  312.                     ->leftJoin($fieldName$paramName)
  313.                     ->andWhere($paramName '.' $relationProperty ' = :' $paramName)
  314.                     ->setParameter($paramName$value);
  315.             } else if (strpos($key'hasAny2_') === 0) {
  316.                 $paramName 'p' bin2hex(random_bytes(5));
  317.                 $has str_replace('hasAny2_'''$key);
  318.                 $relationName explode('_'$has)[0];
  319.                 $relationProperty explode('_'$has)[1];
  320.                 $fieldName $this->getEntityName() . '.' $relationName;
  321.                 $queryBuilder
  322.                     ->leftJoin($fieldName$paramName)
  323.                     ->andWhere(':' $paramName ' member of ' $paramName '.' $relationProperty)
  324.                     ->setParameter($paramName$value);
  325.             } else if (strpos($key'memberOf_') === 0) {
  326.                 $relationName str_replace('memberOf_'''$key);
  327.                 $paramName 'p66' $relationName;
  328.                 $fieldName $this->getEntityName() . '.' $relationName;
  329.                 if ($value === 'isNull') {
  330.                     $queryBuilder->andWhere($fieldName ' is empty');
  331.                 }elseif ($value === 'notNull') {
  332.                     $queryBuilder
  333.                         ->leftJoin($fieldName$paramName);
  334.                     $queryBuilder->andWhere($queryBuilder->expr()->isNotNull($paramName));
  335.                 } else {
  336.                     $queryBuilder
  337.                         ->leftJoin($fieldName$paramName)
  338.                         ->andWhere(':' $paramName ' member of ' $fieldName)
  339.                         ->setParameter($paramName$value);
  340.                 }
  341.             } else if (strpos($key'hasLike_') === 0) {
  342.                 $paramName 'p' bin2hex(random_bytes(5));
  343.                 $has str_replace('hasLike_'''$key);
  344.                 $relationName explode('_'$has)[0];
  345.                 $relationProperty explode('_'$has)[1];
  346.                 $fieldName $this->getEntityName() . '.' $relationName;
  347.                 $queryBuilder
  348.                     ->leftJoin($fieldName$paramName)
  349.                     ->andWhere($paramName '.' $relationProperty ' LIKE :' $paramName)
  350.                     ->setParameter($paramName'%' $value '%');
  351.             }
  352.         }
  353.     }
  354.     public function setSort(QueryBuilder $queryBuilder$requestData)
  355.     {
  356.         foreach ($requestData as $key => $value) {
  357.             if (strpos($key'sort_') === false) {
  358.                 continue;
  359.             }
  360.             $direction strpos($key'_asc') !== false 'ASC' 'DESC';
  361.             $value str_replace('Text'''$value);
  362.             $isRelation strpos($value'Relation') !== false;
  363.             if ($isRelation) {
  364.                 $value str_replace('Relation'''$value);
  365.                 @list($rel1$rel2$rel3) = explode('.'$value);
  366.                 if (empty($rel3)) {
  367.                     $rel1Table $this->getEntityName() . '.' $rel1;
  368.                     $queryBuilder->leftJoin($rel1Table$rel1);
  369.                     $queryBuilder->addOrderBy($value$direction);
  370.                 } else {
  371.                     $rel1Table $this->getEntityName() . '.' $rel1;
  372.                     $queryBuilder->leftJoin($rel1Table$rel1);
  373.                     $rel2Table $rel1 '.' $rel2;
  374.                     $queryBuilder->leftJoin($rel2Table$rel2);
  375.                     $queryBuilder->addOrderBy($rel2 '.' $rel3$direction);
  376.                 }
  377.             } else {
  378.                 $fieldName $this->getEntityName() . '.' $value;
  379.                 $queryBuilder->addOrderBy($fieldName$direction);
  380.             }
  381.         }
  382.     }
  383.     public function getList($requestData$DTO null, callable $extraFilter null$fetchJoinCollection true)
  384.     {
  385.         if ($requestData instanceof Request) {
  386.             $requestData $requestData->query->all();
  387.         }
  388.         $queryBuilder $this->createQueryBuilder($this->getEntityName());
  389.         if (!is_null($extraFilter)) {
  390.             $extraFilter($queryBuilder);
  391.         }
  392.         $this->setFilter($queryBuilder$requestData);
  393.         $this->setSort($queryBuilder$requestData);
  394.         return $this->getPagingData($queryBuilder$requestData$DTO$fetchJoinCollection);
  395.     }
  396.     public function getAll($requestData$DTO null, callable $extraFilter null$returnQuery false)
  397.     {
  398.         if ($requestData instanceof Request) {
  399.             $requestData $requestData->query->all();
  400.         }
  401.         $queryBuilder $this->createQueryBuilder($this->getEntityName());
  402.         if (!is_null($extraFilter)) {
  403.             $extraFilter($queryBuilder);
  404.         }
  405.         $this->setFilter($queryBuilder$requestData);
  406.         $this->setSort($queryBuilder$requestData);
  407.         if ($returnQuery) {
  408.             return $queryBuilder->getQuery();
  409.         }
  410.         $entities $queryBuilder->getQuery()->execute();
  411.         $list = [];
  412.         foreach ($entities as $entity) {
  413.             if (is_null($DTO)) {
  414.                 $outputDTO 'App\DTO\\' $this->getEntityName() . '\\' $this->getEntityName() . 'Output';
  415.                 if (class_exists($outputDTO)) {
  416.                     $DTO $outputDTO;
  417.                 }
  418.             }
  419.             if (is_null($DTO) || $DTO === 'ENTITY') {
  420.                 $list[] = $entity;
  421.             } else {
  422.                 $array = (array)$this->autoMapper->map($entity$DTO);
  423.                 foreach ($array as $key => $value) {
  424.                     if (is_string($value)) {
  425.                         $array[$key] = mb_convert_encoding($value"UTF-8");
  426.                     }
  427.                 }
  428.                 $list[] = $array;
  429.             }
  430.         }
  431.         return $list;
  432.     }
  433.     public function getDistinctAttributeOfList($requestData$DTO null, callable $extraFilter null)
  434.     {
  435.         $entityName $this->getEntityName();
  436.         if ($requestData instanceof Request) {
  437.             $requestData $requestData->query->all();
  438.         }
  439.         if (isset($requestData['distinct_attribute'])) {
  440.             $attributeType 'attribute';
  441.         } else if (isset($requestData['distinct_relation'])) {
  442.             $attributeType 'relation';
  443.         } else return [];
  444.         $queryBuilder $this->createQueryBuilder($entityName);
  445.         if (!is_null($extraFilter)) {
  446.             $extraFilter($queryBuilder);
  447.         }
  448.         $this->setFilter($queryBuilder$requestData);
  449.         $this->setSort($queryBuilder$requestData);
  450.         if ($attributeType == 'attribute') {
  451.             $queryBuilder
  452.                 ->select($entityName '.' $requestData['distinct_attribute'])
  453.                 ->groupBy($entityName '.' $requestData['distinct_attribute']);
  454.         } else if ($attributeType == 'relation') {
  455.             $queryBuilder
  456.                 ->join($entityName '.' $requestData['distinct_relation'], $requestData['distinct_relation'])
  457.                 ->addSelect($requestData['distinct_relation'])
  458.                 ->addSelect('COUNT(' $entityName ') as count')
  459.                 ->groupBy($requestData['distinct_relation']);
  460.         }
  461.         $result $queryBuilder->getQuery()->getResult();
  462.         $attributeList = [];
  463.         foreach ($result as $entity) {
  464.             $attributeName $requestData[$attributeType == 'attribute' 'distinct_attribute' 'distinct_relation'];
  465.             $attribute $entity[0]->{'get' $attributeName}();
  466.             if ($attributeType == 'attribute') {
  467.                 $attributeList[] = [
  468.                     'value' => $attribute,
  469.                     'count' => (int)$entity['count'],
  470.                 ];
  471.             } else if ($attributeType == 'relation') {
  472.                 $array = !is_null($DTO)
  473.                     ? (array)$this->autoMapper->map($attribute$DTO)
  474.                     : (array)$attribute;
  475.                 foreach ($array as $key => $value) {
  476.                     if (is_string($value)) {
  477.                         $array[$key] = mb_convert_encoding($value"UTF-8");
  478.                     }
  479.                 }
  480.                 $array['count'] = (int)$entity['count'];
  481.                 $attributeList[] = $array;
  482.             }
  483.         }
  484.         return $attributeList;
  485.     }
  486.     public function entityToDtoArray($entity$DTO null)
  487.     {
  488.         $array = (array)$this->autoMapper->map($entity$DTO);
  489.         foreach ($array as $key => $value) {
  490.             if (is_string($value)) {
  491.                 $array[$key] = mb_convert_encoding($value"UTF-8");
  492.             }
  493.         }
  494.         return $array;
  495.     }
  496.     public function getEntityName()
  497.     {
  498.         return $this->commonService->getClassName($thistrue);
  499.     }
  500.     public function checkExistSlug($entity$value)
  501.     {
  502.         $id $entity->getId();
  503.         $conn $this->getEntityManager()->getConnection();
  504.         $stmt $conn->executeQuery(
  505.             'select count(id) as id from news where id != :id and slug = :slug',
  506.             [
  507.                 'id' => $id,
  508.                 'slug' => $value
  509.             ]
  510.         );
  511.         $result $stmt->fetchOne();
  512.         return (int) $result;
  513.     }
  514.     public function findOneBy(array $criteria, array $orderBy null)
  515.     {
  516.         $qb $this->createQueryBuilder('o');
  517.         foreach ($criteria as $criterion => $value) {
  518.             $qb
  519.                 ->andWhere('o.' $criterion ' = :' $criterion)
  520.                 ->setParameter($criterion$value);
  521.         }
  522.         $qb->setMaxResults(1);
  523.         $query $qb->getQuery();
  524.         $this->addTranslationWalkerToQuery($query);
  525.         return $query->getOneOrNullResult();
  526.     }
  527.     public function addTranslationWalkerToQuery($query)
  528.     {
  529.         // News, Program
  530.         $translatableEntities = [];
  531.         if (!in_array($this->getEntityName(), $translatableEntities)) return;
  532.         $config $this->_em->getConfiguration();
  533.         if ($config->getCustomHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION) === null) {
  534.             $config->addCustomHydrationMode(
  535.                 TranslationWalker::HYDRATE_OBJECT_TRANSLATION,
  536.                 'Gedmo\\Translatable\\Hydrator\\ORM\\ObjectHydrator'
  537.             );
  538.         }
  539.         $query->setHint(
  540.             \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
  541.             'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
  542.         );
  543.         $query->setHint(
  544.             \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,
  545.             $this->container->get('gedmo.listener.translatable')->getListenerLocale() // take locale from session or request etc.
  546.         );
  547.         $query->setHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION);
  548.         $query->setHint(\Doctrine\ORM\Query::HINT_REFRESHtrue);
  549.     }
  550. }