From 7ab2a8b6689607bd37d76be619b127d765c07436 Mon Sep 17 00:00:00 2001
From: fago <nuppla@zites.net>
Date: Tue, 1 Mar 2011 18:13:43 +0100
Subject: [PATCH] views row plugin

---
 entity.info                        |    1 +
 views/entity.views.inc             |   27 ++++++++++
 views/handlers/entity.row_view.inc |   98 ++++++++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 views/handlers/entity.row_view.inc

diff --git a/entity.info b/entity.info
index 3fce9ed..eb7f36f 100644
--- a/entity.info
+++ b/entity.info
@@ -1,6 +1,7 @@
 name = Entity API
 description = Enables modules to work with any entity type and to provide entities.
 core = 7.x
+files[] = views/handlers/entity.row_view.inc
 files[] = includes/entity.controller.inc
 files[] = includes/entity.inc
 files[] = includes/entity.ui.inc
diff --git a/views/entity.views.inc b/views/entity.views.inc
index 19b795f..f89cd84 100644
--- a/views/entity.views.inc
+++ b/views/entity.views.inc
@@ -25,6 +25,32 @@ function entity_views_data() {
 }
 
 /**
+ * Implements hook_views_plugins().
+ */
+function entity_views_plugins() {
+  foreach (views_fetch_data() as $table => $data) {
+    if (!empty($data['table']['base']['entity type'])) {
+      $base_tables[] = $table;
+    }
+  }
+  if (!empty($base_tables)) {
+    return array(
+      'row' => array(
+        'entity_row_view' => array(
+          'title' => t('Entity view'),
+          'help' => t('Displays a single entity in a specific view mode (e.g. teaser).'),
+          'handler' => 'EntityViewsRowView',
+          'uses fields' => FALSE,
+          'uses options' => TRUE,
+          'type' => 'normal',
+          'base' => $base_tables,
+        ),
+      ),
+    );
+  }
+}
+
+/**
  * Default controller for generating basic views integration.
  *
  * The controller tries to generate suiting views integration for the entity
@@ -59,6 +85,7 @@ class EntityDefaultViewsController {
         'title' => drupal_ucfirst($this->info['label']),
         // @todo: Support an entity info description key or such?
         'help' => '',
+        'entity type' => $this->type,
       );
       $data[$table] += $this->schema_fields();
     }
diff --git a/views/handlers/entity.row_view.inc b/views/handlers/entity.row_view.inc
new file mode 100644
index 0000000..971462d
--- /dev/null
+++ b/views/handlers/entity.row_view.inc
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Row style plugin for displaying the results as entities.
+ */
+
+/**
+ * Plugin class for displaying Views results with entity_view.
+ */
+class EntityViewsRowView extends views_plugin_row {
+
+  /**
+   * The entity type of the entity being displayed.
+   */
+  protected $entity_type, $skip_load, $entities = array();
+
+  public function init(&$view, &$display, $options = NULL) {
+    parent::init($view, $display, $options);
+
+    $table_data = views_fetch_data($this->view->base_table);
+    $this->entity_type = $table_data['table']['base']['entity type'];
+    $this->skip_load = !empty($table_data['table']['base']['skip entity load']);
+
+    // Set base table and field information as used by views_plugin_row to
+    // select the entity id if used with default query class.
+    $info = entity_get_info($this->entity_type);
+    if (!empty($info['base table']) && $info['base table'] == $this->view->base_table) {
+      $this->base_table = $info['base table'];
+      $this->base_field = $info['entity keys']['id'];
+    }
+  }
+
+  public function option_definition() {
+    $options = parent::option_definition();
+    $options['view_mode'] = array('default' => 'full');
+    return $options;
+  }
+
+  public function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $entity_info = entity_get_info($this->entity_type);
+    $options = array();
+    if (!empty($entity_info['view modes'])) {
+      foreach ($entity_info['view modes'] as $mode => $settings) {
+        $options[$mode] = $settings['label'];
+      }
+    }
+
+    if (count($options) > 1) {
+      $form['view_mode'] = array(
+        '#type' => 'select',
+        '#options' => $options,
+        '#title' => t('View mode'),
+        '#default_value' => $this->options['view_mode'],
+      );
+    }
+    else {
+      $form['view_mode'] = array(
+        '#type' => 'value',
+        '#value' => $options ? key($options) : 'full',
+      );
+    }
+  }
+
+  /**
+   * Use entity_load() to load all entities at once if they aren't loaded yet.
+   */
+  public function pre_render($results) {
+    $this->entities = array();
+    foreach ($results as $result) {
+      if (is_object($result)) {
+        $this->entities[entity_id($this->entity_type, $result)] = $result;
+      }
+      elseif (is_array($result) && isset($result['entity'])) {
+        $id = is_object($result['entity']) ? entity_id($this->entity_type, $result['entity']) : $result['entity'];
+        $this->entities[$id] = $result['entity'];
+      }
+    }
+    if (!$this->skip_load) {
+      $this->entities = entity_load($this->entity_type, array_keys($this->entities));
+    }
+  }
+
+  public function render($result) {
+    if (is_object($result)) {
+      $id = entity_id($this->entity_type, $result);
+    }
+    elseif (is_array($result) && isset($result['entity'])) {
+      $id = is_object($result['entity']) ? entity_id($this->entity_type, $result['entity']) : $result['entity'];
+    }
+    if (isset($id)) {
+      $content = entity_view($this->entity_type, array($id => $this->entities[$id]), $this->options['view_mode']);
+      return drupal_render($content);
+    }
+  }
+}
-- 
1.7.1

