src/Repository/BaseRepository.php line 93

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)
  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.         $entities $queryBuilder->getQuery()->execute();
  402.         $list = [];
  403.         foreach ($entities as $entity) {
  404.             if (is_null($DTO)) {
  405.                 $outputDTO 'App\DTO\\' $this->getEntityName() . '\\' $this->getEntityName() . 'Output';
  406.                 if (class_exists($outputDTO)) {
  407.                     $DTO $outputDTO;
  408.                 }
  409.             }
  410.             if (is_null($DTO) || $DTO === 'ENTITY') {
  411.                 $list[] = $entity;
  412.             } else {
  413.                 $array = (array)$this->autoMapper->map($entity$DTO);
  414.                 foreach ($array as $key => $value) {
  415.                     if (is_string($value)) {
  416.                         $array[$key] = mb_convert_encoding($value"UTF-8");
  417.                     }
  418.                 }
  419.                 $list[] = $array;
  420.             }
  421.         }
  422.         return $list;
  423.     }
  424.     public function getDistinctAttributeOfList($requestData$DTO null, callable $extraFilter null)
  425.     {
  426.         $entityName $this->getEntityName();
  427.         if ($requestData instanceof Request) {
  428.             $requestData $requestData->query->all();
  429.         }
  430.         if (isset($requestData['distinct_attribute'])) {
  431.             $attributeType 'attribute';
  432.         } else if (isset($requestData['distinct_relation'])) {
  433.             $attributeType 'relation';
  434.         } else return [];
  435.         $queryBuilder $this->createQueryBuilder($entityName);
  436.         if (!is_null($extraFilter)) {
  437.             $extraFilter($queryBuilder);
  438.         }
  439.         $this->setFilter($queryBuilder$requestData);
  440.         $this->setSort($queryBuilder$requestData);
  441.         if ($attributeType == 'attribute') {
  442.             $queryBuilder
  443.                 ->select($entityName '.' $requestData['distinct_attribute'])
  444.                 ->groupBy($entityName '.' $requestData['distinct_attribute']);
  445.         } else if ($attributeType == 'relation') {
  446.             $queryBuilder
  447.                 ->join($entityName '.' $requestData['distinct_relation'], $requestData['distinct_relation'])
  448.                 ->addSelect($requestData['distinct_relation'])
  449.                 ->addSelect('COUNT(' $entityName ') as count')
  450.                 ->groupBy($requestData['distinct_relation']);
  451.         }
  452.         $result $queryBuilder->getQuery()->getResult();
  453.         $attributeList = [];
  454.         foreach ($result as $entity) {
  455.             $attributeName $requestData[$attributeType == 'attribute' 'distinct_attribute' 'distinct_relation'];
  456.             $attribute $entity[0]->{'get' $attributeName}();
  457.             if ($attributeType == 'attribute') {
  458.                 $attributeList[] = [
  459.                     'value' => $attribute,
  460.                     'count' => (int)$entity['count'],
  461.                 ];
  462.             } else if ($attributeType == 'relation') {
  463.                 $array = !is_null($DTO)
  464.                     ? (array)$this->autoMapper->map($attribute$DTO)
  465.                     : (array)$attribute;
  466.                 foreach ($array as $key => $value) {
  467.                     if (is_string($value)) {
  468.                         $array[$key] = mb_convert_encoding($value"UTF-8");
  469.                     }
  470.                 }
  471.                 $array['count'] = (int)$entity['count'];
  472.                 $attributeList[] = $array;
  473.             }
  474.         }
  475.         return $attributeList;
  476.     }
  477.     public function entityToDtoArray($entity$DTO null)
  478.     {
  479.         $array = (array)$this->autoMapper->map($entity$DTO);
  480.         foreach ($array as $key => $value) {
  481.             if (is_string($value)) {
  482.                 $array[$key] = mb_convert_encoding($value"UTF-8");
  483.             }
  484.         }
  485.         return $array;
  486.     }
  487.     public function getEntityName()
  488.     {
  489.         return $this->commonService->getClassName($thistrue);
  490.     }
  491.     public function checkExistSlug($entity$value)
  492.     {
  493.         $id $entity->getId();
  494.         $conn $this->getEntityManager()->getConnection();
  495.         $stmt $conn->executeQuery(
  496.             'select count(id) as id from news where id != :id and slug = :slug',
  497.             [
  498.                 'id' => $id,
  499.                 'slug' => $value
  500.             ]
  501.         );
  502.         $result $stmt->fetchOne();
  503.         return (int) $result;
  504.     }
  505.     public function findOneBy(array $criteria, array $orderBy null)
  506.     {
  507.         $qb $this->createQueryBuilder('o');
  508.         foreach ($criteria as $criterion => $value) {
  509.             $qb
  510.                 ->andWhere('o.' $criterion ' = :' $criterion)
  511.                 ->setParameter($criterion$value);
  512.         }
  513.         $qb->setMaxResults(1);
  514.         $query $qb->getQuery();
  515.         $this->addTranslationWalkerToQuery($query);
  516.         return $query->getOneOrNullResult();
  517.     }
  518.     public function addTranslationWalkerToQuery($query)
  519.     {
  520.         // News, Program
  521.         $translatableEntities = [];
  522.         if (!in_array($this->getEntityName(), $translatableEntities)) return;
  523.         $config $this->_em->getConfiguration();
  524.         if ($config->getCustomHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION) === null) {
  525.             $config->addCustomHydrationMode(
  526.                 TranslationWalker::HYDRATE_OBJECT_TRANSLATION,
  527.                 'Gedmo\\Translatable\\Hydrator\\ORM\\ObjectHydrator'
  528.             );
  529.         }
  530.         $query->setHint(
  531.             \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
  532.             'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
  533.         );
  534.         $query->setHint(
  535.             \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,
  536.             $this->container->get('gedmo.listener.translatable')->getListenerLocale() // take locale from session or request etc.
  537.         );
  538.         $query->setHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION);
  539.         $query->setHint(\Doctrine\ORM\Query::HINT_REFRESHtrue);
  540.     }
  541. }