Skip to content
This repository has been archived by the owner on Aug 25, 2022. It is now read-only.

Refactor graph loader for readability. #86

Open
wants to merge 4 commits into
base: 8.x-1.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 6 additions & 0 deletions rdf_entity.links.task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,9 @@ entity.rdf_entity.collection:
title: RDF
route_name: entity.rdf_entity.collection
base_route: system.admin_content

entity.rdf_entity.version_history:
route_name: entity.rdf_entity.version_history
base_route: entity.rdf_entity.canonical
title: 'Revisions'
weight: 20
63 changes: 63 additions & 0 deletions rdf_entity.routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ entity.rdf_entity.canonical:
# Calls the access controller of the entity, $operation 'view'.
_entity_access: 'rdf_entity.view'

entity.rdf_entity.version_history:
path: '/rdf_entity/{rdf_entity}/revisions'
defaults:
_title: 'Revisions'
_controller: '\Drupal\rdf_entity\Controller\RdfController::revisionOverview'
requirements:
_entity_access: 'rdf_entity.edit'
options:
parameters:
rdf_entity:
type: entity:rdf_entity

entity.rdf_entity.collection:
path: 'admin/content/rdf'
defaults:
Expand Down Expand Up @@ -148,3 +160,54 @@ entity.rdf_entity_graph.disable:
toggle_operation: disable
requirements:
_custom_access: 'Drupal\rdf_entity\Controller\RdfEntityGraphToggle::access'

entity.rdf_entity.revision:
path: '/rdf_entity/{rdf_entity}/revisions/{rdf_revision}/view'
defaults:
_controller: 'Drupal\rdf_entity\Controller\RdfController::revisionShow'
options:
parameters:
rdf_entity:
type: entity:rdf_entity
rdf_revision:
type: entity:rdf_entity
requirements:
# Calls the access controller of the entity, $operation 'view'.
_entity_access: 'rdf_entity.view'

rdf_entity.revision_revert_confirm:
path: '/rdf_entity/{rdf_entity}/revisions/{rdf_revision}/revert'
defaults:
_form: '\Drupal\rdf_entity\Form\RdfRevisionRevertForm'
_title: 'Revert to earlier revision'
options:
parameters:
rdf_entity:
type: entity:rdf_entity
rdf_revision:
type: entity:rdf_entity
requirements:
_entity_access: 'rdf_entity.edit'
# T
rdf_entity.revision_revert_translation_confirm:
path: '/rdf_entity/{rdf_entity}/revisions/{rdf_revision}/revert/{langcode}'
defaults:
_form: '\Drupal\rdf_entity\Form\RdfRevisionRevertTranslationForm'
_title: 'Revert to earlier revision of a translation'
parameters:
rdf_entity:
type: entity:rdf_entity
rdf_revision:
type: entity:rdf_entity

rdf_entity.revision_delete_confirm:
path: '/rdf_entity/{rdf_entity}/revisions/{rdf_revision}/delete'
defaults:
_form: '\Drupal\rdf_entity\Form\RdfRevisionDeleteForm'
_title: 'Delete earlier revision'
options:
parameters:
rdf_entity:
type: entity:rdf_entity
rdf_revision:
type: entity:rdf_entity
3 changes: 3 additions & 0 deletions rdf_entity.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,6 @@ services:
arguments: ['@typed_data_manager']
tags:
- { name: event_subscriber }
rdf_entity.graph_priority.filter:
class: Drupal\rdf_entity\LayeredGraphPriorityFilter
arguments: ['@entity_type.manager']
225 changes: 224 additions & 1 deletion src/Controller/RdfController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,57 @@

use Drupal\Component\Utility\Xss;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\Controller\EntityViewController;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\rdf_entity\RdfEntitySparqlStorageInterface;
use Drupal\rdf_entity\RdfEntityTypeInterface;
use Drupal\rdf_entity\RdfInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Provides route responses for rdf_entity.module.
*/
class RdfController extends ControllerBase {
class RdfController extends ControllerBase implements ContainerInjectionInterface {

/**
* The date formatter service.
*
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;

/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;

/**
* Constructs a RdfController object.
*
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
*/
public function __construct(DateFormatterInterface $date_formatter, RendererInterface $renderer) {
$this->dateFormatter = $date_formatter;
$this->renderer = $renderer;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('date.formatter'),
$container->get('renderer')
);
}

/**
* Route title callback.
Expand Down Expand Up @@ -108,4 +152,183 @@ public function addPage() {
return $build;
}

/**
* Generates an overview table of older revisions of a entity.
*
* @param \Drupal\rdf_entity\RdfInterface $rdf_entity
* A rdf object.
*
* @return array
* An array as expected by \Drupal\Core\Render\RendererInterface::render().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function revisionOverview(RdfInterface $rdf_entity) {
$account = $this->currentUser();
$langcode = $rdf_entity->language()->getId();
$langname = $rdf_entity->language()->getName();
$languages = $rdf_entity->getTranslationLanguages();
$has_translations = (count($languages) > 1);
$rdf_storage = $this->entityManager()->getStorage('rdf_entity');
$type = $rdf_entity->getType();

$build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $rdf_entity->label()]) : $this->t('Revisions for %title', ['%title' => $rdf_entity->label()]);
$header = [$this->t('Revision'), $this->t('Operations')];

$revert_permission = (($account->hasPermission("revert $type revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $rdf_entity->access('update'));
$delete_permission = (($account->hasPermission("delete $type revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $rdf_entity->access('delete'));

$rows = [];
$default_revision = $rdf_entity->getRevisionId();
$current_revision_displayed = FALSE;

$revisions = $this->getRevisionIds($rdf_entity, $rdf_storage);

foreach ($revisions as $vid) {
/** @var \Drupal\rdf_entity\RdfInterface $revision */
$revision = $rdf_storage->loadRevision($vid);
// Only show revisions that are affected by the language that is being
// displayed.
// @todo && $revision->getTranslation($langcode)->isRevisionTranslationAffected()
if ($revision->hasTranslation($langcode) ) {
$username = [
'#theme' => 'username',
'#account' => $revision->getRevisionUser(),
];

// Use revision link to link to revisions that are not active.
$date = $this->dateFormatter->format($revision->getChangedTime(), '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 = $this->l($date, new Url('entity.rdf_entity.revision', ['rdf_entity' => $rdf_entity->id(), 'rdf_revision' => $vid]));
}
else {
$link = $rdf_entity->link($date);
$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 = [];
if ($revert_permission) {
$links['revert'] = [
'title' => $vid < $rdf_entity->getRevisionId() ? $this->t('Revert') : $this->t('Set as current revision'),
'url' => $has_translations ?
Url::fromRoute('rdf_entity.revision_revert_translation_confirm', ['rdf_rntity' => $rdf_entity->id(), 'rdf_revision' => $vid, 'langcode' => $langcode]) :
Url::fromRoute('rdf_entity.revision_revert_confirm', ['rdf_entity' => $rdf_entity->id(), 'rdf_revision' => $vid]),
];
}

if ($delete_permission) {
$links['delete'] = [
'title' => $this->t('Delete'),
'url' => Url::fromRoute('rdf_entity.revision_delete_confirm', ['rdf_entity' => $rdf_entity->id(), 'rdf_revision' => $vid]),
];
}

$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];

$rows[] = $row;
}
}
}

$build['node_revisions_table'] = [
'#theme' => 'table',
'#rows' => $rows,
'#header' => $header,
'#attached' => [
'library' => ['node/drupal.node.admin'],
],
'#attributes' => ['class' => 'node-revision-table'],
];

$build['pager'] = ['#type' => 'pager'];

// Bypass cache for development
$build['#cache']['max-age'] = 0;

return $build;
}

/**
* Gets a list of rdf revision IDs for a specific entity.
*
* @param \Drupal\rdf_entity\RdfInterface $rdf_entity
* The rdf entity.
* @param \Drupal\rdf_entity\RdfEntitySparqlStorageInterface $rdf_storage
* The rdf storage handler.
*
* @return int[]
* Node revision IDs (in descending order).
*/
protected function getRevisionIds(RdfInterface $rdf_entity, RdfEntitySparqlStorageInterface $rdf_storage) {
$query = $rdf_storage->getQuery()
->allRevisions()
//->condition($rdf_entity->getEntityType()->getKey('bundle'), 'event')
->condition($rdf_entity->getEntityType()->getKey('id'), $rdf_entity->id())
->sort($rdf_entity->getEntityType()->getKey('revision'), 'DESC')
->pager(50);
$result= $query->execute();
return array_keys($result);
}


/**
* Displays a rdf revision.
*
* @param \Drupal\rdf_entity\RdfInterface $rdf_revision
* The rdf revision.
*
* @return array
* An array suitable for \Drupal\Core\Render\RendererInterface::render().
*/
public function revisionShow(RdfInterface $rdf_revision) {
$rdf_entity = $this->entityManager()->getTranslationFromContext($rdf_revision);
$view_controller = new EntityViewController($this->entityManager, $this->renderer);
$page = $view_controller->view($rdf_entity);
unset($page['#cache']);
return $page;
}

}
8 changes: 8 additions & 0 deletions src/Entity/Query/Sparql/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,14 @@ protected function conditionGroupFactory($conjunction = 'AND') {
return new $class($conjunction, $this, $this->namespaces, $this->graphHandler, $this->fieldHandler);
}

public function getLatestRevision() {
return $this->latestRevision;
}

public function getAllRevisions() {
return $this->allRevisions;
}

/**
* Return the query string for debugging help.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Entity/Query/Sparql/SparqlCondition.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,16 @@ public function condition($field = NULL, $value = NULL, $operator = NULL, $lang
* Thrown if the value is NULL or the operator is not allowed.
*/
public function keyCondition($field, $value, $operator) {
// Revision handling.
$query = $this->query;
if ($query instanceof SparqlQueryInterface) {
if ($field === 'id' && $query->getAllRevisions()) {
$field = 'vid';
}
}



// @todo: Add support for loadMultiple with empty Id (load all).
if ($value == NULL) {
throw new \Exception('The value cannot be NULL for conditions related to the Id and bundle keys.');
Expand Down
3 changes: 3 additions & 0 deletions src/Entity/Query/Sparql/SparqlQueryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,7 @@ public function getEntityType(): EntityTypeInterface;
*/
public function getEntityStorage(): RdfEntitySparqlStorageInterface;

public function getLatestRevision();

public function getAllRevisions();
}
Loading