*/ class PostRepositoryQuery extends RepositoryQuery { public function __construct(PostRepository $repository, PaginatorInterface $paginator) { parent::__construct($repository, 'p', $paginator); } public function inCategory(Category $category) { $c = 'c'.mt_rand(); $this ->innerJoin('p.categories', $c) ->andWhere($c.'.id = :category') ->setParameter(':category', $category->getId()) ; return $this; } public function published() { return $this ->andWhere('.status = 1') ->andWhere('.publishedAt <= :now') ->setParameter(':now', (new \DateTime('now'))->format('Y-m-d H:i:s')) ; } public function useFilters(array $filters) { foreach ($filters as $name => $value) { if (null === $value) { continue; } if (is_int($value)) { $this->andWhere('.'.$name.' = :'.$name); $this->setParameter(':'.$name, $value); } elseif (is_string($value)) { $this->andWhere('.'.$name.' LIKE :'.$name); $this->setParameter(':'.$name, '%'.$value.'%'); } else { if ('category' === $name) { $this->inCategory($value); } } } return $this; } public function search(string $keywords) { $conn = $this->repository->getEm()->getConnection(); $statement = $conn->prepare( 'SELECT post.id, post.title, MATCH(post.title) AGAINST(:search) AS MATCH_TITLE, MATCH(post.content) AGAINST(:search) AS MATCH_CONTENT FROM post WHERE post.status = 1 AND post.published_at < :date ORDER BY MATCH_TITLE DESC, MATCH_CONTENT DESC '); $statement->execute([ ':search' => $keywords, ':date' => (new \DateTime())->format('Y-m-d H:i:s'), ]); $results = $statement->fetchAll(); $ids = []; foreach ($results as $k => $v) { $rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT']; if ($rate >= 7) { $ids[] = $v['id']; } } if (0 == count($ids)) { foreach ($results as $k => $v) { $rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT']; if ($rate >= 6) { $ids[] = $v['id']; } } } if (!$ids) { $ids = [-1]; } return $this ->orderBy('FIELD(p.id, :ids)') ->andWhere('.id IN(:ids)') ->setParameter(':ids', $ids) ; } }