sitewide_alerts-1.0.0/src/Controller/SiteAlertController.php
src/Controller/SiteAlertController.php
<?php
namespace Drupal\sitewide_alerts\Controller;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\sitewide_alerts\SiteAlertInterface;
use Drupal\sitewide_alerts\SiteAlertStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Site alert controller.
*
* @package Drupal\sitewide_alerts\Controller
*/
class SiteAlertController extends ControllerBase implements ContainerInjectionInterface {
/**
* The date formatter service.
*/
protected DateFormatterInterface $dateFormatter;
/**
* The renderer service.
*/
protected RendererInterface $renderer;
/**
* The entity repository service.
*/
protected EntityRepositoryInterface $entityRepository;
/**
* Constructs a SiteAlertController object.
*
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
* The entity repository.
*/
public function __construct(DateFormatterInterface $date_formatter, RendererInterface $renderer, EntityRepositoryInterface $entity_repository) {
$this->dateFormatter = $date_formatter;
$this->renderer = $renderer;
$this->entityRepository = $entity_repository;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('date.formatter'),
$container->get('renderer'),
$container->get('entity.repository')
);
}
/**
* Displays a site alert revision.
*
* @param int $site_alert_revision
* The revision.
*
* @return array
* An array suitable for drupal_render().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function revisionShow(int $site_alert_revision): array {
$site_alert = $this->entityTypeManager()
->getStorage('site_alert')
->loadRevision($site_alert_revision);
$view_builder = $this->entityTypeManager()->getViewBuilder('site_alert');
return $view_builder->view($site_alert);
}
/**
* Page title callback for a site alert revision.
*
* @param int $site_alert_revision
* The revision.
*
* @return string
* The page title
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function revisionPageTitle(int $site_alert_revision): string {
$site_alert = $this->entityTypeManager()
->getStorage('site_alert')
->loadRevision($site_alert_revision);
return $this->t('Revision of %title from %date', [
'%title' => $site_alert->label(),
'%date' => $this->dateFormatter->format($site_alert->getRevisionCreationTime()),
]);
}
/**
* Generates an overview table of older revisions of a site alert.
*
* @param \Drupal\sitewide_alerts\SiteAlertInterface $site_alert
* The site alert object.
*
* @return array
* An array as expected by drupal_render().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function revisionOverview(SiteAlertInterface $site_alert): array {
$langcode = $site_alert->language()->getId();
$langname = $site_alert->language()->getName();
$languages = $site_alert->getTranslationLanguages();
$has_translations = (count($languages) > 1);
$site_alert_storage = $this->entityTypeManager()->getStorage('site_alert');
$build['#title'] = $has_translations ? $this->t('@langname revisions for %title', [
'@langname' => $langname,
'%title' => $site_alert->label(),
]) : $this->t('Revisions for %title', ['%title' => $site_alert->label()]);
$header = [$this->t('Revision'), $this->t('Operations')];
$rows = [];
$default_revision = $site_alert->getRevisionId();
$current_revision_displayed = FALSE;
foreach ($this->getRevisionIds($site_alert, $site_alert_storage) as $vid) {
/** @var \Drupal\sitewide_alerts\SiteAlertInterface $revision */
$revision = $site_alert_storage->loadRevision($vid);
// Only show revisions that are affected by the language that is being
// displayed.
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)
->isRevisionTranslationAffected()) {
$username = [
'#theme' => 'username',
'#account' => $revision->getRevisionUser(),
];
// Use revision link and link to revisions that are not active.
$date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
// We treat also the latest translation-affecting revision as current
// revision, if it was the default revision, as its values for the
// current language will be the same of the current default revision in
// this case.
$is_current_revision = $vid == $default_revision || (!$current_revision_displayed && $revision->wasDefaultRevision());
if (!$is_current_revision) {
$link = Link::fromTextAndUrl($date, new Url('entity.site_alert.revision', [
'site_alert' => $site_alert->id(),
'site_alert_revision' => $vid,
]))->toString();
}
else {
$link = $site_alert->toLink($date)->toString();
$current_revision_displayed = TRUE;
}
$row = [];
$column = [
'data' => [
'#type' => 'inline_template',
'#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
'#context' => [
'date' => $link,
'username' => $this->renderer->renderPlain($username),
'message' => [
'#markup' => $revision->revision_log->value,
'#allowed_tags' => Xss::getHtmlTagList(),
],
],
],
];
// @todo Simplify once https://www.drupal.org/node/2334319 lands.
$this->renderer->addCacheableDependency($column['data'], $username);
$row[] = $column;
if ($is_current_revision) {
$row[] = [
'data' => [
'#prefix' => '<em>',
'#markup' => $this->t('Current revision'),
'#suffix' => '</em>',
],
];
$rows[] = [
'data' => $row,
'class' => ['revision-current'],
];
}
else {
$links = [];
$links['revert'] = [
'title' => $vid < $site_alert->getRevisionId() ? $this->t('Revert') : $this->t('Set as current revision'),
'url' => $has_translations ?
Url::fromRoute('entity.site_alert.revision_revert_translation', [
'site_alert' => $site_alert->id(),
'site_alert_revision' => $vid,
'langcode' => $langcode,
]) :
Url::fromRoute('entity.site_alert.revision_revert', [
'site_alert' => $site_alert->id(),
'site_alert_revision' => $vid,
]),
];
$links['delete'] = [
'title' => $this->t('Delete'),
'url' => Url::fromRoute('entity.site_alert.revision_delete', [
'site_alert' => $site_alert->id(),
'site_alert_revision' => $vid,
]),
];
$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
$rows[] = $row;
}
}
}
$build['site_alert_revisions_table'] = [
'#theme' => 'table',
'#rows' => $rows,
'#header' => $header,
'#attributes' => ['class' => 'site-alert-revision-table'],
];
$build['pager'] = ['#type' => 'pager'];
return $build;
}
/**
* Gets a list of site alert revision IDs for a specific site alert.
*
* @param \Drupal\sitewide_alerts\SiteAlertInterface $site_alert
* The site alert entity.
* @param \Drupal\sitewide_alerts\SiteAlertStorageInterface $site_alert_storage
* The site alert storage handler.
*
* @return int[]
* Site alert revision IDs (in descending order).
*/
protected function getRevisionIds(SiteAlertInterface $site_alert, SiteAlertStorageInterface $site_alert_storage): array {
$result = $site_alert_storage->getQuery()
->accessCheck(TRUE)
->allRevisions()
->condition($site_alert->getEntityType()->getKey('id'), $site_alert->id())
->sort($site_alert->getEntityType()->getKey('revision'), 'DESC')
->pager(50)
->execute();
return array_keys($result);
}
}
