<?php
declare(strict_types=1);
namespace Hitso\Bundle\ContentBundle\Twig\Extension;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Hitso\Bundle\CommonBundle\Doctrine\Paginator\DoctrineORMAdapter;
use Hitso\Bundle\ContentBundle\Entity\Article;
use Hitso\Bundle\ContentBundle\Entity\ArticleCategory;
use Hitso\Bundle\ContentBundle\Entity\Banner;
use Hitso\Bundle\ContentBundle\Entity\Category;
use Hitso\Bundle\ContentBundle\Entity\Content;
use Hitso\Bundle\ContentBundle\Entity\Elements\Element;
use Hitso\Bundle\ContentBundle\Entity\Slide;
use Hitso\Bundle\ContentBundle\Services\Video\VideoHelper;
use Hitso\Bundle\MultiSiteBundle\MultiSite\SiteContext;
use Pagerfanta\Pagerfanta;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;
class ContentExtension extends AbstractExtension
{
/**
* @var AdapterInterface
*/
private $cache;
/**
* @var RegistryInterface
*/
protected $doctrine;
/**
* @var SiteContext
*/
protected $context;
/**
* @var VideoHelper
*/
protected $videoHelper;
/**
* @var SiteContext
*/
protected $siteContext;
public function __construct(
RegistryInterface $doctrine,
AdapterInterface $cache,
SiteContext $context,
VideoHelper $videoHelper,
SiteContext $siteContext
) {
$this->doctrine = $doctrine;
$this->cache = $cache;
$this->context = $context;
$this->videoHelper = $videoHelper;
$this->siteContext = $siteContext;
}
public function getFunctions()
{
return [
new TwigFunction('hitso_content_slide', [$this, 'getSlides'], ['is_safe' => ['html']]),
new TwigFunction('related_articles', [$this, 'getRelatedArticles'], ['is_safe' => ['html']]),
new TwigFunction('hitso_content_banner', [$this, 'getBanners'], ['is_safe' => ['html']]),
new TwigFunction('article_categories', [$this, 'getArticleCategories'], ['is_safe' => ['html']]),
new TwigFunction('category_articles', [$this, 'getArticlesByCategory'], ['is_safe' => ['html']]),
new TwigFunction('published_articles', [$this, 'getPublishedArticles'], ['is_safe' => ['html']]),
new TwigFunction('featured_articles', [$this, 'getFeaturedArticles'], ['is_safe' => ['html']]),
new TwigFunction('extract_content', [$this, 'extractContent'], ['is_safe' => ['html']]),
new TwigFunction('video_thumbnail_url', [$this, 'getVideoThumbnailUrl'], ['is_safe' => ['html']]),
new TwigFunction('getYoutubeMovieId', [$this, 'getYoutubeMovieId'], ['is_safe' => ['html']]),
new TwigFunction('getYoutubeMovieUrl', [$this, 'getYoutubeMovieUrl'], ['is_safe' => ['html']]),
new TwigFunction('formatBytes', [$this, 'formatBytes'], ['is_safe' => ['html']]),
];
}
/**
* @return array
*/
public function getFilters()
{
return [
new TwigFilter('file_size_format', [$this, 'fileSizeFormat']),
];
}
public function getName()
{
return 'hitso_content_ext';
}
public function getVideoThumbnailUrl(?string $videoUrl): string
{
if (null !== $videoUrl) {
return $this->videoHelper->getThumbnailUrl($videoUrl);
}
return '';
}
public function extractContent(Content $content): string
{
$html = [];
$content->getElements()->map(function (Element $element) use (&$html) {
if (strlen($element->getSearchableContent())) {
$html[] = $element->getSearchableContent();
}
});
return implode('.', $html);
}
public function getPublishedArticles(int $limit)
{
$repository = $this->doctrine->getRepository(Article::class);
$queryBuilder = $repository->getPublishedContentsQuery();
$queryBuilder->setMaxResults($limit);
return $queryBuilder->getQuery()->getResult();
}
public function getFeaturedArticles(int $limit = 4)
{
$repository = $this->doctrine->getRepository(Article::class);
$queryBuilder = $repository->getPublishedContentsQuery();
$queryBuilder->setMaxResults($limit);
return $queryBuilder->getQuery()->getResult();
}
public function getArticlesByCategory(ArticleCategory $articleCategory, int $page = 1, int $limit = 12)
{
$qb = $this->doctrine->getRepository(Article::class)->getCategoryQuery($articleCategory);
$cacheId = 'article_category_' . $articleCategory->getId();
$adapter = new DoctrineORMAdapter($qb, $cacheId);
return (new Pagerfanta($adapter))
->setMaxPerPage($limit)
->setCurrentPage($page);
}
public function getRelatedArticles(Article $article, int $limit = 4)
{
if (0 !== (int) $article->getId()) {
$qb = $this->doctrine->getRepository(Article::class)->getRelatedQuery($article);
$cacheId = 'article_related_' . $article->getId() . '_' . $this->siteContext->getContentSite()->getId();
$adapter = new DoctrineORMAdapter($qb, $cacheId);
return (new Pagerfanta($adapter))
->setMaxPerPage($limit)
->setCurrentPage(1);
}
return new ArrayCollection();
}
public function getArticleCategories(): Collection
{
$repository = $this->doctrine->getRepository(Category::class);
$criteria = new Criteria();
return $repository->matching($criteria);
}
public function getSlides($ident, $baseUrl = '')
{
$cacheKey = 'content_slides_' . $this->context->getContentSite()->getId() . sha1($ident);
$cacheItem = $this->cache->getItem($cacheKey);
if ($cacheItem->isHit()) {
return $cacheItem->get();
}
$repository = $this->doctrine->getRepository(Slide::class);
$slides = $repository->getActiveSlides($ident);
$cacheItem->set($slides);
$this->cache->save($cacheItem);
return $slides;
}
public function getBanners(string $target)
{
$cacheKey = 'content_banners_' . $this->context->getContentSite()->getId() . sha1($target);
$cacheItem = $this->cache->getItem($cacheKey);
if ($cacheItem->isHit()) {
return $cacheItem->get();
}
$repository = $this->doctrine->getRepository(Banner::class);
$banners = $repository->getActiveBanners($target);
$cacheItem->set($banners);
$this->cache->save($cacheItem);
return $banners;
}
/**
* @param string $videoUrl
*
* @return string
* @throws \Hitso\Bundle\CommonBundle\Exception\Exception
*/
public function getYoutubeMovieId(string $videoUrl): string
{
return $this->videoHelper->getYoutubeMovieId($videoUrl);
}
/**
* @param string $videoUrl
*
* @return string
*/
public function getYoutubeMovieUrl(string $videoUrl): string
{
return $this->videoHelper->getYoutubeMovieUrl($videoUrl);
}
/**
* @param $size
* @param int $precision
* @param string $space
*
* @return string
*/
public function fileSizeFormat($size, $precision = 2, $space = ' ')
{
if ($size <= 0) {
return '0' . $space . 'KB';
}
if ($size === 1) {
return '1' . $space . 'byte';
}
$mod = 1024;
$units = ['b', 'KB', 'MB', 'GB', 'TB', 'PB'];
for ($i = 0; $size > $mod && $i < count($units) - 1; ++$i) {
$size /= $mod;
}
return round($size, $precision) . $space . $units[$i];
}
}