src/Repository/BaseRepository.php line 88

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