deblan.io-murph/src/Repository/Blog/PostRepositoryQuery.php

122 lines
3.1 KiB
PHP

<?php
namespace App\Repository\Blog;
use App\Core\Repository\RepositoryQuery;
use App\Entity\Blog\Category;
use Knp\Component\Pager\PaginatorInterface;
/**
* class PostRepositoryQuery.
*
* @author Simon Vieille <simon@deblan.fr>
*/
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)
;
}
}