Commit bd1f226e authored by alexpott's avatar alexpott

Issue #1881606 by dawehner, jibran: Use a derivative to integrate all entities as row plugins.

parent 7b76e918
......@@ -549,3 +549,15 @@ function comment_views_data_alter(&$data) {
);
}
/**
* Implements hook_views_plugins_row_alter().
*
* Replaces the generic row plugin by a custom one for comments.
*
* @see \Drupal\views\Plugin\views\row\EntityRow
*/
function comment_views_plugins_row_alter(array &$plugins) {
$plugins['entity:comment']['class'] = 'Drupal\comment\Plugin\views\row\CommentRow';
$plugins['entity:comment']['module'] = 'comment';
}
......@@ -2,32 +2,20 @@
/**
* @file
* Definition of Drupal\comment\Plugin\views\row\CommentRow.
* Contains \Drupal\comment\Plugin\views\row\CommentRow.
*/
namespace Drupal\comment\Plugin\views\row;
use Drupal\system\Plugin\views\row\EntityRow;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\views\Plugin\views\row\EntityRow;
/**
* Plugin which performs a comment_view on the resulting object.
*
* @Plugin(
* id = "comment",
* module = "comment",
* title = @Translation("Comment"),
* help = @Translation("Display the comment with standard comment view."),
* base = {"comment"},
* entity_type = "comment",
* display_types = {"normal"}
* )
*/
class CommentRow extends EntityRow {
/**
* Overrides Drupal\system\Plugin\views\row\Entity::defineOptions().
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
......@@ -37,7 +25,7 @@ protected function defineOptions() {
}
/**
* Overrides Drupal\system\Plugin\views\row\Entity::buildOptionsForm().
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, &$form_state) {
parent::buildOptionsForm($form, $form_state);
......@@ -50,7 +38,7 @@ public function buildOptionsForm(&$form, &$form_state) {
}
/**
* Overrides Drupal\system\Plugin\views\row\Entity::render().
* {@inheritdoc}
*/
function render($row) {
$entity_id = $row->{$this->field_alias};
......
......@@ -127,7 +127,7 @@ protected function blockDisplayOptions(array $form, array &$form_state) {
protected function display_options_row(&$display_options, $row_plugin, $row_options) {
switch ($row_plugin) {
case 'comment':
$display_options['row']['type'] = 'comment';
$display_options['row']['type'] = 'entity:comment';
$display_options['row']['options']['links'] = !empty($row_options['links']);
break;
}
......
......@@ -74,7 +74,7 @@ public function testCommentWizard() {
$view = views_get_view($view['id']);
$view->initHandlers();
$row = $view->display_handler->getOption('row');
$this->assertEqual($row['type'], 'comment');
$this->assertEqual($row['type'], 'entity:comment');
// Check for the default filters.
$this->assertEqual($view->filter['status']->table, 'comment');
......
......@@ -39,7 +39,7 @@ display:
style:
type: default
row:
type: node
type: 'entity:node'
display_plugin: default
display_title: Master
id: default
......
......@@ -133,7 +133,7 @@ display:
query_comment: ''
query_tags: { }
row:
type: node
type: 'entity:node'
options:
build_mode: teaser
comments: '0'
......
......@@ -2,15 +2,12 @@
/**
* @file
* Definition of Drupal\node\Plugin\views\row\NodeRow.
* Contains \Drupal\node\Plugin\views\row\NodeRow.
*/
namespace Drupal\node\Plugin\views\row;
use Drupal\views\ViewExecutable;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\system\Plugin\views\row\EntityRow;
use Drupal\views\Plugin\views\row\EntityRow;
/**
* Plugin which performs a node_view on the resulting object.
......@@ -18,21 +15,11 @@
* Most of the code on this object is in the theme function.
*
* @ingroup views_row_plugins
*
* @Plugin(
* id = "node",
* module = "node",
* title = @Translation("Content"),
* help = @Translation("Display the content with standard node view."),
* base = {"node"},
* entity_type = "node",
* display_types = {"normal"}
* )
*/
class NodeRow extends EntityRow {
/**
* Overrides Drupal\system\Plugin\views\row\Entity::defineOptions().
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
......@@ -46,7 +33,7 @@ protected function defineOptions() {
}
/**
* Overrides Drupal\system\Plugin\views\row\Entity::buildOptionsForm().
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, &$form_state) {
parent::buildOptionsForm($form, $form_state);
......
......@@ -219,13 +219,13 @@ protected function blockDisplayOptions(array $form, array &$form_state) {
protected function display_options_row(&$display_options, $row_plugin, $row_options) {
switch ($row_plugin) {
case 'full_posts':
$display_options['row']['type'] = 'node';
$display_options['row']['type'] = 'entity:node';
$display_options['row']['options']['build_mode'] = 'full';
$display_options['row']['options']['links'] = !empty($row_options['links']);
$display_options['row']['options']['comments'] = !empty($row_options['comments']);
break;
case 'teasers':
$display_options['row']['type'] = 'node';
$display_options['row']['type'] = 'entity:node';
$display_options['row']['options']['build_mode'] = 'teaser';
$display_options['row']['options']['links'] = !empty($row_options['links']);
$display_options['row']['options']['comments'] = !empty($row_options['comments']);
......
......@@ -650,3 +650,15 @@ function node_views_wizard() {
}
}
/**
* Implements hook_views_plugins_row_alter().
*
* Replaces the generic row plugin by a custom one for nodes.
*
* @see \Drupal\views\Plugin\views\row\EntityRow
*/
function node_views_plugins_row_alter(array &$plugins) {
$plugins['entity:node']['class'] = 'Drupal\node\Plugin\views\row\NodeRow';
$plugins['entity:node']['module'] = 'node';
}
......@@ -33,7 +33,7 @@ display:
build_mode: teaser
comments: '0'
links: '1'
type: node
type: 'entity:node'
sorts: { }
style:
type: default
......
......@@ -66,7 +66,7 @@ display:
style:
type: default
row:
type: node
type: 'entity:node'
display_plugin: default
display_title: Master
id: default
......
......@@ -2,34 +2,22 @@
/**
* @file
* Definition of Drupal\user\Plugin\views\row\UserRow.
* Contains \Drupal\user\Plugin\views\row\UserRow.
*/
namespace Drupal\user\Plugin\views\row;
use Drupal\system\Plugin\views\row\EntityRow;
use Drupal\Component\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\views\Plugin\views\row\EntityRow;
/**
* A row plugin which renders a user.
*
* @ingroup views_row_plugins
*
* @Plugin(
* id = "user",
* module = "user",
* title = @Translation("User"),
* help = @Translation("Display the user with standard user view."),
* base = {"users"},
* entity_type = "user",
* display_types = {"normal"}
* )
*/
class UserRow extends EntityRow {
/**
* Overrides Drupal\system\Plugin\views\row\Entity::defineOptions().
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
......
......@@ -377,3 +377,15 @@ function user_views_data() {
return $data;
}
/**
* Implements hook_views_plugins_row_alter().
*
* Replaces the generic row plugin by a custom one for users.
*
* @see \Drupal\views\Plugin\views\row\EntityRow
*/
function user_views_plugins_row_alter(array &$plugins) {
$plugins['entity:user']['class'] = 'Drupal\user\Plugin\views\row\UserRow';
$plugins['entity:user']['module'] = 'user';
}
......@@ -105,7 +105,7 @@ display:
row_class_special: '1'
uses_fields: '0'
row:
type: node
type: 'entity:node'
options:
view_mode: teaser
links: '1'
......
......@@ -152,7 +152,7 @@ display:
row_class_special: '1'
uses_fields: '0'
row:
type: node
type: 'entity:node'
options:
view_mode: teaser
links: '1'
......
<?php
/**
* @file
* Contains \Drupal\views\Plugin\Derivative\ViewsEntityRow.
*/
namespace Drupal\views\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DerivativeInterface;
use Drupal\views\Views;
/**
* Provides views row plugin definitions for all non-special entity types.
*
* @ingroup views_row_plugins
*
* @see \Drupal\views\Plugin\views\row\EntityRow
*/
class ViewsEntityRow implements DerivativeInterface {
/**
* Stores all entity row plugin information.
*
* @var array
*/
protected $derivatives = array();
/**
* {@inheritdoc}
*/
public function getDerivativeDefinition($derivative_id, array $base_plugin_definition) {
if (!empty($this->derivatives) && !empty($this->derivatives[$derivative_id])) {
return $this->derivatives[$derivative_id];
}
$this->getDerivativeDefinitions($base_plugin_definition);
return $this->derivatives[$derivative_id];
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions(array $base_plugin_definition) {
$entity_types = \Drupal::entityManager()->getDefinitions();
$views_data = Views::viewsData();
foreach ($entity_types as $entity_type => $entity_info) {
// Just add support for entity types which have a views integration.
if (isset($entity_info['base_table']) && $views_data->get($entity_info['base_table']) && \Drupal::entityManager()->hasController($entity_type, 'render')) {
$this->derivatives[$entity_type] = array(
'id' => 'entity:' . $entity_type,
'module' => 'views',
'title' => $entity_info['label'],
'help' => t('Display the @label', array('@label' => $entity_info['label'])),
'base' => array($entity_info['base_table']),
'entity_type' => $entity_type,
'display_types' => array('normal'),
'class' => $base_plugin_definition['class'],
);
}
}
return $this->derivatives;
}
}
......@@ -2,17 +2,24 @@
/**
* @file
* Definition of Drupal\system\Plugin\views\row\EntityRow.
* Contains \Drupal\views\Plugin\views\row\EntityRow.
*/
namespace Drupal\system\Plugin\views\row;
namespace Drupal\views\Plugin\views\row;
use Drupal\views\Plugin\views\row\RowPluginBase;
use Drupal\Core\Entity\EntityManager;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\ViewExecutable;
use Drupal\Component\Annotation\Plugin;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Generic entity row plugin to provide a common base for all entity types.
*
* @Plugin(
* id = "entity",
* derivative = "Drupal\views\Plugin\Derivative\ViewsEntityRow"
* )
*/
class EntityRow extends RowPluginBase {
......@@ -52,17 +59,36 @@ class EntityRow extends RowPluginBase {
protected $build = array();
/**
* Overrides Drupal\views\Plugin\views\PluginBase::init().
* {@inheritdoc}
*
* @param \Drupal\Core\Entity\EntityManager $entity_manager
* The entity manager.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityManager $entity_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityManager = $entity_manager;
}
/**
* {@inheritdoc}
*/
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
$this->entityType = $this->definition['entity_type'];
$this->entityInfo = entity_get_info($this->entityType);
$this->entityInfo = $this->entityManager->getDefinition($this->entityType);
$this->base_table = $this->entityInfo['base_table'];
$this->base_field = $this->entityInfo['entity_keys']['id'];
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('plugin.manager.entity'));
}
/**
* Overrides Drupal\views\Plugin\views\row\RowPluginBase::defineOptions().
*/
......@@ -107,7 +133,12 @@ protected function buildViewModeOptions() {
*/
public function summaryTitle() {
$options = $this->buildViewModeOptions();
return check_plain($options[$this->options['view_mode']]);
if (isset($options[$this->options['view_mode']])) {
return check_plain($options[$this->options['view_mode']]);
}
else {
return t('No view mode selected');
}
}
/**
......
<?php
/**
* @file
* Contains \Drupal\views\Tests\Plugin\RowEntityTest.
*/
namespace Drupal\views\Tests\Plugin;
use Drupal\views\Tests\ViewUnitTestBase;
/**
* Tests the generic entity row plugin.
*
* @see \Drupal\views\Plugin\views\row\EntityRow
*/
class RowEntityTest extends ViewUnitTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('taxonomy', 'field', 'entity', 'system');
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_entity_row');
/**
* A string for assert raw and text helper methods.
*
* @var string
*/
protected $content;
public static function getInfo() {
return array(
'name' => 'Row: Entity',
'description' => 'Tests the generic entity row plugin.',
'group' => 'Views Plugins',
);
}
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', array('menu_router'));
$this->installSchema('taxonomy', array('taxonomy_term_data', 'taxonomy_term_hierarchy'));
}
/**
* Tests the entity row handler.
*/
public function testEntityRow() {
$vocab = entity_create('taxonomy_vocabulary', array('name' => $this->randomName(), 'vid' => strtolower($this->randomName())));
$vocab->save();
$term = entity_create('taxonomy_term', array('name' => $this->randomName(), 'vid' => $vocab->id() ));
$term->save();
$view = views_get_view('test_entity_row');
$this->content = $view->preview();
$this->content = drupal_render($this->content);
$this->assertText($term->label(), 'The rendered entity appears as row in the view.');
}
/**
* Pass if the text is found in set string.
*
* @param string $text
* Text to look for.
* @param string $message
* (optional) A message to display with the assertion. Do not translate
* messages: use format_string() to embed variables in the message text, not
* t(). If left blank, a default message will be displayed.
* @param string $group
* (optional) The group this message is in, which is displayed in a column
* in test output. Use 'Debug' to indicate this is debugging output. Do not
* translate this string. Defaults to 'Other'; most tests do not override
* this default.
*
* @return bool TRUE on pass, FALSE on fail.
*/
protected function assertText($text, $message = '', $group = 'Other') {
if (!$message) {
$message = t('Raw "@raw" found', array('@raw' => $text));
}
return $this->assert(strpos(filter_xss($this->content, array()), $text) !== FALSE, $message, $group);
}
}
base_table: taxonomy_term_data
core: '8'
description: ''
status: '1'
display:
default:
display_options:
defaults:
fields: '0'
pager: '0'
pager_options: '0'
sorts: '0'
pager:
options:
offset: '0'
type: none
pager_options: { }
row:
type: 'entity:taxonomy_term'
options:
relationship: none
view_mode: full
display_plugin: default
display_title: Master
id: default
position: '0'
label: ''
id: test_entity_row
tag: ''
......@@ -74,7 +74,7 @@ display:
style:
type: default
row:
type: node
type: 'entity:node'
options:
comments: '0'
links: '1'
......
......@@ -51,7 +51,7 @@ display:
build_mode: teaser
comments: '0'
links: '1'
type: node
type: 'entity:node'
sorts:
created:
field: created
......
......@@ -68,7 +68,7 @@ display:
style:
type: default
row:
type: node
type: 'entity:node'
display_plugin: default
display_title: Master
id: default
......
......@@ -26,7 +26,7 @@ display:
style:
type: default
row:
type: node
type: 'entity:node'
options:
build_mode: teaser
links: '1'
......
......@@ -41,7 +41,7 @@ display:
style:
type: default
row:
type: node
type: 'entity:node'
options:
build_mode: teaser
links: '1'
......