397 lines
12 KiB
PHP
397 lines
12 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ContentBundle\View;
|
|
|
|
use KupShop\ComponentsBundle\View\ComponentsViewInterface;
|
|
use KupShop\ComponentsBundle\View\ComponentsViewTrait;
|
|
use KupShop\ContentBundle\Util\Block;
|
|
use KupShop\ContentBundle\Util\InlineEdit;
|
|
use KupShop\ContentBundle\Util\RecursiveTemplateFinderTrait;
|
|
use KupShop\I18nBundle\Translations\ArticlesAuthorsTranslation;
|
|
use KupShop\I18nBundle\Translations\ArticlesTagsTranslation;
|
|
use KupShop\KupShopBundle\Util;
|
|
use KupShop\KupShopBundle\Util\StringUtil;
|
|
use KupShop\KupShopBundle\Views\Traits\RequestTrait;
|
|
use KupShop\KupShopBundle\Views\View;
|
|
use Query\Operator;
|
|
use Query\Translation;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
class ArticleView extends View implements ComponentsViewInterface
|
|
{
|
|
use RequestTrait;
|
|
use ComponentsViewTrait;
|
|
use RecursiveTemplateFinderTrait;
|
|
|
|
protected $template = 'article.tpl';
|
|
protected string $entrypoint = 'article';
|
|
|
|
protected $IDa;
|
|
|
|
private $articleBlocks;
|
|
|
|
private $article;
|
|
|
|
public function __construct(protected Block $block, private InlineEdit $inlineEdit, protected Util\RequestUtil $requestUtil)
|
|
{
|
|
$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 getBodyVariables()
|
|
{
|
|
$vars = parent::getBodyVariables();
|
|
|
|
$article = $this->getArticle();
|
|
$vars['article'] = [
|
|
'id' => $this->IDa,
|
|
'title' => $article['title'],
|
|
'image' => leadImage($this->IDa, 1, 'ARTICLE'),
|
|
'lead' => $article['lead_in'],
|
|
'source' => $article['source'],
|
|
'date' => $article['datef'],
|
|
'body' => $this->getArticleBody(),
|
|
'seen' => $article['seen'],
|
|
'parts' => [],
|
|
'authors' => [],
|
|
'blocks' => $this->getArticleBlocks(),
|
|
'data' => $article['data'],
|
|
'id_branch' => $article['id_branch'],
|
|
'section' => ['name' => $article['section_name'] ?? '', 'id' => $article['id_branch'] ?? 0],
|
|
'id_block' => $article['id_block'],
|
|
];
|
|
$this->title = $article['title'];
|
|
|
|
$vars['returnNav'] = $this->getReturnNav($article['title']);
|
|
$vars['printPreview'] = $this->handlePrint();
|
|
|
|
$vars['article']['authors'] = $this->getArticleAuthors();
|
|
$vars['article']['photos'] = $this->getArticleImages();
|
|
$vars['article']['tags'] = $this->getArticleTags();
|
|
|
|
return $vars;
|
|
}
|
|
|
|
public function getShowInSearch(): bool
|
|
{
|
|
return ($this->getArticle()['show_in_search'] ?? false) === 'Y';
|
|
}
|
|
|
|
public function getWpjToolbar()
|
|
{
|
|
if ($this->IDa > 0) {
|
|
$url = getAdminUrl('articles', ['ID' => $this->IDa]);
|
|
|
|
$arr = [
|
|
'url' => $url,
|
|
'title' => 'Upravit článek',
|
|
];
|
|
|
|
return array_merge(parent::getWpjToolbar(), $arr);
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
protected function getObjectInfo()
|
|
{
|
|
$object_info = [
|
|
'type' => 'articles',
|
|
'id' => $this->IDa,
|
|
'name' => (translate('objects', 'blocks', true, true)['article'] ?? 'article').': '.$this->getArticle()['title'] ?? '',
|
|
];
|
|
|
|
return json_encode($object_info);
|
|
}
|
|
|
|
public function getArticleBody()
|
|
{
|
|
$body = ['title' => '', 'body' => ''];
|
|
foreach ($this->getArticleBlocks() as $block) {
|
|
$wrapped = $this->inlineEdit->wrapBlock($block);
|
|
$body['body'] .= $wrapped['content'];
|
|
}
|
|
|
|
return $body;
|
|
}
|
|
|
|
public function getArticleBlocks()
|
|
{
|
|
if ($this->articleBlocks) {
|
|
return $this->articleBlocks;
|
|
}
|
|
|
|
$article = $this->getArticle();
|
|
|
|
if ($id_block = $article['id_block'] ?? null) {
|
|
$blocks = $this->block->getBlocks($id_block);
|
|
$object_info = $this->getObjectInfo();
|
|
$this->articleBlocks = array_map(function ($block) use ($object_info) {
|
|
$block['object_info'] = $object_info;
|
|
|
|
return $block;
|
|
}, $blocks);
|
|
} else {
|
|
$this->articleBlocks = [
|
|
[
|
|
'id_object' => $this->IDa,
|
|
'type' => 'articles',
|
|
],
|
|
];
|
|
}
|
|
|
|
return $this->articleBlocks;
|
|
}
|
|
|
|
public function getArticle()
|
|
{
|
|
global $cfg;
|
|
|
|
if ($this->article) {
|
|
return $this->article;
|
|
}
|
|
|
|
$dbcfg = \Settings::getDefault();
|
|
$article = false;
|
|
|
|
$qb = sqlQueryBuilder()
|
|
->select('a.show_in_search, a.id', 'a.title', 'a.id_block', 'a.source', 'DATE_FORMAT(a.date, "'.$dbcfg['date_format'].' '.$dbcfg['time_format'].'") AS datef',
|
|
'a.lead_in', 'a.seen', 'a.comments', 'a.comment_question', 'a.rating_value', 'a.rating_voted', 'a.type, a.link', 'a.figure', 'a.data',
|
|
'ab.template AS branch_template, a.url, a.meta_title, a.meta_description, ar.id_branch, ab.name as section_name', 'a.date > NOW() AS dateunactive')
|
|
->from('articles', 'a')
|
|
->leftJoin('a', 'articles_relation', 'ar', 'ar.id_art=a.id')
|
|
->leftJoin('ar', 'articles_branches', 'ab', 'ab.id=ar.id_branch')
|
|
->where('a.id=:IDa')
|
|
->setMaxResults(1)
|
|
->setParameter('IDa', $this->IDa)
|
|
->groupBy('a.id');
|
|
|
|
// join translations
|
|
$qb->andWhere(
|
|
Translation::adminAlwaysVisible(
|
|
\Query\Translation::coalesceTranslatedFields(
|
|
\KupShop\I18nBundle\Translations\ArticlesTranslation::class
|
|
)
|
|
)
|
|
);
|
|
|
|
if (!($article = $qb->execute()->fetchAssociative())) {
|
|
throw new NotFoundHttpException('Article not found');
|
|
}
|
|
|
|
if (($article['dateunactive'] or ($article['figure'] != 'Y')) and !getAdminUser()) {
|
|
throw new NotFoundHttpException('Invisible article');
|
|
}
|
|
|
|
$article['seo_url'] = !empty($article['url']) ? $article['url'] : StringUtil::slugify($article['title']);
|
|
|
|
// pokud clanek slouzi jen jako presmerovani
|
|
if ($article['type'] == 'L' && $article['link'] != '') {
|
|
if (strpos($article['link'], $cfg['Addr']['full']) !== false || $article['link'][0] == '/') {
|
|
$url = $article['link'];
|
|
} else {
|
|
$url = createScriptURL([
|
|
'URL' => 'launch.php',
|
|
's' => 'redir',
|
|
'link' => urlencode($article['link']),
|
|
'ESCAPE' => 'NO',
|
|
]);
|
|
}
|
|
|
|
redirection($url);
|
|
}
|
|
|
|
if (!empty($article['branch_template'])) {
|
|
if (findModule(\Modules::COMPONENTS)) {
|
|
$this->template = "articles/{$article['branch_template']}/article.html.twig";
|
|
} else {
|
|
$this->template = 'fallback:article.'.$article['branch_template'].'.tpl:'.$this->template;
|
|
}
|
|
}
|
|
|
|
// zobrazeni
|
|
if (!isset($_GET['comment']) && !isset($_GET['part'])) {
|
|
$this->updateArticleSeen();
|
|
$article['seen']++;
|
|
}
|
|
|
|
$article['data'] = json_decode($article['data'], true);
|
|
|
|
return $this->article = $article;
|
|
}
|
|
|
|
public function getArticleImages()
|
|
{
|
|
$data = [];
|
|
$qb = sqlQueryBuilder()
|
|
->select('ph.id', 'ph.date', 'ph.descr', 'ph.source', 'ph.image_2', 'pha.show_in_lead', 'ph.date_update', 'ph.descr')
|
|
->from('photos', 'ph')
|
|
->from('photos_articles_relation', 'pha')
|
|
->where('ph.id=pha.id_photo AND pha.id_art=:IDa')
|
|
->orderBy('pha.position', 'ASC')
|
|
->addOrderBy('pha.date_added', 'ASC')
|
|
->setParameter('IDa', $this->IDa)
|
|
->execute();
|
|
|
|
foreach ($qb as $row) {
|
|
$row['IDph'] = $row['id'];
|
|
$row['img'] = getImage($row['id'], $row['image_2'], $row['source'], 4, $row['descr'], strtotime($row['date_update']));
|
|
$row['width'] = ($row['img']['width'] <= 200) ? $row['img']['width'] : 200;
|
|
$data[] = $row;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function getArticleAuthors(): array
|
|
{
|
|
if (!findModule(\Modules::ARTICLES_AUTHORS)) {
|
|
return [];
|
|
}
|
|
|
|
$qb = sqlFetchAll(sqlQueryBuilder()
|
|
->select('au.*')
|
|
->from('articles_authors', 'au')
|
|
->from('articles_authors_relation', 'aar')
|
|
->andWhere(
|
|
Operator::andX(
|
|
Operator::equals(['aar.id_art' => $this->IDa]),
|
|
'aar.id_auth=au.id'
|
|
)
|
|
)
|
|
->andWhere(Translation::coalesceTranslatedFields(ArticlesAuthorsTranslation::class))
|
|
->execute(), 'id');
|
|
|
|
foreach ($qb as $row) {
|
|
$row['photo'] = getImage($row['id'], $row['photo'], '../articles_authors/', 'articles_authors', dateUpdate: strtotime($row['date_update']));
|
|
$data[] = $row;
|
|
}
|
|
|
|
return $data ?? $qb;
|
|
}
|
|
|
|
public function getArticleTags()
|
|
{
|
|
$tags = sqlQueryBuilder()
|
|
->select('at.id, at.tag')
|
|
->from('articles_tags_relation', 'atr')
|
|
->leftJoin('atr', 'articles_tags', 'at', 'at.id = atr.id_tag')
|
|
->where(\Query\Operator::equals(['atr.id_article' => $this->IDa]))
|
|
->andWhere(Translation::coalesceTranslatedFields(ArticlesTagsTranslation::class))
|
|
->execute()->fetchAll();
|
|
|
|
$tags = array_combine(array_column($tags, 'id'), $tags);
|
|
|
|
return $tags;
|
|
}
|
|
|
|
public function getReturnNav($articleTitle)
|
|
{
|
|
$returnNav = [];
|
|
|
|
$qb = sqlQueryBuilder()
|
|
->select('id_branch')
|
|
->from(getTableName('articles_relation'))
|
|
->where('id_art=:IDa')
|
|
->setParameter('IDa', $this->IDa)
|
|
->execute();
|
|
|
|
foreach ($qb as $row) {
|
|
$returnNav = array_merge($returnNav, getReturnNavigation($row['id_branch'], 'ARTICLE', [$articleTitle]));
|
|
}
|
|
|
|
return $returnNav;
|
|
}
|
|
|
|
public function updateArticleSeen(): bool
|
|
{
|
|
if (!$this->requestUtil->isRobot($this->request)) {
|
|
$qb = sqlQueryBuilder()
|
|
->update('articles')
|
|
->set('seen', 'seen+1')
|
|
->where('id=:IDa')
|
|
->setParameter('IDa', $this->IDa);
|
|
|
|
if ($qb->execute()) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function setIDa($IDa)
|
|
{
|
|
$this->IDa = $IDa;
|
|
}
|
|
|
|
public function handlePrint()
|
|
{
|
|
return $this->request->get('print');
|
|
}
|
|
|
|
/**
|
|
* Returns correct url of category.
|
|
*/
|
|
public function getCorrectUrl(): ?string
|
|
{
|
|
if (!$this->getArticle()) {
|
|
return null;
|
|
}
|
|
|
|
return createScriptURL([
|
|
'URL' => 'launch.php',
|
|
's' => 'article',
|
|
'IDa' => $this->IDa,
|
|
'TITLE' => $this->article['seo_url'],
|
|
]);
|
|
}
|
|
|
|
public function getMetaTitle()
|
|
{
|
|
if (!empty($this->getArticle()['meta_title'])) {
|
|
return $this->getArticle()['meta_title'];
|
|
}
|
|
|
|
return parent::getMetaTitle();
|
|
}
|
|
|
|
public function getMetaDescription()
|
|
{
|
|
if (!empty($this->getArticle()['meta_description'])) {
|
|
return $this->getArticle()['meta_description'];
|
|
}
|
|
|
|
return parent::getMetaDescription();
|
|
}
|
|
|
|
public function getBreadcrumbsNew(): array
|
|
{
|
|
if (findModule(\Modules::COMPONENTS)) {
|
|
$breadcrumbs = getReturnNavigation($this->article['id_branch'], 'ARTICLE', [$this->article['title']]);
|
|
|
|
return reset($breadcrumbs);
|
|
}
|
|
|
|
return parent::getBreadcrumbsNew();
|
|
}
|
|
|
|
public function getTemplates(): iterable
|
|
{
|
|
yield from $this->getTemplatesFromPath(__DIR__.'/../../../../../shop/twig/articles', 'article.html.twig', 'articles');
|
|
// default template
|
|
yield $this->getTemplate();
|
|
}
|
|
}
|