Skip to content
Snippets Groups Projects
QuestRepository.php 5.32 KiB
Newer Older
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
<?php

namespace App\Repository;

use App\Entity\Quest;
use App\Redis\RedisFilter;
use App\Service\Dto\Classes\FilterDto;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use App\Service\Response\Classes\Data\Pagination;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use DateInterval;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Query\QueryException;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Doctrine\ORM\QueryBuilder;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Doctrine\ORM\Tools\Pagination\Paginator;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
use Doctrine\Persistence\ManagerRegistry;

/**
 * @extends ServiceEntityRepository<Quest>
 */
class QuestRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Quest::class);
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    /**
     * Получение всех квестов по фильтру
     *
     * @param int $userId
     *
     * @return array
     */
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    public function findAllByFilter(int $userId): array
    {
        $queryBuilder = $this->getFilterQuery($userId);
        return $queryBuilder->getQuery()->getResult();
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    /**
     * Получение всех квестов по фильтру постранично
     *
     * @param int $userId
     * @param int $page
     * @param int $limit
     *
     * @return Pagination
     */
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    public function findAllByFilterPaged(int $userId, int $page = 1, int $limit = 10): Pagination
    {
        $queryBuilder = $this->getFilterQuery($userId);

        $paginator = new Paginator($queryBuilder->getQuery());

        $result = new Pagination();

        $maxCount = count($paginator);

        $maxPage = ceil($maxCount / $limit);

        if ($page > $maxPage) {
            $page = (int)$maxPage;
        }
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        if ($page > 0) {
            $result->page = $page;
            $result->maxPage = $maxPage;
            $result->limit = $limit;

            $paginator->getQuery()
                ->setFirstResult(($page - 1) * $limit)
                ->setMaxResults($limit);
        }
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed

        $result->quests = $paginator->getQuery()->getResult();

        return $result;
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    /**
     * Получение пройденных квестов
     *
     * @param int $userId
     *
     * @return array
     *
     * @throws QueryException
     */
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    public function findCompletedByFilter(int $userId): array
    {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $queryBuilder = $this->getBaseQuery();

        $criteria = Criteria::create();
        $expr = Criteria::expr();

        if (!$expr) {
            return [];
        }
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed

        $currentDate = new \DateTime();
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $criteria
            ->andWhere($expr->lt('date', $currentDate))
            ->andWhere($expr->eq('appointments.related_user', $userId));
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $queryBuilder->addCriteria($criteria);
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed

        return $queryBuilder->getQuery()->getResult();
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    /**
     * Получение квеста
     *
     * @param int $id
     * @param int $userId
     * @param bool $cache
     *
     * @return Quest|null
     */
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    public function findOneById(int $id, int $userId, bool $cache = true): ?Quest
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $queryBuilder = $this->getBaseQuery();
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $queryBuilder->setParameter('detail_id', $id)
            ->andWhere('q.id = :detail_id');
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $query = $queryBuilder->getQuery();
        if ($cache) {
            $query->enableResultCache(3600, $id);
        }
        return $query->getOneOrNullResult();
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    /**
     * Получение квестов по критерии
     *
     * @param Criteria $criteria
     *
     * @return array
     */
    public function getByCriteria(Criteria $criteria): array
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        return $this->getQueryByCriteria($criteria)->getQuery()->getResult();
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    private function getBaseQuery(): QueryBuilder
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        return $this->createQueryBuilder('q')
            ->leftJoin('q.genre', 'genre')
            ->leftJoin('q.theme', 'theme')
            ->leftJoin('q.tags', 'tags')
            ->leftJoin('q.appointments', 'appointments')
            ->leftJoin('q.reviews', 'reviews');
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    private function getQueryByCriteria(Criteria $criteria): QueryBuilder
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $queryBuilder = $this->getBaseQuery();
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $queryBuilder->addCriteria($criteria);
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        return $queryBuilder;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    }

i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    private function getFilterQuery(int $userId): QueryBuilder
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    {
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
        $redisFilter = new RedisFilter($userId);
        $filter = $redisFilter->get();
        if ($filter instanceof FilterDto) {
            $criteria = $filter->getCriteria();
            $queryBuilder = $this->getQueryByCriteria($criteria);
        } else {
            $queryBuilder = $this->getBaseQuery();
        }
        return $queryBuilder;
i.vasilenko@iq-adv.ru's avatar
i.vasilenko@iq-adv.ru committed
    }

    //    /**
    //     * @return Quest[] Returns an array of Quest objects
    //     */
    //    public function findByExampleField($value): array
    //    {
    //        return $this->createQueryBuilder('q')
    //            ->andWhere('q.exampleField = :val')
    //            ->setParameter('val', $value)
    //            ->orderBy('q.id', 'ASC')
    //            ->setMaxResults(10)
    //            ->getQuery()
    //            ->getResult()
    //        ;
    //    }

    //    public function findOneBySomeField($value): ?Quest
    //    {
    //        return $this->createQueryBuilder('q')
    //            ->andWhere('q.exampleField = :val')
    //            ->setParameter('val', $value)
    //            ->getQuery()
    //            ->getOneOrNullResult()
    //        ;
    //    }
}