Files
kupshop/bundles/KupShop/ContentBundle/View/ArticlesView.php
2025-08-02 16:30:27 +02:00

514 lines
15 KiB
PHP

<?php
namespace KupShop\ContentBundle\View;
use KupShop\ComponentsBundle\View\ComponentsViewInterface;
use KupShop\ComponentsBundle\View\ComponentsViewTrait;
use KupShop\ContentBundle\Util\ArticleList;
use KupShop\ContentBundle\Util\BlocksTrait;
use KupShop\ContentBundle\Util\RecursiveTemplateFinderTrait;
use KupShop\I18nBundle\Translations\ArticlesAuthorsTranslation;
use KupShop\I18nBundle\Translations\ArticlesTagsTranslation;
use KupShop\KupShopBundle\Util\StringUtil;
use KupShop\KupShopBundle\Views\Traits\RequestTrait;
use KupShop\KupShopBundle\Views\View;
use Query\Operator;
use Query\QueryBuilder;
use Query\Translation;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ArticlesView extends View implements ComponentsViewInterface
{
use BlocksTrait;
use RequestTrait;
use ComponentsViewTrait;
use RecursiveTemplateFinderTrait;
protected $template = 'articles.tpl';
protected string $entrypoint = 'article';
protected $IDb;
protected $IDauthor;
protected $tagId;
private $cat;
private $catOrderBy;
private $catOrderDir;
private $catBehaviour;
private $sort;
/** @var ArticleList */
private $articleList;
private ?array $activeTag = null;
private array $dynamicFilter = [];
public function __construct(ArticleList $articleList)
{
$this->articleList = $articleList;
$this->proxyCacheEnabled = findModule(\Modules::PROXY_CACHE, 'content');
}
public function getResponse(?Request $request = null)
{
if (!findModule('articles')) {
redirection('MODUL_NOT_FOUND');
}
return parent::getResponse($request);
}
public function setIDb($IDb)
{
$this->IDb = $IDb;
}
public function setTagId(int $tagId): void
{
$this->tagId = $tagId;
}
public function setAuthorId(int $authorId): void
{
$this->IDauthor = $authorId;
}
public function setSort(?string $sort): void
{
$this->sort = $sort;
}
public function setDynamicFilter(array $dynamicFilter): void
{
$this->dynamicFilter = $dynamicFilter;
}
public function getCorrectUrl(): ?string
{
if ($this->IDb) {
$sectionSettings = $this->sectionSetting();
$urlCorrect = createScriptURL([
'URL' => 'launch.php',
's' => 'articles',
'IDb' => $this->IDb,
'TITLE' => $sectionSettings['name'] ?? null,
]);
} elseif ($this->tagId) {
$urlCorrect = createScriptURL([
'URL' => 'launch.php',
's' => 'articles_tags',
'ID' => $this->tagId,
]);
} elseif ($this->IDauthor) {
$urlCorrect = createScriptURL([
'URL' => 'launch.php',
's' => 'author',
'IDa' => $this->IDauthor,
'TITLE' => $this->getAuthor($this->IDauthor)['nick'],
]);
} else {
return null;
}
return $urlCorrect;
}
public function getMetaDescription()
{
return $this->cat['meta_description'] ?? strip_tags($this->cat['descr']) ?? parent::getMetaDescription();
}
public function getMetaTitle()
{
return $this->cat['meta_title'] ?? parent::getMetaTitle();
}
public function getBodyVariables()
{
$vars = parent::getBodyVariables();
// $this->IDb = $this->handleIDb();
if (empty($this->IDauthor)) {
$this->IDauthor = $this->handleIDauthor();
}
// nastaveni sekce
if (!empty($this->IDb)) {
$this->cat = $this->sectionSetting();
if (!$this->cat) {
$this->IDb = null;
}
}
// kdzy neni zadna sekce
if (empty($this->IDb)) {
$this->cat = $this->sectionSettingNoSection();
}
if (!empty($this->cat['template'])) {
if (findModule(\Modules::COMPONENTS)) {
$this->template = "articles/{$this->cat['template']}/articles.html.twig";
} else {
$this->template = 'fallback:articles.'.$this->cat['template'].'.tpl:'.$this->template;
}
}
$this->title = $this->cat['name'];
if ($activeTag = $this->getActiveTag()) {
$this->title = $activeTag['tag'];
}
$this->catOrderBy = $this->cat['orderby'];
$this->catOrderDir = $this->cat['orderdir'];
$this->catBehaviour = $this->cat['behaviour'];
$vars['returnNav'] = getReturnNavigation($this->IDb, 'ARTICLES_BRANCHES');
$vars['id'] = $this->IDb;
$vars['subCat'] = $this->getSubCat();
$vars['title'] = $this->cat['name'];
$vars['descr'] = $this->cat['descr'];
$vars['top_branch'] = $this->cat['top_branch'] ?? null;
$vars['pageDivider'] = '';
$vars['activeTag'] = $this->getActiveTag();
$pageNumber = (int) getVal('page', null, 1);
if ($pageNumber < 1 || $pageNumber > \Pager::INFINITE_PAGE_COUNT) {
throw new NotFoundHttpException();
}
$pager = $this->articleList->createPager($pageNumber);
$specs = $this->createQuery();
if (!empty($this->cat['items_per_page'])) {
$pager->setOnPage($this->cat['items_per_page']);
}
$specs[] = $this->getPagerSpec($pager);
$vars['articles'] = $this->articleList->getArticles(Operator::andX($specs));
$pager->setTotal($this->articleList->getTotalCount());
if ($pageNumber > $pager->count) {
$vars['pager'] = null;
} else {
$vars['pager'] = $pager;
}
if (findModule('articles_comments')) {
$vars['articles'] = $this->addComments($vars['articles']);
}
$vars['id_list_author'] = $this->IDauthor;
return $vars;
}
public function addComments($articles)
{
if (findModule('articles_comments')) {
$dbcfg = \Settings::getDefault();
$newArticles = $articles;
foreach ($articles as $key => $row) {
$count = sqlQueryBuilder()->select('COUNT(id) as count')
->from(getTableName('comments'))
->where('id_item=:IDart AND type="article"')
->setParameter('IDart', $row['artid'])
->execute()->fetch()['count'];
$date = sqlQueryBuilder()->select('DATE_FORMAT(date, "'.$dbcfg['date_format'].' '.$dbcfg['time_format'].'") as date')
->from(getTableName('comments'))
->where('id_item=:IDart AND type="article"')
->orderBy('id', 'DESC')
->setMaxResults(1)
->execute()->fetch()['date'];
$newArticles[$key]['comments'] = [
'count' => $count,
'lastCommentDate' => $date,
];
}
return $newArticles;
}
}
public function createQuery()
{
$this->articleList->setImage(1);
[$order, $orderDir] = $this->getSortParams();
$specs[] = function (QueryBuilder $qb) use ($order, $orderDir) {
$qb->orderBy($order, $orderDir);
};
if ($this->dynamicFilter) {
if ($this->dynamicFilter['tags'] ?? false) {
$specs[] = function (QueryBuilder $qb) {
$qb->andWhere(Operator::inIntArray($this->dynamicFilter['tags'], 'atr.id_tag'));
};
}
}
if ($this->tagId) {
$specs[] = function (QueryBuilder $qb) {
$qb->andWhere(Operator::equals(['atr.id_tag' => $this->tagId]));
};
}
if ($this->catBehaviour == 1) {
$specs[] = function (QueryBuilder $qb) {
$qb->andWhere(Operator::equals(['ar.id_branch' => $this->IDb]));
};
} elseif ($this->catBehaviour == 2) {
// ZOBRAZOVANI CLANKU V TETO SEKCI A JEJICH DCERINYCH SEKCICH
$cats = $this->from_cat($this->IDb);
$specs[] = function (QueryBuilder $qb) use ($cats) {
$qb->andWhere(Operator::inIntArray($cats, 'ar.id_branch'));
};
} elseif ($this->catBehaviour == 3) {
// ZOBRAZOVANI VSECH CLANKU
$specs[] = function (QueryBuilder $qb) {
$qb->andWhere(1);
};
} elseif ($this->catBehaviour == 4) {
$specs[] = function (QueryBuilder $qb) {
$qb->from('articles_authors_relation',
'aar')->andWhere('aar.id_art=a.id AND aar.id_auth=:IDauthor')->setParameter('IDauthor', $this->IDauthor);
};
}
return $specs;
}
public function from_cat($CatID, $return = [])
{
$return[] = $CatID;
$qb = sqlQueryBuilder()
->select('id')
->from(getTableName('articles_branches'))
->where('figure="Y" AND top_branch=:catID')
->setParameter('catID', $CatID)
->orderBy('id', 'ASC')
->execute();
foreach ($qb as $row) {
$return = $this->from_cat($row['id'], $return);
}
return $return;
}
public function getSubCat()
{
if (empty($this->IDauthor)) {
$spec = function (QueryBuilder $qb) {
$qb->andWhere(Operator::equals(['top_branch' => $this->IDb]))
->orderBy('position, name', 'ASC');
};
$qb = $this->articleList->getSections($spec);
$data = [];
foreach ($qb as $key => $row) {
$data[$key] = [
'id' => $row['id'],
'title' => $row['name'],
];
}
return $data;
}
return [];
}
public function sectionSetting()
{
$spec = function (QueryBuilder $qb) {
$qb->andWhere(Operator::equals(['ab.id' => $this->IDb]));
};
$section = $this->articleList->getSection($spec);
return $section;
}
public function sectionSettingNoSection()
{
$IDauthor = $this->IDauthor;
$qb = sqlQueryBuilder();
$cat = [];
$cat['name'] = translate('title', 'articles')['default'] ?? translate('title', 'articles')['default'];
$cat['descr'] = '';
if (empty($IDauthor)) {
$cat['descr'] = translate('default_descr', 'articles');
$cat['behaviour'] = 3;
} else {
$cat['behaviour'] = 4;
}
$cat['orderby'] = 'date';
$cat['orderdir'] = 'DESC';
if (!empty($IDauthor)) {
$author = $this->getAuthor($IDauthor);
$AuthName = $author['nick'];
if (!empty($AuthName)) {
$cat['name'] = str_replace('{AUTHOR}', $AuthName, translate('title', 'articles')['author']);
$cat['descr'] = translate('author_descr', 'articles');
} else {
unset($IDauthor);
}
}
return $cat;
}
public function handleIDb()
{
return intval(getVal('IDb'));
}
public function handleIDauthor()
{
return intval(getVal('IDauthor'));
}
public function getPrevNext($IDa, $param)
{
if (!empty($this->IDb)) {
$this->cat = $this->sectionSetting();
}
if (empty($this->IDb)) {
$this->cat = $this->sectionSettingNoSection();
}
$this->title = $this->cat['name'];
$this->catOrderBy = $this->cat['orderby'];
$this->catOrderDir = $this->cat['orderdir'];
$this->catBehaviour = $this->cat['behaviour'];
$specs = $this->createQuery();
$articles = $this->articleList->getArticles(Operator::andX($specs));
$articlesIds = array_column($articles, 'id');
$pos = 0;
foreach ($articlesIds as $key => $articleId) {
if ((string) $articleId == (string) $IDa) {
$pos = $key;
break;
}
}
if ($param == 'next') {
$pos--;
} elseif ($param == 'prev') {
$pos++;
}
if ($pos < 0) {
$pos = count($articlesIds) - 1;
} elseif ($pos > count($articlesIds) - 1) {
$pos = 0;
}
return $articlesIds[$pos];
}
protected function getPagerSpec(\Pager $pager): callable
{
return $pager->getSpec();
}
protected function getSortParams(): array
{
$orderBy = $this->sort ?? $this->catOrderBy;
$orderDir = $this->sort ? 'ASC' : $this->catOrderDir;
if (StringUtil::startsWith($orderBy, '-')) {
$orderBy = ltrim($orderBy, '-');
$orderDir = 'DESC';
}
switch ($orderBy) {
case 'date':
$order = 'a.date';
break;
case 'title':
$order = 'a.title';
break;
case 'rating':
$order = 'a.rating';
break;
case 'seen':
$order = 'a.seen';
break;
default:
$order = 'a.date';
break;
}
return [$order, $orderDir];
}
private function getActiveTag(): ?array
{
if (!$this->tagId) {
return null;
}
if (!$this->activeTag) {
$tag = 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))
->andWhere(Operator::equals(['at.id' => $this->tagId]))
->groupBy('at.id')
->execute()->fetchAssociative();
$this->activeTag = $tag ?: null;
}
return $this->activeTag;
}
protected function getAuthor(int $authorId)
{
if (isset($this->author)) {
return $this->author;
}
$author = sqlQueryBuilder()
->select('*')
->from('articles_authors', 'au')
->where(Operator::equals(['au.id' => $authorId]))
->andWhere(Translation::coalesceTranslatedFields(ArticlesAuthorsTranslation::class))
->execute()
->fetchAssociative();
$author['photo'] = getImage($authorId, null, '../authors', 'articles_authors', '', strtotime($author['date_update']));
$author['nick'] = empty($author['nick']) ? $author['name'].' '.$author['surname'] : $author['nick'];
$this->author = $author;
return $this->author;
}
public function getBreadcrumbsNew(): array
{
if (findModule(\Modules::COMPONENTS)) {
$breadcrumbs = getReturnNavigation($this->IDb, 'ARTICLES_BRANCHES');
return reset($breadcrumbs);
}
return parent::getBreadcrumbsNew();
}
public function getTemplates(): iterable
{
yield from $this->getTemplatesFromPath(__DIR__.'/../../../../../shop/twig/articles', 'articles.html.twig', 'articles');
// default template
yield $this->getTemplate();
}
}