254 lines
9.2 KiB
PHP
254 lines
9.2 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ContentBundle\Util;
|
|
|
|
use KupShop\I18nBundle\Translations\ArticlesTagsTranslation;
|
|
use KupShop\I18nBundle\Translations\ArticlesTranslation;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use Query\Operator;
|
|
use Query\QueryBuilder;
|
|
use Query\Translation;
|
|
use Symfony\Contracts\Service\Attribute\Required;
|
|
|
|
class ArticlesUtil
|
|
{
|
|
#[Required]
|
|
public LanguageContext $languageContext;
|
|
|
|
#[Required]
|
|
public ArticleList $articleList;
|
|
|
|
public function getArticleSections($topSection = null)
|
|
{
|
|
$sectionsCacheName = "article-sections-{$this->languageContext->getActiveId()}";
|
|
if (isset($topSection)) {
|
|
$sectionsCacheName .= '-'.$topSection;
|
|
}
|
|
if ($cache = getCache($sectionsCacheName)) {
|
|
$sections = $cache;
|
|
} else {
|
|
$sections = $this->articleList->getSectionsTree($topSection);
|
|
setCache($sectionsCacheName, $sections);
|
|
}
|
|
|
|
return $sections;
|
|
}
|
|
|
|
public function getArticleTags($idArticle, $onlyActive = null)
|
|
{
|
|
if (!findModule(\Modules::ARTICLES)) {
|
|
return null;
|
|
}
|
|
|
|
$qb = sqlQueryBuilder()
|
|
->select('at.*, COUNT(atr.id_article) as count')
|
|
->from('articles_tags', 'at')
|
|
->leftJoin('at', 'articles_tags_relation', 'atr', 'atr.id_tag = at.id')
|
|
->andWhere(Translation::coalesceTranslatedFields(ArticlesTagsTranslation::class))
|
|
->groupBy('at.id')
|
|
->orderBy('at.tag');
|
|
|
|
if ($idArticle) {
|
|
$qb->andWhere(Operator::equals(['atr.id_article' => $idArticle]));
|
|
}
|
|
|
|
if ($onlyActive) {
|
|
$qb->leftJoin('atr', 'articles', 'a', 'atr.id_article = a.id')
|
|
->andWhere('a.date <= NOW()');
|
|
$qb->andWhere(Translation::joinTranslatedFields(ArticlesTranslation::class,
|
|
function (QueryBuilder $qb, $columnName, $translatedField) {
|
|
$qb->andWhere(Operator::coalesce($translatedField, 'a.figure').' = "Y" ');
|
|
},
|
|
['figure']));
|
|
$qb->having('count > 0');
|
|
}
|
|
|
|
return $qb->execute()->fetchAll();
|
|
}
|
|
|
|
public function getArticles($params)
|
|
{
|
|
$defaults = [
|
|
'count' => null,
|
|
'section' => null,
|
|
'section_id' => null,
|
|
'product_id' => null,
|
|
'id' => null,
|
|
'section_id_exclude' => [],
|
|
'related' => [],
|
|
'related_symmetric' => false,
|
|
'tag' => null,
|
|
'assign' => null,
|
|
'order_by' => 'a.date',
|
|
'order' => 'DESC',
|
|
'require_tag' => null,
|
|
'image' => 1,
|
|
];
|
|
|
|
$params = array_merge($defaults, $params);
|
|
|
|
if (empty($params['section']) && empty($params['section_id']) && empty($params['product_id']) && empty($params['tag']) && empty($params['id']) && empty($params['related'])) {
|
|
echo "Použij parametr 'section' nebo 'section_id' nebo 'product_id' nebo 'tag' nebo 'id' nebo 'related'";
|
|
}
|
|
|
|
if ($params['tag'] && !is_array($params['tag'])) {
|
|
$params['tag'] = [$params['tag']];
|
|
}
|
|
|
|
$spec_section = null;
|
|
if ($params['section'] != 'all') {
|
|
$spec_section = function (QueryBuilder $qb) use ($params) {
|
|
$qb->andWhere('(ab.name=:section OR ab.id=:section_id)')
|
|
->setParameters(['section' => $params['section'], 'section_id' => $params['section_id']]);
|
|
};
|
|
}
|
|
|
|
return [
|
|
'section' => $this->articleList->getSection($spec_section),
|
|
'articles' => $this->getArticlesWithFallback($params, $defaults),
|
|
];
|
|
}
|
|
|
|
private function getArticlesWithFallback(array $params, array $defaultParams): array
|
|
{
|
|
if (!empty($params['section_id_exclude'])) {
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->andWhere(
|
|
Operator::not(
|
|
Operator::inIntArray($params['section_id_exclude'], 'ar.id_branch')
|
|
)
|
|
);
|
|
};
|
|
}
|
|
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
if (is_array($params['order_by'])) {
|
|
$qb->orderBy('FIELD(a.id, :orderByArticlesId)')
|
|
->setParameter('orderByArticlesId', $params['order_by'], \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
|
|
} else {
|
|
$qb->orderBy($params['order_by'], $params['order']);
|
|
}
|
|
};
|
|
|
|
if (isset($params['section_id']) && $params['section'] != 'all') {
|
|
$sectionIds = [$params['section_id']];
|
|
|
|
if ($filterSection = $this->articleList->getSectionById((int) $params['section_id'])) {
|
|
$this->getFilterSectionsIdsRecursively($filterSection, $sectionIds);
|
|
}
|
|
|
|
$specs[] = Operator::inIntArray($sectionIds, 'ar.id_branch');
|
|
}
|
|
|
|
if ($params['count'] > 0) {
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->setMaxResults($params['count']);
|
|
};
|
|
}
|
|
|
|
if ($params['product_id']) {
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->join('a', 'products_in_articles', 'pia', 'pia.id_article = a.id')
|
|
->andWhere('pia.id_product=:id_product')->setParameter('id_product', $params['product_id']);
|
|
};
|
|
}
|
|
|
|
if ($params['id']) {
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->andWhere(Operator::inIntArray((array) $params['id'], 'a.id'));
|
|
};
|
|
}
|
|
|
|
if ($params['tag']) {
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->leftJoin('a', 'articles_tags_relation', 'atr', 'a.id = atr.id_article')
|
|
->andWhere(Operator::inIntArray($params['tag'], 'atr.id_tag'));
|
|
};
|
|
}
|
|
|
|
if ($params['require_tag']) {
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->join('a', 'articles_tags_relation', 'atr2', 'a.id = atr2.id_article')
|
|
->andWhere(Operator::equals(['atr2.id_tag' => $params['require_tag']]));
|
|
};
|
|
}
|
|
|
|
if (!empty($params['exclude_articles'])) {
|
|
if (!is_array($params['exclude_articles'])) {
|
|
$params['exclude_articles'] = [$params['exclude_articles']];
|
|
}
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->andWhere(Operator::not(Operator::inIntArray($params['exclude_articles'], 'a.id')));
|
|
};
|
|
}
|
|
|
|
if (!empty($params['related'])) {
|
|
$specs[] = function (QueryBuilder $qb) use ($params) {
|
|
$qb->leftJoin('a', 'articles_related', 'arr', 'a.id = arr.id_article_related')
|
|
->orderBy('arr.position');
|
|
|
|
$orX = [Operator::inIntArray((array) $params['related'], 'arr.id_article')];
|
|
|
|
if ($params['related_symmetric'] ?? false) {
|
|
$qb->leftJoin('a', 'articles_related', 'arr2', 'a.id = arr2.id_article');
|
|
$orX[] = Operator::inIntArray((array) $params['related'], 'arr2.id_article_related');
|
|
}
|
|
|
|
$andX = [Operator::orX($orX)];
|
|
|
|
if (findModule(\Modules::ARTICLES_RELATED_TYPES) && !empty($params['related_type'])) {
|
|
$andX[] = Operator::inIntArray((array) $params['related_type'], 'arr.type');
|
|
if (!empty($params['related_symmetric'])) {
|
|
$andX[] = Operator::inIntArray((array) $params['related_type'], 'arr2.type');
|
|
}
|
|
}
|
|
|
|
$qb->andWhere(Operator::andX($andX));
|
|
};
|
|
}
|
|
|
|
if ($params['image']) {
|
|
$this->articleList->setImage($params['image']);
|
|
}
|
|
|
|
$articles = $this->articleList->getArticles(Operator::andX($specs));
|
|
$count = count($articles);
|
|
|
|
if (!empty($params['count']) && $count < $params['count'] && !empty($params['fallback'])) {
|
|
$fallback = $params['fallback'];
|
|
unset($params['fallback']);
|
|
|
|
foreach ($fallback as $fallbackParams) {
|
|
if ($count >= $params['count']) {
|
|
break;
|
|
}
|
|
|
|
$fallbackParams = array_merge($defaultParams, $fallbackParams, [
|
|
'count' => $params['count'] - $count,
|
|
]);
|
|
|
|
$fallbackArticles = $this->getArticlesWithFallback($fallbackParams, $defaultParams);
|
|
$count += count($fallbackArticles);
|
|
|
|
$articles = array_merge($articles, $fallbackArticles);
|
|
}
|
|
}
|
|
|
|
return $articles;
|
|
}
|
|
|
|
private function getFilterSectionsIdsRecursively(array $section, array &$filterIds): void
|
|
{
|
|
// pokud je nastaveno "Zobrazovat jen články v sekci", tak nenacitam IDcka podsekci
|
|
if (($section['behaviour'] ?? null) != 2) {
|
|
return;
|
|
}
|
|
|
|
// pokud je u sekce zaksrnuto "Zobrazovat články v této sekci a jejích podsekcích"
|
|
foreach ($section['children'] ?? [] as $child) {
|
|
$filterIds[] = $child['id'];
|
|
$this->getFilterSectionsIdsRecursively($child, $filterIds);
|
|
}
|
|
}
|
|
}
|