Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always cache the menu #2853

Closed
wants to merge 6 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Caching more stuffs
  • Loading branch information
bobdenotter committed Oct 6, 2021
commit 8b59f287e2cb7b8b72ec772fad6ca97cf85a4a7b
34 changes: 31 additions & 3 deletions src/Canonical.php
Original file line number Diff line number Diff line change
@@ -14,6 +14,9 @@
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;

class Canonical
{
@@ -43,14 +46,20 @@ class Canonical

/** @var RouterInterface */
private $router;
/** @var Stopwatch */
private $stopwatch;
/** @var TagAwareCacheInterface */
private $cache;

public function __construct(Config $config, UrlGeneratorInterface $urlGenerator, RequestStack $requestStack, RouterInterface $router, string $defaultLocale)
public function __construct(Config $config, UrlGeneratorInterface $urlGenerator, RequestStack $requestStack, RouterInterface $router, string $defaultLocale, Stopwatch $stopwatch, TagAwareCacheInterface $cache)
{
$this->config = $config;
$this->urlGenerator = $urlGenerator;
$this->request = $requestStack->getCurrentRequest() ?? Request::createFromGlobals();
$this->defaultLocale = $defaultLocale;
$this->router = $router;
$this->stopwatch = $stopwatch;
$this->cache = $cache;

$this->init();
}
@@ -174,6 +183,23 @@ public function setPath(?string $route = null, array $params = []): void
}

public function generateLink(?string $route, ?array $params, $canonical = false): ?string
{
$cacheKey = 'generateLink_' . md5($route . implode('-', $params) . (string) $canonical);

$this->stopwatch->start('bolt.GenerateLink');

$link = $this->cache->get($cacheKey, function (ItemInterface $item) use ($route, $params, $canonical) {
$item->tag('routes');

return $this->generateLinkHelper($route, $params, $canonical);
});

$this->stopwatch->stop('bolt.GenerateLink');

return $link;
}

private function generateLinkHelper(?string $route, ?array $params, $canonical = false): ?string
{
$removeDefaultLocaleOnCanonical = $this->config->get('general/localization/remove_default_locale_on_canonical', true);
$hasDefaultLocale = isset($params['_locale']) && $params['_locale'] === $this->defaultLocale;
@@ -197,15 +223,17 @@ public function generateLink(?string $route, ?array $params, $canonical = false)
}

try {
return $this->urlGenerator->generate(
$link = $this->urlGenerator->generate(
$route,
$params,
$canonical ? UrlGeneratorInterface::ABSOLUTE_URL : UrlGeneratorInterface::ABSOLUTE_PATH
);
} catch (InvalidParameterException | MissingMandatoryParametersException | RouteNotFoundException | \TypeError $e) {
// Just use the current URL /shrug
return $canonical ? $this->request->getUri() : $this->request->getPathInfo();
$link = $canonical ? $this->request->getUri() : $this->request->getPathInfo();
}

return $link;
}

private function routeRequiresParam(string $route, string $param): bool
1 change: 1 addition & 0 deletions src/Entity/Content.php
Original file line number Diff line number Diff line change
@@ -192,6 +192,7 @@ public function getCacheKey(?string $locale = null): string
if ($locale !== null) {
$key .= '-' . $locale;
}

return $key;
}

53 changes: 41 additions & 12 deletions src/Twig/FieldExtension.php
Original file line number Diff line number Diff line change
@@ -16,6 +16,9 @@
use Bolt\Utils\ContentHelper;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
use Tightenco\Collect\Support\Collection;
use Twig\Environment;
use Twig\Extension\AbstractExtension;
@@ -38,19 +41,26 @@ class FieldExtension extends AbstractExtension

/** @var Query */
private $query;
/** @var Stopwatch */
private $stopwatch;

/** @var TagAwareCacheInterface */
private $cache;

public function __construct(
Notifications $notifications,
ContentRepository $contentRepository,
Config $config,
ContentHelper $contentHelper,
Query $query)
Query $query, Stopwatch $stopwatch, TagAwareCacheInterface $cache)
{
$this->notifications = $notifications;
$this->contentRepository = $contentRepository;
$this->config = $config;
$this->contentHelper = $contentHelper;
$this->query = $query;
$this->stopwatch = $stopwatch;
$this->cache = $cache;
}

/**
@@ -275,19 +285,38 @@ private function selectOptionsContentType(Field $field): Collection
'order' => $order,
];

/** @var Content[] $records */
$records = iterator_to_array($this->query->getContent($contentTypeSlug, $params)->getCurrentPageResults());
$options = $this->selectOptionsContentTypeCache($contentTypeSlug, $params, $field, $format);

return new Collection($options);
}

private function selectOptionsContentTypeCache(string $contentTypeSlug, array $params, Field $field, string $format)
{
$cacheKey = 'selectOptions_' . md5($contentTypeSlug . implode('-', $params));

$this->stopwatch->start('selectOptions');

$options = $this->cache->get($cacheKey, function (ItemInterface $item) use ($contentTypeSlug, $params, $field, $format) {
$item->tag($contentTypeSlug);

foreach ($records as $record) {
if ($field->getDefinition()->get('mode') === 'format') {
$formattedKey = $this->contentHelper->get($record, $field->getDefinition()->get('format'));
/** @var Content[] $records */
$records = iterator_to_array($this->query->getContent($contentTypeSlug, $params)->getCurrentPageResults());

foreach ($records as $record) {
if ($field->getDefinition()->get('mode') === 'format') {
$formattedKey = $this->contentHelper->get($record, $field->getDefinition()->get('format'));
}
$options[] = [
'key' => $formattedKey ?? $record->getId(),
'value' => $this->contentHelper->get($record, $format),
];
}
$options[] = [
'key' => $formattedKey ?? $record->getId(),
'value' => $this->contentHelper->get($record, $format),
];
}

return new Collection($options);
return $options;
});

$this->stopwatch->stop('selectOptions');

return $options;
}
}
1 change: 0 additions & 1 deletion src/Twig/JsonExtension.php
Original file line number Diff line number Diff line change
@@ -142,7 +142,6 @@ private function contentToArrayHelper(Content $content, string $locale = ''): ar
return $result;
}


/**
* Test whether a passed string contains valid JSON.
*/
7 changes: 1 addition & 6 deletions src/Twig/RelatedExtension.php
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@
use Bolt\Repository\RelationRepository;
use Bolt\Storage\Query;
use Bolt\Utils\ContentHelper;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
use Tightenco\Collect\Support\Collection;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
@@ -157,22 +157,18 @@ public function getRelatedOptions(string $contentTypeSlug, ?string $order = null

$cacheKey = 'relatedOptions_' . md5($contentTypeSlug . $order . $format . (string) $required . $maxAmount);


$options = $this->cache->get($cacheKey, function (ItemInterface $item) use ($contentTypeSlug, $order, $format, $required, $maxAmount) {
dump('cache ' . $contentTypeSlug);
$item->tag($contentTypeSlug);

return $this->getRelatedOptionsCache($contentTypeSlug, $order, $format, $required, $maxAmount);
});



return new Collection($options);
}

public function getRelatedOptionsCache(string $contentTypeSlug, string $order, string $format, bool $required, int $maxAmount): array
{

$pager = $this->query->getContent($contentTypeSlug, ['order' => $order])
->setMaxPerPage($maxAmount)
->setCurrentPage(1);
@@ -200,7 +196,6 @@ public function getRelatedOptionsCache(string $contentTypeSlug, string $order, s
}

return $options;

}

public function getRelatedValues(Content $source, string $contentType): Collection