cache_ui-1.0.0/src/Controller/CacheUiController.php
src/Controller/CacheUiController.php
<?php
namespace Drupal\cache_ui\Controller;
use Drupal\Core\Cache\CacheFactory;
use Drupal\Core\Cache\DatabaseBackend;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
class CacheUiController extends ControllerBase {
/**
* Cache factory instance.
*
* @var \Drupal\Core\Cache\CacheFactory
*/
protected $cacheFactory;
/**
* Config factory instance.
*
* @var \Drupal\Core\Cache\CacheFactory
*/
protected $configFactory;
/**
* Date formatter instance.
*
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
/**
* Current request instance.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* Constructs the CacheUiController object.
*
* @param \Drupal\Core\Cache\CacheFactory $cache_factory
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* @param \Symfony\Component\HttpFoundation\Request $request
*/
public function __construct(CacheFactory $cache_factory, ConfigFactoryInterface $config_factory, DateFormatterInterface $date_formatter, Request $request) {
$this->cacheFactory = $cache_factory;
$this->configFactory = $config_factory;
$this->dateFormatter = $date_formatter;
$this->request = $request;
}
/**
* @inheritdoc
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('cache_factory'),
$container->get('config.factory'),
$container->get('date.formatter'),
$container->get('request_stack')->getCurrentRequest(),
);
}
/**
* Cache UI Route handler.
*
* @return array
*/
public function content() {
$container = \Drupal::getContainer();
$services = [];
foreach ($container->getServiceIds() as $service_id) {
if (str_starts_with($service_id, 'cache.')) {
$service = $container->get($service_id);
if ($service instanceof \Drupal\Core\Cache\CacheBackendInterface) {
$services[$service_id] = $service;
}
}
}
$build = [
'#type' => 'table',
'#header' => [
$this->t('Cache Bin'),
$this->t('Backend'),
$this->t('Operations')
],
];
foreach ($services as $bin => $cache_backend) {
$bin_link = Link::createFromRoute($bin, 'cache_ui.cache_bin_keys', ['bin' => $bin])->toString();
$operations = [
'list_keys' => [
'title' => $this->t('List keys'),
'url' => Url::fromRoute('cache_ui.cache_bin_keys', ['bin' => $bin]),
],
'clear' => [
'title' => $this->t('Clear'),
'url' => Url::fromRoute('cache_ui.cache_bin_clear', ['bin' => $bin]),
],
'gb' => [
'title' => $this->t('Garbage Collection'),
'url' => Url::fromRoute('cache_ui.cache_bin_clear', ['bin' => $bin]),
],
];
$build['#rows'][] = [
['data' => $bin_link],
['data' => get_class($services[$bin])],
[
'data' => [
'#type' => 'operations',
'#links' => $operations,
],
],
];
}
return $build;
}
/**
* Route handler to list cache bin keys.
*
* @see cache_ui.cache_bin_keys
*
* @param $bin
* Service ID of the cache bin.
*
* @return array
* Render array.
*/
public function viewBin($bin) {
$cache_bin = \Drupal::service($bin);
$parts = explode('.', $bin);
$cache_id = end($parts);
$results = [];
$entries = [];
if ($cache_bin instanceof DatabaseBackend) {
$table_name = sprintf('cache_%s', $cache_id);
$results = \Drupal::database()
->select($table_name, 'c')
->fields('c', ['cid', 'data', 'expire', 'created', 'tags'])
->execute()
->fetchAll(\PDO::FETCH_ASSOC);
}
$config = $this->config('cache_ui.settings');
if (!empty($config->get($bin))) {
$results = $config->get($bin);
}
if (empty($results)) {
return [
'#attached' => [
'library' => ['cache_ui/entry.view'],
],
'#markup' => t('@class cache bin does not support listing keys or is empty.', ['@class' => get_class($cache_bin)]),
];
}
foreach ($results as $row) {
$created = ['#markup' => '<em>Unset</em>'];
if (!empty($row['created'])) {
$created = $this->dateFormatter->format(intval($row['created']), 'long');
}
$entries[] = [
['data' => $row['cid']],
['data' => $row['expire'] ?? ''],
['data' => $created,],
[
'data' => [
'#type' => 'operations',
'#links' => [
'view_data' => [
'title' => $this->t('View Data'),
'url' => Url::fromRoute('cache_ui.cache_bin_data', ['bin' => $bin, 'cid' => urlencode($row['cid'])]),
],
],
],
],
];
}
$build = [
'#type' => 'table',
'#header' => [
$this->t('Cache Entry'),
$this->t('Expire'),
$this->t('Created'),
$this->t('Operations')
],
'#attached' => [
'library' => ['cache_ui/entry.view'],
],
'#rows' => $entries,
'#empty' => t('@class cache bin does not support listing keys or is empty.', ['@class' => get_class($cache_bin)]),
];
return $build;
}
/**
* Dynamic title callback for route.
*
* @see cache_ui.cache_bin_keys
*
* @param $bin
* Service ID of the cache bin.
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup
* Title of the page.
*/
public function viewBinTitle($bin) {
return $this->t('@bin', ['@bin' => $bin]);
}
/**
* View stored data of a cache key.
*
* @see cache_ui.cache_bin_data
*
* @param $bin
* Service ID of the cache bin.
*
* @return array
* Render array.
*/
public function viewData($bin) {
$cid = urldecode($this->request->get('cid'));
$cache_bin = \Drupal::service($bin);
$entry = $cache_bin->get($cid);
if (!$entry) {
return ['#markup' => 'No cache found.'];
}
$rows = [
[
['data' => $this->t('CID'), 'header' => TRUE],
$entry->cid,
],
[
['data' => $this->t('Created'), 'header' => TRUE],
$this->dateFormatter->format(intval($entry->created), 'long'),
],
[
['data' => $this->t('Expire'), 'header' => TRUE],
$entry->expire,
],
[
['data' => $this->t('Tags'), 'header' => TRUE],
implode(' ', $entry->tags ?? []),
],
[
['data' => $this->t('Checksum'), 'header' => TRUE],
$entry->checksum,
],
[
['data' => $this->t('Operations'), 'header' => TRUE],
['data' => [
'#type' => 'operations',
'#links' => [
'invalidate' => [
'title' => $this->t('Invalidate'),
'url' => Url::fromRoute('cache_ui.cache_bin_data_invalidate', ['bin' => $bin, 'cid' => urlencode($entry->cid)]),
],
],
]],
],
];
$build['table'] = [
'#type' => 'table',
'#rows' => $rows,
'#attributes' => ['class' => ['dblog-event']],
'#attached' => [
'library' => ['cache_ui/entry.view'],
],
];
$data = json_encode($cache_bin->get($cid)->data, JSON_PRETTY_PRINT);
if ($data === '{}' && !empty($cache_bin->get($cid)->data)) {
$build['info'] = [
'#markup' => sprintf('<em>%s</em>', $this->t('Could not decode PHP serialized value to JSON. Displaying original.')),
];
$data = serialize($cache_bin->get($cid)->data);
}
$build['data'] = [
'#type' => 'inline_template',
'#template' => '<pre class="cache_ui--entry-view">{{ var }}</pre>',
'#context' => [
'var' => $data,
],
];
return $build;
}
/**
* Invalidate a given cache entry.
*
* @see cache_ui.cache_bin_data_invalidate
*
* @param $bin
* Service ID of the cache bin.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* Redirect to the cache bin overview page.
*/
public function invalidate($bin) {
$cid = urldecode($this->request->get('cid'));
/** @var \Drupal\Core\Cache\CacheBackendInterface $cache_bin */
$cache_bin = \Drupal::service($bin);
$cache_bin->invalidate($cid);
return new RedirectResponse(Url::fromRoute('cache_ui.cache_bin_keys', compact('bin'))->toString());
}
/**
* Clear a given cache bin.
*
* @param $bin
* Service ID of the cache bin.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* Redirect to the Cache UI admin page.
*/
public function clearBin($bin) {
$cache_bin = $this->cacheFactory->get($bin);
$cache_bin->deleteAll();
$this->messenger()->addStatus($this->t('Cache bin @bin cleared.', ['@bin' => $bin]));
return new RedirectResponse(Url::fromRoute('cache_ui.admin')->toString());
}
}
