117 lines
3.4 KiB
PHP
117 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace KupShop\CommentsBundle\Util;
|
|
|
|
use Doctrine\DBAL\Connection;
|
|
use Doctrine\DBAL\Query\QueryBuilder;
|
|
use KupShop\CommentsBundle\Comment;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use Query\Operator;
|
|
|
|
class CommentList
|
|
{
|
|
public const ITEMS_PER_PAGE = 10;
|
|
|
|
protected $specs = [];
|
|
|
|
private $commentsUtil;
|
|
|
|
private $languageContext;
|
|
|
|
public function __construct(CommentsUtil $commentsUtil, LanguageContext $languageContext)
|
|
{
|
|
$this->commentsUtil = $commentsUtil;
|
|
$this->languageContext = $languageContext;
|
|
}
|
|
|
|
public function getComments(int $objectId, string $type, ?string $languageId = null, ?int &$totalCount = null): array
|
|
{
|
|
if (!$languageId) {
|
|
$languageId = $this->languageContext->getActiveId();
|
|
}
|
|
|
|
$qb = $this->createQueryBuilder()
|
|
->from('ancestors AS a')
|
|
->andWhere('c.id_parent = a.id');
|
|
|
|
$rootCommentIds = $this->getRootCommentIds($objectId, $type, $languageId, $totalCount);
|
|
|
|
$comments = sqlQuery(
|
|
'WITH RECURSIVE ancestors as (
|
|
SELECT * FROM comments WHERE id IN (:ids)
|
|
UNION
|
|
'.$qb->getSQL().'
|
|
) SELECT * FROM ancestors ORDER BY FIELD(id, :ids)',
|
|
array_merge($qb->getParameters(), ['ids' => $rootCommentIds]),
|
|
array_merge($qb->getParameterTypes(), ['ids' => Connection::PARAM_INT_ARRAY])
|
|
)->fetchAll();
|
|
|
|
return $this->commentsUtil->buildCommentsTree(
|
|
$this->commentsUtil->loadComments($comments)
|
|
);
|
|
}
|
|
|
|
public function createPager(int $page): \Pager
|
|
{
|
|
$pager = new \Pager();
|
|
$pager->setOnPage(self::ITEMS_PER_PAGE);
|
|
$pager->setPageNumber($page);
|
|
|
|
return $pager;
|
|
}
|
|
|
|
public function andSpec(callable $spec): self
|
|
{
|
|
$this->specs[] = $spec;
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function createQueryBuilder(bool $useTotalCount = false): QueryBuilder
|
|
{
|
|
return sqlQueryBuilder()
|
|
->select($useTotalCount ? 'SQL_CALC_FOUND_ROWS c.*' : 'c.*')
|
|
->from('comments', 'c')
|
|
->where(
|
|
Operator::inIntArray(
|
|
[
|
|
Comment::STATUS_CONFIRMED,
|
|
Comment::STATUS_TOP,
|
|
],
|
|
'c.status'
|
|
)
|
|
);
|
|
}
|
|
|
|
private function getRootCommentIds(int $objectId, string $type, string $languageId, ?int &$totalCount = null): array
|
|
{
|
|
$useTotalCount = $totalCount !== null;
|
|
|
|
$comments = $this->createQueryBuilder($useTotalCount)
|
|
->andWhere('id_parent IS NULL')
|
|
->andWhere(
|
|
Operator::equals(
|
|
[
|
|
'id_language' => $languageId,
|
|
$this->commentsUtil->getObjectField($type) => $objectId,
|
|
]
|
|
)
|
|
)
|
|
->orderBy('c.status', 'DESC')
|
|
->addOrderBy('c.date_add', 'DESC')
|
|
->andWhere(Operator::andX($this->specs))
|
|
->execute()->fetchAll();
|
|
|
|
if ($useTotalCount) {
|
|
$totalCount = (int) sqlFetchAssoc(sqlQuery('SELECT FOUND_ROWS() as total_count'))['total_count'];
|
|
}
|
|
|
|
return array_map(
|
|
function ($x) {
|
|
return $x['id'];
|
|
},
|
|
$comments
|
|
);
|
|
}
|
|
}
|