From 9b8cca8a8c7e33391db596f1aec754c7deb4a077 Mon Sep 17 00:00:00 2001
From: Marco Villegas <marvil07@gmail.com>
Date: Sun, 30 Jan 2011 18:02:10 -0500
Subject: [PATCH] Starting views row plugin for operations feed.

---
 includes/versioncontrol_theme.inc                  |    5 +
 .../versioncontrol_plugin_row_operation_rss.inc    |  107 ++++++++++++++++++++
 includes/views/versioncontrol.views.inc            |   25 +++++
 versioncontrol.module                              |   49 +++++++++
 4 files changed, 186 insertions(+), 0 deletions(-)
 create mode 100644 includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc

diff --git includes/versioncontrol_theme.inc includes/versioncontrol_theme.inc
index f139b2e..6614781 100644
--- includes/versioncontrol_theme.inc
+++ includes/versioncontrol_theme.inc
@@ -38,3 +38,8 @@ function theme_versioncontrol_diffstat_removal() {
 function theme_versioncontrol_diffstat_no_op() {
   return '<span class="no-op"> </span>';
 }
+
+function theme_versioncontrol_view_row_operation_rss($view, $options, $item) {
+  //FIXME actuallly theme the item
+  return '<pre>' . print_r($item, 1) . '</pre>';
+}
diff --git includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc
new file mode 100644
index 0000000..b78a18d
--- /dev/null
+++ includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc
@@ -0,0 +1,107 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Contains the versioncontrol operation RSS row style plugin.
+ */
+
+/**
+ * FIXME Plugin which performs a node_view on the resulting object
+ * and formats it as an RSS item.
+ */
+class versioncontrol_plugin_row_operation_rss extends views_plugin_row {
+  public $backends = NULL;
+  public $operations = array();
+  // Basic properties that let the row style follow relationships.
+  public $base_table = 'versioncontrol_operations';
+  public $base_field = 'vc_op_id';
+
+  function construct() {
+    parent::construct();
+    $this->backends = versioncontrol_get_backends();
+  }
+
+  function pre_render($results) {
+    $vc_op_ids = array();
+    foreach ($results as $result) {
+      $vc_op_ids[] = $result->{$this->base_field};
+    }
+    $this->operations = versioncontrol_operation_load_multiple($vc_op_ids);
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $set = versioncontrol_get_views_set('individual_commit_view');
+    $view_name = $set->getViewName();
+
+    $options['single_operation_view'] = array('default' => $view_name ? $view_name : '');
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $all_views = drupal_map_assoc(array_keys(views_get_all_views()));
+
+    $form['single_operation_view'] = array(
+      '#type' => 'select',
+      '#title' => t('Display type'),
+      '#description' => t('The view that is going to be used on the description for of the RSS item.'),
+      '#options' => $all_views,
+      '#default_value' => $this->options['single_operation_view'],
+    );
+  }
+
+  function render($row) {
+    global $base_url;
+    $vc_op_id = $row->{$this->field_alias};
+    $operation = $this->operations[$vc_op_id];
+    $description_view = $this->options['single_operation_view'];
+
+    $view = views_get_view($description_view);
+    // Basic logic here borrowed from views_embed_view().
+    if (!$view || !$view->access('default')) {
+      return '';
+    }
+    //FIXME make sure we have these field are available!
+    $repo_id = $row->versioncontrol_repositories_repo_id;
+    $revision = $row->versioncontrol_operations_revision;
+    //FIXME I do not know why the next line is failing.
+    $view_output = $view->preview('default', array((string)$repo_id, (string)$vc_op_id));
+
+    //FIXME do not assume fields!
+    $item = new stdClass();
+    $item->title = $view->get_title();
+    $item->link = url(sprintf('commitlog/commit/%s/%s', $repo_id, $revision));
+    //TODO $item->readmore = $node->readmore; <- not necessary?
+    $item->elements = array(
+      array('key' => 'pubDate', 'value' => gmdate('r', $operation->date)),
+      array(
+        'key' => 'dc:creator',
+        //FIXME format correctly
+        'value' => $operation->author,
+        'namespace' => array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'),
+      ),
+      array(
+        'key' => 'guid',
+        'value' => 'VCOPID at link_to_indiv_commit_view',
+        'attributes' => array('isPermaLink' => 'false')
+      ),
+    );
+
+    foreach ($item->elements as $element) {
+      if (isset($element['namespace'])) {
+        $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $element['namespace']);
+      }
+    }
+
+    $item->description = $view_output;
+
+    //FIXME just return the them output
+    $output = theme($this->theme_functions(), $this->view, $this->options, $item);
+    $output = '<pre>' . $output . '</pre>';
+    return $output;
+  }
+}
+
diff --git includes/views/versioncontrol.views.inc includes/views/versioncontrol.views.inc
index 8037669..7e0a200 100755
--- includes/views/versioncontrol.views.inc
+++ includes/views/versioncontrol.views.inc
@@ -630,3 +630,28 @@ function versioncontrol_views_handlers() {
   );
   return $ret;
 }
+
+/**
+ * Implementation of hook_views_plugins.
+ */
+function versioncontrol_views_plugins() {
+  return array(
+    //'module' => 'views', // This just tells our themes are elsewhere.
+    'row' => array(
+      'versioncontrol_operations_rss' => array(
+        'title' => t('Versioncontrol Operations'),
+        'help' => t('Display versioncontrol operations for RSS feeds.'),
+        'handler' => 'versioncontrol_plugin_row_operation_rss',
+        'path' => drupal_get_path('module', 'versioncontrol') . '/includes/views/plugins', // not necessary for most modules
+        'theme' => 'versioncontrol_view_row_operation_rss',
+        'theme file' => 'versioncontrol_theme.inc',
+        'theme path' => drupal_get_path('module', 'versioncontrol') . '/includes',
+        'base' => array('versioncontrol_operations'), // only works with 'versioncontrol_operations' as base.
+        'uses options' => TRUE,
+        'uses fields' => TRUE,
+        'type' => 'feed',
+        'help topic' => 'style-node-rss',
+      ),
+    ),
+  );
+}
diff --git versioncontrol.module versioncontrol.module
index 9d249b2..aa6bd7d 100644
--- versioncontrol.module
+++ versioncontrol.module
@@ -150,6 +150,10 @@ function versioncontrol_theme() {
     'arguments' => array(),
     'file' => 'includes/versioncontrol_theme.inc'
   );
+  $theme['versioncontrol_view_row_operation_rss'] = array(
+    'arguments' => array('view', 'options', 'item'),
+    'file' => 'includes/versioncontrol_theme.inc'
+  );
   return $theme;
 }
 
@@ -350,6 +354,51 @@ function versioncontrol_repository_load_multiple($ids = array(), $conditions = a
 }
 
 /**
+ * Load multiple versioncontrol operations, given provided conditions and
+ * options.
+ *
+ * @param $ids
+ * @param $conditions
+ * @param $options
+ * @return array
+ */
+function versioncontrol_operation_load_multiple($ids = array(), $conditions = array(), $options = array()) {
+  $backends = versioncontrol_get_backends();
+
+  // FIXME Stop working fine only if we pass $ids
+  //       Main problem here is figured out which controller to use to
+  //       avoid having a bad type for each operation object returned.
+  if (!empty($ids)) {
+    // Try to know which controller we need to use based on the vcs
+    $query = db_select('versioncontrol_operations', 'vco');
+    $query->join('versioncontrol_repositories', 'vcr', 'vco.repo_id = vcr.repo_id');
+    $init_result = $query->fields('vco', array('vc_op_id'))
+      ->fields('vcr', array('vcs'))
+      ->condition('vco.vc_op_id', $ids, 'IN')
+      ->execute();
+    $vc_op_ids_by_vcs = array();
+    foreach ($init_result as $record) {
+      $vc_op_ids_by_vcs[$record->vcs][] = $record->vc_op_id;
+    }
+
+    $results = array();
+    foreach ($vc_op_ids_by_vcs as $vcs => $vc_op_ids) {
+      $vcs_results = $backends[$vcs]->loadEntities('operation', $vc_op_ids, $conditions, $options);
+      $results += $vcs_results;
+    }
+    return $results;
+  }
+
+  $results = array();
+  foreach ($backends as $vcs => $backend) {
+    $vcs_results = $backend->loadEntities('operation', $ids, $conditions, $options);
+    $results += $vcs_results;
+  }
+
+  return $results;
+}
+
+/**
  * Get a list of all backends with its detailed information.
  *
  * @param string $backend
-- 
1.7.2.3

