View source
<?php
namespace Drupal\diff\Controller;
use Drupal\Core\Entity\ContentEntityInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Core\Controller\ControllerBase;
use Drupal\diff\DiffLayoutManager;
use Drupal\diff\DiffEntityComparison;
class PluginRevisionController extends ControllerBase {
protected $config;
protected $entityComparison;
protected $diffLayoutManager;
protected $requestStack;
public function __construct(DiffEntityComparison $entity_comparison, DiffLayoutManager $diff_layout_manager, RequestStack $request_stack) {
$this->config = $this
->config('diff.settings');
$this->diffLayoutManager = $diff_layout_manager;
$this->entityComparison = $entity_comparison;
$this->requestStack = $request_stack;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('diff.entity_comparison'), $container
->get('plugin.manager.diff.layout'), $container
->get('request_stack'));
}
public function getRevisionIds(EntityStorageInterface $storage, $entity_id) {
$result = $storage
->getQuery()
->allRevisions()
->condition($storage
->getEntityType()
->getKey('id'), $entity_id)
->accessCheck(FALSE)
->execute();
$result_array = array_keys($result);
sort($result_array);
return $result_array;
}
public function compareEntityRevisions(RouteMatchInterface $route_match, ContentEntityInterface $left_revision, ContentEntityInterface $right_revision, $filter) {
$entity_type_id = $left_revision
->getEntityTypeId();
$entity = $route_match
->getParameter($entity_type_id);
$entity_type_id = $entity
->getEntityTypeId();
$storage = $this
->entityTypeManager()
->getStorage($entity_type_id);
$langcode = $entity
->language()
->getId();
$left_revision = $left_revision
->getTranslation($langcode);
$right_revision = $right_revision
->getTranslation($langcode);
$revisions_ids = [];
foreach ($this
->getRevisionIds($storage, $entity
->id()) as $revision_id) {
$revision = $storage
->loadRevision($revision_id);
if ($revision
->hasTranslation($langcode) && $revision
->getTranslation($langcode)
->isRevisionTranslationAffected()) {
$revisions_ids[] = $revision_id;
}
}
$build = [
'#title' => $this
->t('Changes to %title', [
'%title' => $entity
->label(),
]),
'header' => [
'#prefix' => '<header class="diff-header">',
'#suffix' => '</header>',
],
'controls' => [
'#prefix' => '<div class="diff-controls">',
'#suffix' => '</div>',
],
];
$build['header']['diff_navigation'] = $this
->buildRevisionsNavigation($entity, $revisions_ids, $left_revision
->getRevisionId(), $right_revision
->getRevisionId(), $filter);
$build['controls']['diff_layout'] = [
'#type' => 'item',
'#title' => $this
->t('Layout'),
'#wrapper_attributes' => [
'class' => 'diff-controls__item',
],
'filter' => $this
->buildLayoutNavigation($entity, $left_revision
->getRevisionId(), $right_revision
->getRevisionId(), $filter),
];
if ($left_revision != FALSE && $right_revision != FALSE) {
if ($plugin = $this->diffLayoutManager
->createInstance($filter)) {
$build = array_merge_recursive($build, $plugin
->build($left_revision, $right_revision, $entity));
$build['diff']['#prefix'] = '<div class="diff-responsive-table-wrapper">';
$build['diff']['#suffix'] = '</div>';
$build['diff']['#attributes']['class'][] = 'diff-responsive-table';
}
}
$build['#attached']['library'][] = 'diff/diff.general';
return $build;
}
protected function buildLayoutNavigation(ContentEntityInterface $entity, $left_revision_id, $right_revision_id, $active_filter) {
$links = [];
$layouts = $this->diffLayoutManager
->getPluginOptions();
foreach ($layouts as $key => $value) {
$links[$key] = array(
'title' => $value,
'url' => $this
->diffRoute($entity, $left_revision_id, $right_revision_id, $key),
);
}
$filter = $links[$active_filter];
unset($links[$active_filter]);
array_unshift($links, $filter);
$filter = [
'#type' => 'operations',
'#links' => $links,
];
return $filter;
}
protected function buildRevisionsNavigation(ContentEntityInterface $entity, array $revision_ids, $left_revision_id, $right_revision_id, $filter) {
$revisions_count = count($revision_ids);
$layout_options =& drupal_static(__FUNCTION__);
if (!isset($layout_options)) {
$layout_options = UrlHelper::filterQueryParameters($this->requestStack
->getCurrentRequest()->query
->all(), [
'page',
]);
}
if ($revisions_count == 2) {
return [];
}
else {
$left_link = $right_link = '';
$element = [
'#type' => 'item',
'#title' => $this
->t('Navigation'),
'#wrapper_attributes' => [
'class' => 'diff-navigation',
],
];
$i = 0;
while ($left_revision_id > $revision_ids[$i]) {
$i += 1;
}
if ($i != 0) {
$left_link = Link::fromTextAndUrl($this
->t('Previous change'), $this
->diffRoute($entity, $revision_ids[$i - 1], $left_revision_id, $filter, $layout_options))
->toString();
}
$element['left'] = [
'#type' => 'markup',
'#markup' => $left_link,
'#prefix' => '<div class="diff-navigation__link prev-link">',
'#suffix' => '</div>',
];
$i = 0;
while ($i < $revisions_count && $right_revision_id >= $revision_ids[$i]) {
$i += 1;
}
if ($revisions_count != $i && $revision_ids[$i - 1] != $revision_ids[$revisions_count - 1]) {
$right_link = Link::fromTextAndUrl($this
->t('Next change'), $this
->diffRoute($entity, $right_revision_id, $revision_ids[$i], $filter, $layout_options))
->toString();
}
$element['right'] = [
'#type' => 'markup',
'#markup' => $right_link,
'#prefix' => '<div class="diff-navigation__link next-link">',
'#suffix' => '</div>',
];
return $element;
}
}
public static function diffRoute(ContentEntityInterface $entity, $left_revision_id, $right_revision_id, $layout = NULL, array $layout_options = NULL) {
$entity_type_id = $entity
->getEntityTypeId();
if ($entity
->getEntityTypeId() == 'node') {
$route_name = 'diff.revisions_diff';
}
else {
$route_name = "entity.{$entity_type_id}.revisions_diff";
}
$route_parameters = [
$entity_type_id => $entity
->id(),
'left_revision' => $left_revision_id,
'right_revision' => $right_revision_id,
];
if ($layout) {
$route_parameters['filter'] = $layout;
}
$options = [];
if ($layout_options) {
$options = [
'query' => $layout_options,
];
}
return Url::fromRoute($route_name, $route_parameters, $options);
}
}