Commit 9073a347 authored by dawehner's avatar dawehner Committed by larowlan

Issue #2702041 by dawehner, jibran, Crell, lussoluca: Add views relationship...

Issue #2702041 by dawehner, jibran, Crell, lussoluca: Add views relationship from content to latest revision
parent 47b10718
......@@ -48,3 +48,12 @@ block_content.type.*.third_party.workbench_moderation:
default_moderation_state:
type: string
label: 'Moderation state for new block content'
views.filter.latest_revision:
type: views_filter
label: 'Latest revision'
type: mapping
mapping:
value:
type: string
label: 'Value'
<?php
namespace Drupal\workbench_moderation;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Provides the workbench_moderation views integration.
*/
class ViewsData {
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The moderation information.
*
* @var \Drupal\workbench_moderation\ModerationInformationInterface
*/
protected $moderationInformation;
/**
* Creates a new ViewsData instance.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\workbench_moderation\ModerationInformationInterface $moderation_information
* The moderation information.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_information) {
$this->entityTypeManager = $entity_type_manager;
$this->moderationInformation = $moderation_information;
}
/**
* Returns the views data.
*
* @return array
* The views data.
*/
public function getViewsData() {
$data = [];
$data['workbench_revision_tracker']['table']['group'] = $this->t('Workbench moderation');
$data['workbench_revision_tracker']['entity_type'] = [
'title' => $this->t('Entity type'),
'field' => [
'id' => 'standard',
],
'filter' => [
'id' => 'string',
],
'argument' => [
'id' => 'string',
],
'sort' => [
'id' => 'standard',
],
];
$data['workbench_revision_tracker']['entity_id'] = [
'title' => $this->t('Entity ID'),
'field' => [
'id' => 'standard',
],
'filter' => [
'id' => 'numeric',
],
'argument' => [
'id' => 'numeric',
],
'sort' => [
'id' => 'standard',
],
];
$data['workbench_revision_tracker']['langcode'] = [
'title' => $this->t('Entity language'),
'field' => [
'id' => 'standard',
],
'filter' => [
'id' => 'language',
],
'argument' => [
'id' => 'language',
],
'sort' => [
'id' => 'standard',
],
];
$data['workbench_revision_tracker']['revision_id'] = [
'title' => $this->t('Latest revision ID'),
'field' => [
'id' => 'standard',
],
'filter' => [
'id' => 'numeric',
],
'argument' => [
'id' => 'numeric',
],
'sort' => [
'id' => 'standard',
],
];
// Add a join for each entity type to the workbench_revision_tracker table.
foreach ($this->moderationInformation->selectRevisionableEntities($this->entityTypeManager->getDefinitions()) as $entity_type_id => $entity_type) {
/** @var \Drupal\views\EntityViewsDataInterface $views_data */
// We need the views_data handler in order to get the table name later.
if ($this->entityTypeManager->hasHandler($entity_type_id, 'views_data') && $views_data = $this->entityTypeManager->getHandler($entity_type_id, 'views_data')) {
// Add a join from the entity base table to the revision tracker table.
$base_table = $views_data->getViewsTableForEntityType($entity_type);
$data['workbench_revision_tracker']['table']['join'][$base_table] = [
'left_field' => $entity_type->getKey('id'),
'field' => 'entity_id',
'extra' => [
[
'field' => 'entity_type',
'value' => $entity_type_id,
],
],
];
// Some entity types might not be translatable.
if ($entity_type->hasKey('langcode')) {
$data['workbench_revision_tracker']['table']['join'][$base_table]['extra'][] = [
'field' => 'langcode',
'left_field' => $entity_type->getKey('langcode'),
'operation' => '=',
];
}
// Add a relationship between the revision tracker table to the latest
// revision on the entity revision table.
$data['workbench_revision_tracker']['latest_revision__' . $entity_type_id] = [
'title' => $this->t('@label latest revision', ['@label' => $entity_type->getLabel()]),
'group' => $this->t('@label revision', ['@label' => $entity_type->getLabel()]),
'relationship' => [
'id' => 'standard',
'label' => $this->t('@label latest revision', ['@label' => $entity_type->getLabel()]),
'base' => $this->getRevisionViewsTableForEntityType($entity_type),
'base field' => $entity_type->getKey('revision'),
'relationship field' => 'revision_id',
'extra' => [
[
'left_field' => 'entity_type',
'value' => $entity_type_id,
],
],
],
];
// Some entity types might not be translatable.
if ($entity_type->hasKey('langcode')) {
$data['workbench_revision_tracker']['latest_revision__' . $entity_type_id]['relationship']['extra'][] = [
'left_field' => 'langcode',
'field' => $entity_type->getKey('langcode'),
'operation' => '=',
];
}
}
}
return $data;
}
/**
* Gets the table of an entity type to be used as revision table in views.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return string
* The revision base table.
*/
protected function getRevisionViewsTableForEntityType(EntityTypeInterface $entity_type) {
return $entity_type->getRevisionDataTable() ?: $entity_type->getRevisionTable();
}
}
<?php
namespace Drupal\Tests\workbench_moderation\Kernel;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
use Drupal\views\Views;
/**
* Tests the views integration of workbench_moderation.
*
* @group workbench_moderation
*/
class ViewsDataTest extends ViewsKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'workbench_moderation_test_views',
'node',
'workbench_moderation',
];
/**
* {@inheritdoc}
*/
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
$this->installEntitySchema('node');
$this->installEntitySchema('user');
$this->installSchema('node', 'node_access');
$this->installConfig('workbench_moderation_test_views');
}
public function testViewsData() {
$node_type = NodeType::create([
'type' => 'page',
]);
$node_type->setThirdPartySetting('workbench_moderation', 'enabled', TRUE);
$node_type->save();
$node = Node::create([
'type' => 'page',
'title' => 'Test title first revision',
'moderation_state' => 'published',
]);
$node->save();
$revision = clone $node;
$revision->setNewRevision(TRUE);
$revision->isDefaultRevision(FALSE);
$revision->title->value = 'Test title second revision';
$revision->moderation_state->target_id = 'draft';
$revision->save();
$view = Views::getView('test_workbench_moderation_latest_revision');
$view->execute();
// Ensure that the workbench_revision_tracker contains the right latest
// revision ID.
// Also ensure that the relationship back to the revision table contains the
// right latest revision.
$expected_result = [
[
'nid' => $node->id(),
'revision_id' => $revision->getRevisionId(),
'title' => $revision->label(),
'moderation_state_revision' => 'published',
'moderation_state' => 'published',
],
];
$this->assertIdenticalResultset($view, $expected_result, ['nid' => 'nid', 'workbench_revision_tracker_revision_id' => 'revision_id', 'moderation_state_revision' => 'moderation_state_revision', 'moderation_state' => 'moderation_state']);
}
}
......@@ -216,6 +216,8 @@ function workbench_moderation_action_info_alter(&$definitions) {
/**
* Implements hook_views_data_alter().
*
* @todo Use \Drupal\workbench_moderation\ViewsData
*/
function workbench_moderation_views_data_alter(array &$data) {
......
......@@ -33,3 +33,6 @@ services:
arguments: ['@database']
tags:
- { name: backend_overridable }
workbench_moderation.views_data:
class: \Drupal\workbench_moderation\ViewsData
arguments: ['@entity_type.manager', '@workbench_moderation.moderation_information']
<?php
/**
* Implements hook_views_data().
*/
function workbench_moderation_views_data() {
/** @var \Drupal\workbench_moderation\ViewsData $workbench_moderation_views_data */
$workbench_moderation_views_data = \Drupal::service('workbench_moderation.views_data');
return $workbench_moderation_views_data->getViewsData();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment