src/Repository/BaseRepository.php line 549

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 && strpos($key'sorts_') === false) {
  358.                 continue;
  359.             }
  360.             $direction strpos($key'_asc') !== false 'ASC' 'DESC';
  361.             $isRelation strpos($value'Relation') !== false;
  362.             if ($isRelation) {
  363.                 $value str_replace('Relation'''$value);
  364.                 $fieldName $this->getEntityName() . '.' $value;
  365.                 $queryBuilder->leftJoin($fieldName$value);
  366.                 $queryBuilder->addOrderBy($value '.id'$direction);
  367.             } else {
  368.                 $fieldName $this->getEntityName() . '.' $value;
  369.                 $queryBuilder
  370.                     ->addSelect('CASE WHEN ' $fieldName ' IS NULL THEN 1 ELSE 0 END as HIDDEN ' $value '_is_null')
  371.                     ->addOrderBy($value '_is_null''ASC')
  372.                     ->addOrderBy($fieldName$direction)
  373.                     ;
  374.             }
  375.         }
  376.     }
  377.     public function getList($requestData$DTO null, callable $extraFilter null$fetchJoinCollection true)
  378.     {
  379.         if ($requestData instanceof Request) {
  380.             $requestData $requestData->query->all();
  381.         }
  382.         $queryBuilder $this->createQueryBuilder($this->getEntityName());
  383.         if (!is_null($extraFilter)) {
  384.             $extraFilter($queryBuilder);
  385.         }
  386.         $this->setFilter($queryBuilder$requestData);
  387.         $this->setSort($queryBuilder$requestData);
  388.         return $this->getPagingData($queryBuilder$requestData$DTO$fetchJoinCollection);
  389.     }
  390.     public function getAll($requestData$DTO null, callable $extraFilter null$returnQuery false)
  391.     {
  392.         if ($requestData instanceof Request) {
  393.             $requestData $requestData->query->all();
  394.         }
  395.         $queryBuilder $this->createQueryBuilder($this->getEntityName());
  396.         if (!is_null($extraFilter)) {
  397.             $extraFilter($queryBuilder);
  398.         }
  399.         $this->setFilter($queryBuilder$requestData);
  400.         $this->setSort($queryBuilder$requestData);
  401.         if ($returnQuery) {
  402.             return $queryBuilder->getQuery();
  403.         }
  404.         $entities $queryBuilder->getQuery()->execute();
  405.         $list = [];
  406.         foreach ($entities as $entity) {
  407.             if (is_null($DTO)) {
  408.                 $outputDTO 'App\DTO\\' $this->getEntityName() . '\\' $this->getEntityName() . 'Output';
  409.                 if (class_exists($outputDTO)) {
  410.                     $DTO $outputDTO;
  411.                 }
  412.             }
  413.             if (is_null($DTO) || $DTO === 'ENTITY') {
  414.                 $list[] = $entity;
  415.             } else {
  416.                 $array = (array)$this->autoMapper->map($entity$DTO);
  417.                 foreach ($array as $key => $value) {
  418.                     if (is_string($value)) {
  419.                         $array[$key] = mb_convert_encoding($value"UTF-8");
  420.                     }
  421.                 }
  422.                 $list[] = $array;
  423.             }
  424.         }
  425.         return $list;
  426.     }
  427.     public function getDistinctAttributeOfList($requestData$DTO null, callable $extraFilter null)
  428.     {
  429.         $entityName $this->getEntityName();
  430.         if ($requestData instanceof Request) {
  431.             $requestData $requestData->query->all();
  432.         }
  433.         if (isset($requestData['distinct_attribute'])) {
  434.             $attributeType 'attribute';
  435.         } else if (isset($requestData['distinct_relation'])) {
  436.             $attributeType 'relation';
  437.         } else return [];
  438.         $queryBuilder $this->createQueryBuilder($entityName);
  439.         if (!is_null($extraFilter)) {
  440.             $extraFilter($queryBuilder);
  441.         }
  442.         $this->setFilter($queryBuilder$requestData);
  443.         $this->setSort($queryBuilder$requestData);
  444.         if ($attributeType == 'attribute') {
  445.             $queryBuilder
  446.                 ->select($entityName '.' $requestData['distinct_attribute'])
  447.                 ->groupBy($entityName '.' $requestData['distinct_attribute']);
  448.         } else if ($attributeType == 'relation') {
  449.             $queryBuilder
  450.                 ->join($entityName '.' $requestData['distinct_relation'], $requestData['distinct_relation'])
  451.                 ->addSelect($requestData['distinct_relation'])
  452.                 ->addSelect('COUNT(' $entityName ') as count')
  453.                 ->groupBy($requestData['distinct_relation']);
  454.         }
  455.         $result $queryBuilder->getQuery()->getResult();
  456.         $attributeList = [];
  457.         foreach ($result as $entity) {
  458.             $attributeName $requestData[$attributeType == 'attribute' 'distinct_attribute' 'distinct_relation'];
  459.             $attribute $entity[0]->{'get' $attributeName}();
  460.             if ($attributeType == 'attribute') {
  461.                 $attributeList[] = [
  462.                     'value' => $attribute,
  463.                     'count' => (int)$entity['count'],
  464.                 ];
  465.             } else if ($attributeType == 'relation') {
  466.                 $array = !is_null($DTO)
  467.                     ? (array)$this->autoMapper->map($attribute$DTO)
  468.                     : (array)$attribute;
  469.                 foreach ($array as $key => $value) {
  470.                     if (is_string($value)) {
  471.                         $array[$key] = mb_convert_encoding($value"UTF-8");
  472.                     }
  473.                 }
  474.                 $array['count'] = (int)$entity['count'];
  475.                 $attributeList[] = $array;
  476.             }
  477.         }
  478.         return $attributeList;
  479.     }
  480.     public function entityToDtoArray($entity$DTO null)
  481.     {
  482.         $array = (array)$this->autoMapper->map($entity$DTO);
  483.         foreach ($array as $key => $value) {
  484.             if (is_string($value)) {
  485.                 $array[$key] = mb_convert_encoding($value"UTF-8");
  486.             }
  487.         }
  488.         return $array;
  489.     }
  490.     public function getEntityName()
  491.     {
  492.         return $this->commonService->getClassName($thistrue);
  493.     }
  494.     public function checkExistSlug($entity$value)
  495.     {
  496.         $id $entity->getId();
  497.         $conn $this->getEntityManager()->getConnection();
  498.         $stmt $conn->executeQuery(
  499.             'select count(id) as id from news where id != :id and slug = :slug',
  500.             [
  501.                 'id' => $id,
  502.                 'slug' => $value
  503.             ]
  504.         );
  505.         $result $stmt->fetchOne();
  506.         return (int) $result;
  507.     }
  508.     public function findOneBy(array $criteria, array $orderBy null)
  509.     {
  510.         $qb $this->createQueryBuilder('o');
  511.         foreach ($criteria as $criterion => $value) {
  512.             $qb
  513.                 ->andWhere('o.' $criterion ' = :' $criterion)
  514.                 ->setParameter($criterion$value);
  515.         }
  516.         $qb->setMaxResults(1);
  517.         $query $qb->getQuery();
  518.         $this->addTranslationWalkerToQuery($query);
  519.         return $query->getOneOrNullResult();
  520.     }
  521.     public function addTranslationWalkerToQuery($query)
  522.     {
  523.         // News, Program
  524.         $translatableEntities = [];
  525.         if (!in_array($this->getEntityName(), $translatableEntities)) return;
  526.         $config $this->_em->getConfiguration();
  527.         if ($config->getCustomHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION) === null) {
  528.             $config->addCustomHydrationMode(
  529.                 TranslationWalker::HYDRATE_OBJECT_TRANSLATION,
  530.                 'Gedmo\\Translatable\\Hydrator\\ORM\\ObjectHydrator'
  531.             );
  532.         }
  533.         $query->setHint(
  534.             \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
  535.             'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
  536.         );
  537.         $query->setHint(
  538.             \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,
  539.             $this->container->get('gedmo.listener.translatable')->getListenerLocale() // take locale from session or request etc.
  540.         );
  541.         $query->setHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION);
  542.         $query->setHint(\Doctrine\ORM\Query::HINT_REFRESHtrue);
  543.     }
  544. }