From 747641b287abfd49c4a21c610a3ae732a5a45f4c Mon Sep 17 00:00:00 2001
From: dereine <dereine@99340.no-reply.drupal.org>
Date: Thu, 18 Oct 2012 10:33:10 +0200
Subject: [PATCH] Issue #1740000 by dawehner: Added Provide a generic entity
 row plugin.

---
 lib/Views/comment/Plugin/views/row/View.php  |  81 +++--------
 lib/Views/node/Plugin/views/row/View.php     |  85 ++---------
 lib/Views/system/Plugin/views/row/Entity.php | 141 +++++++++++++++++++
 lib/Views/user/Plugin/views/row/View.php     |  72 ++--------
 modules/comment.views.inc                    |  26 ----
 views.module                                 |   8 +-
 6 files changed, 180 insertions(+), 233 deletions(-)
 create mode 100644 lib/Views/system/Plugin/views/row/Entity.php

diff --git a/lib/Views/comment/Plugin/views/row/View.php b/lib/Views/comment/Plugin/views/row/View.php
index 2389ba48a4e7..094971b5fc3e 100644
--- a/lib/Views/comment/Plugin/views/row/View.php
+++ b/lib/Views/comment/Plugin/views/row/View.php
@@ -7,7 +7,7 @@
 
 namespace Views\comment\Plugin\views\row;
 
-use Drupal\views\Plugin\views\row\RowPluginBase;
+use Views\system\Plugin\views\row\Entity;
 use Drupal\Core\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
 
@@ -21,46 +21,28 @@
  *   help = @Translation("Display the comment with standard comment view."),
  *   theme = "views_view_row_comment",
  *   base = {"comment"},
+ *   entity_type = "comment",
  *   type = "normal"
  * )
  */
-class View extends RowPluginBase {
-
-  var $base_field = 'cid';
-  var $base_table = 'comment';
-
-  /**
-   * Stores all comments which are preloaded.
-   */
-  var $comments = array();
+class View extends Entity {
 
   /**
-   * Stores all nodes of all comments which are preloaded.
+   * Overrides Views\system\Plugin\views\row\Entity::defineOptions().
    */
-  var $nodes = array();
-
-  public function summaryTitle() {
-    return t('Settings');
-  }
-
   protected function defineOptions() {
     $options = parent::defineOptions();
-    $options['links'] = array('default' => TRUE, 'bool' => TRUE);
-    $options['view_mode'] = array('default' => 'full');
+    $options['links'] = array('default' => TRUE);
+    $options['view_mode']['default'] = 'full';
     return $options;
   }
 
+  /**
+   * Overrides Views\system\Plugin\views\row\Entity::buildOptionsForm().
+   */
   public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    $options = $this->options_form_summary_options();
-    $form['view_mode'] = array(
-      '#type' => 'select',
-      '#options' => $options,
-      '#title' => t('View mode'),
-      '#default_value' => $this->options['view_mode'],
-     );
-
     $form['links'] = array(
       '#type' => 'checkbox',
       '#title' => t('Display links'),
@@ -69,46 +51,15 @@ public function buildOptionsForm(&$form, &$form_state) {
   }
 
   /**
-   * Return the main options, which are shown in the summary title.
+   * Overrides Views\system\Plugin\views\row\Entity::render().
    */
-  function options_form_summary_options() {
-    $entity_info = entity_get_info('comment');
-    $options = array();
-    if (!empty($entity_info['view modes'])) {
-      foreach ($entity_info['view modes'] as $mode => $settings) {
-        $options[$mode] = $settings['label'];
-      }
-    }
-    if (empty($options)) {
-      $options = array(
-        'full' => t('Full content')
-      );
-    }
-
-    return $options;
-  }
-
-  function pre_render($result) {
-    $cids = array();
-
-    foreach ($result as $row) {
-      $cids[] = $row->cid;
-    }
-
-    // Load all comments.
-    $cresult = comment_load_multiple($cids);
-    $nids = array();
-    foreach ($cresult as $comment) {
-      $comment->depth = count(explode('.', $comment->thread)) - 1;
-      $this->comments[$comment->id()] = $comment;
-      $nids[] = $comment->nid;
-    }
-
-    // Load all nodes of the comments.
-    $nodes = node_load_multiple(array_unique($nids));
-    foreach ($nodes as $node) {
-      $this->nodes[$node->nid] = $node;
+  function render($row) {
+    $entity_id = $row->{$this->field_alias};
+    $build = $this->build[$entity_id];
+    if (!$this->options['links']) {
+      unset($build['links']);
     }
+    return drupal_render($build);
   }
 
 }
diff --git a/lib/Views/node/Plugin/views/row/View.php b/lib/Views/node/Plugin/views/row/View.php
index 2a081d4e0aea..ef7cb17bdcb7 100644
--- a/lib/Views/node/Plugin/views/row/View.php
+++ b/lib/Views/node/Plugin/views/row/View.php
@@ -10,7 +10,7 @@
 use Drupal\views\ViewExecutable;
 use Drupal\Core\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
-use Drupal\views\Plugin\views\row\RowPluginBase;
+use Views\system\Plugin\views\row\Entity;
 
 /**
  * Plugin which performs a node_view on the resulting object.
@@ -25,51 +25,32 @@
  *   title = @Translation("Content"),
  *   help = @Translation("Display the content with standard node view."),
  *   base = {"node"},
+ *   entity_type = "node",
  *   type = "normal"
  * )
  */
-class View extends RowPluginBase {
-
-  // Basic properties that let the row style follow relationships.
-  var $base_table = 'node';
-
-  var $base_field = 'nid';
-
-  // Stores the nodes loaded with pre_render.
-  var $nodes = array();
-
-  public function init(ViewExecutable $view, &$display, $options = NULL) {
-    parent::init($view, $display, $options);
-    // Handle existing views with the deprecated 'teaser' option.
-    if (isset($this->options['teaser'])) {
-      $this->options['build_mode'] = $this->options['teaser'] ? 'teaser' : 'full';
-    }
-    // Handle existing views which has used build_mode instead of view_mode.
-    if (isset($this->options['build_mode'])) {
-      $this->options['view_mode'] = $this->options['build_mode'];
-    }
-  }
+class View extends Entity {
 
+  /**
+   * Overrides Views\system\Plugin\views\row\Entity::defineOptions().
+   */
   protected function defineOptions() {
     $options = parent::defineOptions();
 
-    $options['view_mode'] = array('default' => 'teaser');
+    $options['view_mode']['default'] = 'teaser';
+
     $options['links'] = array('default' => TRUE, 'bool' => TRUE);
     $options['comments'] = array('default' => FALSE, 'bool' => TRUE);
 
     return $options;
   }
 
+  /**
+   * Overrides Views\system\Plugin\views\row\Entity::buildOptionsForm().
+   */
   public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
-    $options = $this->buildOptionsForm_summary_options();
-    $form['view_mode'] = array(
-      '#type' => 'select',
-      '#options' => $options,
-      '#title' => t('View mode'),
-      '#default_value' => $this->options['view_mode'],
-     );
     $form['links'] = array(
       '#type' => 'checkbox',
       '#title' => t('Display links'),
@@ -82,48 +63,4 @@ public function buildOptionsForm(&$form, &$form_state) {
     );
   }
 
-  /**
-   * Return the main options, which are shown in the summary title.
-   */
-  public function buildOptionsForm_summary_options() {
-    $entity_info = entity_get_info('node');
-    $options = array();
-    if (!empty($entity_info['view modes'])) {
-      foreach ($entity_info['view modes'] as $mode => $settings) {
-        $options[$mode] = $settings['label'];
-      }
-    }
-    if (empty($options)) {
-      $options = array(
-        'teaser' => t('Teaser'),
-        'full' => t('Full content')
-      );
-    }
-
-    return $options;
-  }
-
-  public function summaryTitle() {
-    $options = $this->buildOptionsForm_summary_options();
-    return check_plain($options[$this->options['view_mode']]);
-  }
-
-  function pre_render($values) {
-    $nids = array();
-    foreach ($values as $row) {
-      $nids[] = $row->{$this->field_alias};
-    }
-    $this->nodes = node_load_multiple($nids);
-  }
-
-  function render($row) {
-    if (isset($this->nodes[$row->{$this->field_alias}])) {
-      $node = $this->nodes[$row->{$this->field_alias}];
-      $node->view = $this->view;
-      $build = node_view($node, $this->options['view_mode']);
-
-      return drupal_render($build);
-    }
-  }
-
 }
diff --git a/lib/Views/system/Plugin/views/row/Entity.php b/lib/Views/system/Plugin/views/row/Entity.php
new file mode 100644
index 000000000000..cec930f0a562
--- /dev/null
+++ b/lib/Views/system/Plugin/views/row/Entity.php
@@ -0,0 +1,141 @@
+<?php
+
+/**
+ * @file
+ * Definition of Views\system\Plugin\views\row\Entity.
+ */
+
+namespace Views\system\Plugin\views\row;
+
+use Drupal\views\Plugin\views\row\RowPluginBase;
+use Drupal\views\ViewExecutable;
+
+/**
+ * Generic entity row plugin to provide a common base for all entity types.
+ */
+class Entity extends RowPluginBase {
+  protected $entityInfo1;
+
+  /**
+   * The table the entity is using for storage.
+   *
+   * @var string
+   */
+  public $base_table;
+
+  /**
+   * The actual field which is used for the entity id.
+   *
+   * @var string
+   */
+  public $base_field;
+
+  /**
+   * Stores the entity type of the result entities.
+   *
+   * @var string
+   */
+  protected $entityType;
+
+  /**
+   * Contains the entity info of the entity type of this row plugin instance.
+   *
+   * @see entity_get_info
+   */
+  protected $entityInfo;
+
+  /**
+   * Contains an array of render arrays, one for each rendered entity.
+   *
+   * @var array
+   */
+  protected $build = array();
+
+  /**
+   * Overrides Drupal\views\Plugin\views\row\RowPluginBase::init().
+   */
+  public function init(ViewExecutable $view, &$display, $options = NULL) {
+    parent::init($view, $display, $options);
+    $this->entityType = $this->definition['entity_type'];
+
+    $this->entityInfo = entity_get_info($this->entityType);
+    $this->base_table = $this->entityInfo['base table'];
+    $this->base_field = $this->entityInfo['entity keys']['id'];
+  }
+
+  /**
+   * Overrides Drupal\views\Plugin\views\row\RowPluginBase::defineOptions().
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+
+    $options['view_mode'] = array('default' => '');
+
+    return $options;
+  }
+
+  /**
+   * Overrides Drupal\views\Plugin\views\row\RowPluginBase::buildOptionsForm().
+   */
+  public function buildOptionsForm(&$form, &$form_state) {
+    parent::buildOptionsForm($form, $form_state);
+
+    $options = $this->buildViewModeOptions();
+    $form['view_mode'] = array(
+      '#type' => 'select',
+      '#options' => $options,
+      '#title' => t('View mode'),
+      '#default_value' => $this->options['view_mode'],
+    );
+  }
+
+  /**
+   * Return the main options, which are shown in the summary title.
+   */
+  protected function buildViewModeOptions() {
+    $options = array();
+    if (!empty($this->entityInfo['view modes'])) {
+      foreach ($this->entityInfo['view modes'] as $mode => $settings) {
+        $options[$mode] = $settings['label'];
+      }
+    }
+
+    return $options;
+  }
+
+  /**
+   * Overrides Drupal\views\Plugin\views\PluginBase::summaryTitle().
+   */
+  public function summaryTitle() {
+    $options = $this->buildViewModeOptions();
+    return check_plain($options[$this->options['view_mode']]);
+  }
+
+  /**
+   * Overrides Drupal\views\Plugin\views\row\RowPluginBase::pre_render().
+   */
+  public function pre_render($result) {
+    parent::pre_render($result);
+
+    if ($result) {
+      // Get all entities which will be used to render in rows.
+      $entities = array();
+      foreach ($result as $row) {
+        $entity = $row->_entity;
+        $entity->view = $this->view;
+        $entities[$entity->id()] = $entity;
+      }
+
+      // Prepare the render arrays for all rows.
+      $this->build = entity_view_multiple($entities, $this->options['view_mode']);
+    }
+  }
+
+  /**
+   * Overrides Drupal\views\Plugin\views\row\RowPluginBase::render().
+   */
+  function render($row) {
+    $entity_id = $row->{$this->field_alias};
+    return drupal_render($this->build[$entity_id]);
+  }
+}
diff --git a/lib/Views/user/Plugin/views/row/View.php b/lib/Views/user/Plugin/views/row/View.php
index b7160088ca43..17375b9ab727 100644
--- a/lib/Views/user/Plugin/views/row/View.php
+++ b/lib/Views/user/Plugin/views/row/View.php
@@ -7,12 +7,12 @@
 
 namespace Views\user\Plugin\views\row;
 
-use Drupal\views\Plugin\views\row\RowPluginBase;
+use Views\system\Plugin\views\row\Entity;
 use Drupal\Core\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
 
 /**
- * A row plugin which renders a user via user_view.
+ * A row plugin which renders a user.
  *
  * @ingroup views_row_plugins
  *
@@ -22,76 +22,20 @@
  *   title = @Translation("User"),
  *   help = @Translation("Display the user with standard user view."),
  *   base = {"users"},
+ *   entity_type = "user",
  *   type = "normal"
  * )
  */
-class View extends RowPluginBase {
-
-  var $base_table = 'users';
-  var $base_field = 'uid';
-
-  // Store the users to be used for pre_render.
-  var $users = array();
+class View extends Entity {
 
+  /**
+   * Overrides Views\system\Plugin\views\row\Entity::defineOptions().
+   */
   protected function defineOptions() {
     $options = parent::defineOptions();
-    $options['view_mode'] = array('default' => 'full');
+    $options['view_mode']['default'] = 'full';
 
     return $options;
   }
 
-  public function buildOptionsForm(&$form, &$form_state) {
-    parent::buildOptionsForm($form, $form_state);
-
-    $options = $this->buildOptionsForm_summary_options();
-    $form['view_mode'] = array(
-      '#type' => 'select',
-      '#options' => $options,
-      '#title' => t('View mode'),
-      '#default_value' => $this->options['view_mode'],
-     );
-    $form['help']['#markup'] = t("Display the user with standard user view. It might be necessary to add a user-profile.tpl.php in your themes template folder, because the default <a href=\"@user-profile-api-link\">user-profile</a>e template don't show the username per default.", array('@user-profile-api-link' => url('http://api.drupal.org/api/drupal/modules--user--user-profile.tpl.php/7')));
-  }
-
-    /**
-     * Return the main options, which are shown in the summary title.
-     */
-    public function buildOptionsForm_summary_options() {
-      $entity_info = entity_get_info('user');
-      $options = array();
-      if (!empty($entity_info['view modes'])) {
-        foreach ($entity_info['view modes'] as $mode => $settings) {
-          $options[$mode] = $settings['label'];
-        }
-      }
-      if (empty($options)) {
-        $options = array(
-          'full' => t('User account')
-        );
-      }
-
-      return $options;
-    }
-
-    public function summaryTitle() {
-      $options = $this->buildOptionsForm_summary_options();
-      return check_plain($options[$this->options['view_mode']]);
-    }
-
-  function pre_render($values) {
-    $uids = array();
-    foreach ($values as $row) {
-      $uids[] = $row->{$this->field_alias};
-    }
-    $this->users = user_load_multiple($uids);
-  }
-
-  function render($row) {
-    $account = $this->users[$row->{$this->field_alias}];
-    $account->view = $this->view;
-    $build = user_view($account, $this->options['view_mode']);
-
-    return drupal_render($build);
-  }
-
 }
diff --git a/modules/comment.views.inc b/modules/comment.views.inc
index 5d8976abfb61..79c3bc324790 100644
--- a/modules/comment.views.inc
+++ b/modules/comment.views.inc
@@ -578,29 +578,3 @@ function comment_views_data_alter(&$data) {
   );
 
 }
-
-/**
- * Template helper for theme_views_view_row_comment
- */
-function template_preprocess_views_view_row_comment(&$vars) {
-  $options = $vars['options'];
-  $view = &$vars['view'];
-  $plugin = &$view->style_plugin->row_plugin;
-  $comment = $plugin->comments[$vars['row']->{$vars['field_alias']}];
-  $node = $plugin->nodes[$comment->nid];
-  // Put the view on the node so we can retrieve it in the preprocess.
-  $node->view = &$view;
-
-  $build = comment_view_multiple(array($comment->id() => $comment), $node, $plugin->options['view_mode']);
-  // If we're displaying the comments without links, remove them from the
-  // renderable array. There is no way to avoid building them in the first
-  // place (see comment_build_content()).
-  if (empty($options['links'])) {
-    foreach ($build as $cid => &$comment_build) {
-      if (isset($comment_build['links'])) {
-        unset($comment_build['links']);
-      }
-    }
-  }
-  $vars['comment'] = drupal_render($build);
-}
diff --git a/views.module b/views.module
index 078dff681753..c7945cf1726a 100644
--- a/views.module
+++ b/views.module
@@ -433,11 +433,11 @@ function views_preprocess_node(&$vars) {
  */
 function views_preprocess_comment(&$vars) {
   // The 'view' attribute of the node is added in template_preprocess_views_view_row_comment()
-  if (!empty($vars['node']->view) && !empty($vars['node']->view->storage->name)) {
-    $vars['view'] = &$vars['node']->view;
-    $vars['theme_hook_suggestions'][] = 'comment__view__' . $vars['node']->view->storage->name;
+  if (!empty($vars['comment']->view) && !empty($vars['comment']->view->storage->name)) {
+    $vars['view'] = &$vars['comment']->view;
+    $vars['theme_hook_suggestions'][] = 'comment__view__' . $vars['comment']->view->storage->name;
     if (!empty($vars['node']->view->current_display)) {
-      $vars['theme_hook_suggestions'][] = 'comment__view__' . $vars['node']->view->storage->name . '__' . $vars['node']->view->current_display;
+      $vars['theme_hook_suggestions'][] = 'comment__view__' . $vars['comment']->view->storage->name . '__' . $vars['comment']->view->current_display;
     }
   }
 }
-- 
GitLab