Files
kupshop/bundles/KupShop/CommentsBundle/Util/CommentList.php
2025-08-02 16:30:27 +02:00

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
);
}
}