cache_review-1.0.x-dev/src/Render/RendererCacheReview.php
src/Render/RendererCacheReview.php
<?php
namespace Drupal\cache_review\Render;
use Drupal\cache_review\Form\CacheReviewConfigForm;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Render\PlaceholderGeneratorInterface;
use Drupal\Core\Render\RenderCacheInterface;
use Drupal\Core\Render\Renderer;
use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Utility\CallableResolver;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Decorates core's Renderer to add mark to placeholders.
*/
class RendererCacheReview extends Renderer {
use StringTranslationTrait;
/**
* The original Renderer.
*
* @var \Drupal\Core\Render\Renderer
*/
protected Renderer $renderer;
/**
* The current route match service.
*
* @var \Drupal\Core\Routing\CurrentRouteMatch
*/
protected CurrentRouteMatch $currentRouteMatch;
/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected ConfigFactoryInterface $configFactory;
/**
* Construct RendererCacheReview object.
*
* @param \Drupal\Core\Render\Renderer $original_renderer
* The original renderer.
* @param \Drupal\Core\Routing\CurrentRouteMatch $current_route_match
* The current route match service.
* @param \Drupal\Core\Utility\CallableResolver $callableResolver
* The callable resolver.
* @param \Drupal\Core\Theme\ThemeManagerInterface $theme
* The theme manager.
* @param \Drupal\Core\Render\ElementInfoManagerInterface $element_info
* The element info.
* @param \Drupal\Core\Render\PlaceholderGeneratorInterface $placeholder_generator
* The placeholder generator.
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache service.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param array $renderer_config
* The renderer configuration array.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory for retrieving required config objects.
*/
public function __construct(
Renderer $original_renderer,
CurrentRouteMatch $current_route_match,
CallableResolver $callableResolver,
ThemeManagerInterface $theme,
ElementInfoManagerInterface $element_info,
PlaceholderGeneratorInterface $placeholder_generator,
RenderCacheInterface $render_cache,
RequestStack $request_stack,
array $renderer_config,
ConfigFactoryInterface $config_factory,
) {
$this->renderer = $original_renderer;
$this->currentRouteMatch = $current_route_match;
$this->configFactory = $config_factory;
parent::__construct($callableResolver, $theme, $element_info, $placeholder_generator, $render_cache, $request_stack, $renderer_config);
}
/**
* {@inheritdoc}
*/
protected function doRender(&$elements, $is_root_call = FALSE) {
// Set not-cached mark to add cache options later.
if (isset($elements['#cache']) && !isset($elements['#cache']['keys'])) {
$not_cached = TRUE;
}
$result = parent::doRender($elements, $is_root_call);
// Return if nothing to visualize.
if ($result === '') {
return '';
}
// Ignore html_tags from cache_review configuration.
$cache_review_config = $this->configFactory->get(CacheReviewConfigForm::CACHE_REVIEW_CONF);
$framing = $cache_review_config->get('framing');
// Check html id tags if framing is set to disable.
$analyze_by_id = FALSE;
if ($framing === 'no_frame') {
$html_tags_values = $cache_review_config->get('html_tags');
$html_tags = array_filter(explode("\r\n", trim($html_tags_values)));
foreach ($html_tags as $html_tag) {
if (str_contains($elements['#markup'], 'id="' . $html_tag . '"')) {
$analyze_by_id = TRUE;
}
}
}
// Check if it needs to show cache info on admin routes.
$check_admin_routes = $cache_review_config->get('check_admin_routes');
$is_admin = (bool) $this->currentRouteMatch->getRouteObject()->getOption('_admin_route');
// Check framing settings.
if (!$is_admin || $check_admin_routes) {
if (($framing !== 'frame_cached' && $framing !== 'no_frame') ||
($framing === 'no_frame' && $analyze_by_id)) {
// Add cache data for lazy built elements.
if (!empty($elements['#attached']['placeholders']) && !empty($elements['#markup']) &&
count($elements['#attached']['placeholders']) === 1) {
$lazy_cache = '';
if (!empty(reset($elements['#attached']['placeholders'])['#cache'])) {
$lazy_cache = $this->t('<b>Lazy options:</b> @placeholders<br>', ['@placeholders' => json_encode(reset($elements['#attached']['placeholders'])['#cache'])]);
}
$markup_string = (string) $elements['#markup'];
if (!empty($markup_string)) {
$prefix = '<div class="lazy-wrapper">';
$suffix = '</div>';
$options_data = $this->t('<b>Item options:</b><br> contexts: @context<br>max-age: @max-age<br>tags: @tags',
[
'@context' => json_encode(array_values($elements['#cache']['contexts'])),
'@max-age' => json_encode($elements['#cache']['max-age']),
'@tags' => json_encode(array_values($elements['#cache']['tags'])),
]);
$options = '<span class="cache_tooltip_text">' . $lazy_cache . $options_data . '</span>';
$cache_mark = '<div class="lazy-item cache_tooltip">L' . $options . '</div>';
$elements['#markup'] = Markup::create($prefix . $cache_mark . $markup_string . $suffix);
}
}
// Add cache data for non-cached (separately) elements.
if (!empty($not_cached) && $framing !== 'frame_lazy') {
$markup_string = (string) $elements['#markup'];
$caught_condition = '';
if (!empty($markup_string)) {
$apc = $this->rendererConfig['auto_placeholder_conditions'];
if (array_intersect($elements['#cache']['contexts'], $apc['contexts']) ||
array_intersect($elements['#cache']['tags'], $apc['tags']) ||
$elements['#cache']['max-age'] == $apc['max-age']) {
$caught_condition = ' cache_caught';
}
$prefix = '<div class="base-wrapper">';
$suffix = '</div>';
$options_data = $this->t('<b>Item options:</b><br> contexts: @context<br>max-age: @max-age<br>tags: @tags',
[
'@context' => json_encode(array_values($elements['#cache']['contexts'])),
'@max-age' => json_encode($elements['#cache']['max-age']),
'@tags' => json_encode(array_values($elements['#cache']['tags'])),
]);
$options = '<span class="cache_tooltip_text">' . $options_data . '</span>';
$cache_mark = '<div class="base-item cache_tooltip' . $caught_condition . '">N' . $options . '</div>';
$elements['#markup'] = Markup::create($prefix . $cache_mark . $markup_string . $suffix);
}
}
}
}
return $elements['#markup'];
}
}
