Skip to content

Instantly share code, notes, and snippets.

@alexander-schranz
Last active May 27, 2024 08:46
Show Gist options
  • Select an option

  • Save alexander-schranz/6763148880e60410ed77894ccb585802 to your computer and use it in GitHub Desktop.

Select an option

Save alexander-schranz/6763148880e60410ed77894ccb585802 to your computer and use it in GitHub Desktop.
CacheNavigationTwigExtension
<?php
namespace App\Twig;
use Doctrine\Common\Cache\CacheProvider;
use Sulu\Bundle\WebsiteBundle\Navigation\NavigationItem;
use Sulu\Bundle\WebsiteBundle\Navigation\NavigationMapperInterface;
use Sulu\Bundle\WebsiteBundle\Twig\Navigation\NavigationTwigExtension as SuluNavigationTwigExtension;
use Sulu\Component\Content\Mapper\ContentMapperInterface;
use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
class NavigationTwigExtension extends SuluNavigationTwigExtension
{
/**
* @var CacheProvider
*/
private $cache;
public function __construct(
ContentMapperInterface $contentMapper,
NavigationMapperInterface $navigationMapper,
RequestAnalyzerInterface $requestAnalyzer = null,
CacheProvider $cache = null
) {
parent::__construct($contentMapper, $navigationMapper, $requestAnalyzer);
$this->cache = $cache;
}
/**
* {@inheritdoc}
*/
public function treeRootNavigationFunction($context = null, $depth = 1, $loadExcerpt = false)
{
$id = $this->generateId('treeRootNavigationFunction', [$context, $depth, $loadExcerpt]);
if ($this->cache && $this->cache->contains($id)) {
return $this->cache->fetch($id);
}
$navigation = parent::treeRootNavigationFunction($context, $depth, $loadExcerpt);
$data = $this->toArray($navigation);
if ($this->cache) {
$this->cache->save($id, $data);
}
return $data;
}
/**
* {@inheritdoc}
*/
public function flatRootNavigationFunction($context = null, $depth = 1, $loadExcerpt = false)
{
$id = $this->generateId('flatRootNavigationFunction', [$context, $depth, $loadExcerpt]);
if ($this->cache && $this->cache->contains($id)) {
return $this->cache->fetch($id);
}
$navigation = parent::flatRootNavigationFunction($context, $depth, $loadExcerpt);
$data = $this->toArray($navigation);
if ($this->cache) {
$this->cache->save($id, $data);
}
return $data;
}
/**
* {@inheritdoc}
*/
public function breadcrumbFunction($uuid)
{
$id = $this->generateId('breadcrumbFunction', [$uuid]);
if ($this->cache && $this->cache->contains($id)) {
return $this->cache->fetch($id);
}
$navigation = parent::breadcrumbFunction($uuid);
$data = $this->toArray($navigation);
if ($this->cache) {
$this->cache->save($id, $data);
}
return $data;
}
/**
* Generates unique id for given arguments.
*
* @param string $name
* @param array $arguments
*
* @return string
*/
private function generateId($name, array $arguments)
{
$locale = '';
$webspaceKey = '';
$segment = '';
if ($this->requestAnalyzer) {
$locale = $this->requestAnalyzer->getCurrentLocalization()->getLocale();
$webspaceKey = $this->requestAnalyzer->getWebspace()->getKey();
$segment = $this->requestAnalyzer->getSegment();
}
$arguments = array_merge($arguments, [$locale, $webspaceKey, $segment]);
return md5(sprintf('%s(%s)', $name, serialize($arguments)));
}
/**
* Serializes navigation to array.
*
* @param array $navigation
*
* @return array
*/
private function toArray(array $navigation)
{
$data = [];
foreach ($navigation as $item) {
if (!array_key_exists('uuid', $item)) {
continue;
}
$dataItem = [
'uuid' => $item['uuid'],
'url' => $item['url'],
'title' => $item['title'],
'excerpt' => [],
'children' => array_key_exists('children', $item) ? $this->toArray($item['children']) : [],
];
if (array_key_exists('excerpt', $item)
&& array_key_exists('icon', $item['excerpt'])
&& count($item['excerpt']['icon'])
) {
$formats = $item['excerpt']['icon'][0]->getFormats();
$dataItem['excerpt'] = [
'icon' => [
[
'formats' => $formats,
'thumbnails' => $formats,
],
],
];
}
$data[] = $dataItem;
}
return $data;
}
}
/*
# config/packages/doctrine_cache.yaml:
framework:
cache:
pools:
app.twig_extensions_cache_pool:
adapter: cache.app
services:
app.cache.twig_extensions:
class: Symfony\Component\Cache\DoctrineProvider
public: false
arguments:
- '@app.twig_extensions_cache_pool'
*/
<?php
namespace App\Cache;
use Doctrine\Common\Cache\CacheProvider;
use Sulu\Bundle\HttpCacheBundle\Cache\CacheManager;
use Sulu\Bundle\WebsiteBundle\Cache\CacheClearerInterface;
use Sulu\Bundle\WebsiteBundle\Event\CacheClearEvent;
use Sulu\Bundle\WebsiteBundle\Events;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class CacheClearer implements CacheClearerInterface
{
/**
* @var CacheClearerInterface
*/
private $cacheClearer;
/**
* @var CacheProvider
*/
private $cacheProvider;
public function __construct(
CacheClearerInterface $cacheClearer,
CacheProvider $cacheProvider
) {
$this->cacheClearer = $cacheClearer;
$this->cacheProvider = $cacheProvider;
}
public function clear(?array $tags = null): void
{
$this->cacheClearer->clear($tags);
if ($this->cacheProvider) {
$this->cacheProvider->deleteAll();
}
}
}
/*
services:
App\Cache\CacheClearer:
decorates: sulu_website.http_cache.clearer
arguments:
- '@.inner'
- '@app.twig_extensions_cache_pool'
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment