From 9c7e09d6e51ca0de070fbb957d3e2ba2747b423a Mon Sep 17 00:00:00 2001
From: Marco Villegas <marvil07@gmail.com>
Date: Mon, 7 Feb 2011 19:30:22 -0500
Subject: [PATCH] take 3

- Make sure we have the needed fields, aka no more TODOs on row plugin handler.
- Add a views argument handler for repo_id to be able to set the title propertly.
- Rework commitlog_operations_page() to use our custom views_embed_view, versioncontrol_render_commitlog_view.
- Add feeds to commitlog_repository_commits and commitlog_user_commits views.
---
 commitlog/commitlog.module                         |  124 ++++++++++++--------
 .../commitlog_global_commits.view.php              |    1 +
 .../commitlog_repository_commits.view.php          |   48 +++++---
 .../default_views/commitlog_user_commits.view.php  |   44 ++++---
 ...control_handler_argument_repository_repo_id.inc |   22 ++++
 .../versioncontrol_plugin_row_operation_rss.inc    |   18 ++-
 includes/views/versioncontrol.views.inc            |   11 +-
 7 files changed, 171 insertions(+), 97 deletions(-)
 create mode 100644 includes/views/handlers/versioncontrol_handler_argument_repository_repo_id.inc

diff --git commitlog/commitlog.module commitlog/commitlog.module
index c007259..615fef5 100644
--- commitlog/commitlog.module
+++ commitlog/commitlog.module
@@ -30,35 +30,35 @@ function commitlog_menu() {
     'access arguments' => array($view_access),
     'type' => MENU_SUGGESTED_ITEM,
   );
-  $items['commitlog/repository/%'] = array(
+  $items['commitlog/repository/%versioncontrol_repository'] = array(
     'title' => 'Commit messages',
     'page callback' => 'commitlog_operations_page',
     'page arguments' => array('repository', 'page', 2),
     'access arguments' => array($view_access),
     'type' => MENU_SUGGESTED_ITEM,
   );
-  $items['commitlog/repository/%/feed'] = array(
+  $items['commitlog/repository/%versioncontrol_repository/feed'] = array(
     'title' => 'Commit messages',
     'page callback' => 'commitlog_operations_page',
     'page arguments' => array('repository', 'feed', 2),
     'access arguments' => array($view_access),
     'type' => MENU_SUGGESTED_ITEM,
   );
-  $items['commitlog/author/%'] = array(
+  $items['commitlog/author/%user'] = array(
     'title' => 'Commit messages',
     'page callback' => 'commitlog_operations_page',
     'page arguments' => array('author', 'page', 2),
     'access arguments' => array($view_access),
     'type' => MENU_SUGGESTED_ITEM,
   );
-  $items['commitlog/author/%/feed'] = array(
+  $items['commitlog/author/%user/feed'] = array(
     'title' => 'Commit messages',
     'page callback' => 'commitlog_operations_page',
     'page arguments' => array('author', 'feed', 2),
     'access arguments' => array($view_access),
     'type' => MENU_SUGGESTED_ITEM,
   );
-  $items['commitlog/commit/%/%'] = array(
+  $items['commitlog/commit/%versioncontrol_repository/%'] = array(
     'title' => 'Commit',
     'page callback' => 'commitlog_operations_page',
     'page arguments' => array('commit', 'page', 2, 3),
@@ -138,63 +138,87 @@ function commitlog_ctools_plugin_directory($module, $plugin) {
 function commitlog_operations_page($view_type = NULL, $display_type='page', $argument = NULL, $argument2 = NULL) {
   drupal_add_css(drupal_get_path('module', 'commitlog') . '/commitlog.css', 'module');
 
-  $view = '';
-  if ($view_type == 'author' && !is_null($argument)) {
+  $view_name = '';
+  if (($view_type == 'author' || $view_type == 'user') && !is_null($argument)) {
+    $account = $argument;
     $set = versioncontrol_get_views_set('user_commit_view');
-    $view = $set->getViewName();
-  }
-  else if ($view_type == 'user' && !is_null($argument)) {
-    drupal_set_title($argument->name);
-    $argument = $argument->uid;
-    $set = versioncontrol_get_views_set('user_commit_view');
-    $view = $set->getViewName();
+    $view_name = $set->getViewName();
+
+    if ($display_type == 'feed') {
+      $link = ($view_type == 'author') ? "commitlog/author/{$account->uid}" : "user/{$account->uid}/track/code/feed";
+      return versioncontrol_render_commitlog_view($view_name, 'feed', array($account->uid), $link);
+    }
+    return versioncontrol_render_commitlog_view($view_name, 'default', array($account->uid));
   }
-  else if ($view_type == 'repository' && !is_null($argument)) {
+  if ($view_type == 'repository' && !is_null($argument)) {
+    $repository = $argument;
     $set = versioncontrol_get_views_set('repository_commit_view');
-    $view = $set->getViewNameByEntity(versioncontrol_repository_load($argument));
+    $view_name = $set->getViewNameByEntity($repository);
+
+    if ($display_type == 'feed') {
+      return versioncontrol_render_commitlog_view($view_name, 'feed', array($repository->repo_id), "commitlog/repository/{$repository->repo_id}/feed");
+    }
+    return versioncontrol_render_commitlog_view($view_name, 'default', array($repository->repo_id));
   }
-  else if ($view_type == 'commit' && !is_null($argument) && !is_null($argument2)) {
+  if ($view_type == 'commit' && !is_null($argument) && !is_null($argument2)) {
+    $repository = $argument;
+    $revision = $argument2;
     $set = versioncontrol_get_views_set('individual_commit_view');
     $view_name = $set->getViewName();
-    $view = views_get_view($view_name);
-
-    // Basic logic here borrowed from views_embed_view().
-    if (!$view || !$view->access('default')) {
-      return drupal_not_found();
-    }
-    $output = $view->preview('default', array($argument, $argument2));
+    return versioncontrol_render_commitlog_view($view_name, 'default', array($repository->repo_id, $revision));
+  }
+  // global by default
+  $set = versioncontrol_get_views_set('global_commit_view');
+  $view_name = $set->getViewName();
 
-    $title = $view->get_title();
-    if (!empty($title)) {
-      drupal_set_title($title);
-    }
+  if ($display_type == 'feed') {
+    return versioncontrol_render_commitlog_view($view_name, 'feed', array(), 'commitlog/feed');
+  }
+  return versioncontrol_render_commitlog_view($view_name, 'default');
+}
 
-    return $output;
+/**
+ * A convinience function to render a commitlog view.
+ * Basic logic here borrowed from views_embed_view().
+ *
+ * @param $view_name
+ *   Name of the view to render.
+ * @param $display_type
+ *   What type of display output we are creating. Supported types are 'default' and 'feed'.
+ * @param $arguments
+ *   The arguments needed for render the view.
+ * @param $path
+ *   The path to overwrite the view with.
+ * @return
+ *   On $display_type == 'default', the content to show.
+ *   On $display_type == 'feed', NULL, but handle RSS printning by hand.
+ */
+function versioncontrol_render_commitlog_view($view_name, $display_type, $arguments = array(), $path = '') {
+  $view = views_get_view($view_name);
+  if (!$view || !$view->access($display_type)) {
+    return drupal_not_found();
   }
-  else { // global
-    $set = versioncontrol_get_views_set('global_commit_view');
-    $view_name = $set->getViewName();
 
+  if (!empty($path)) {
+    $view->override_path = $path;
     if ($display_type == 'feed') {
-      $view = views_get_view($view_name);
-      $view->override_path = 'commitlog/feed';
-      // Basic logic here borrowed from views_embed_view().
-      if (!$view || !$view->access('feed')) {
-        return drupal_not_found();
-      }
-      $output = $view->preview('feed');
-      $title = $view->get_title();
-      if (!empty($title)) {
-        drupal_set_title($title);
-      }
-      drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
-      print $output;
-      return;
-    }
-    else {
-      $view = $view_name;
+      // Ugh, this line is needed, as override_path seems to not be enough
+      $view->display['feed']->display_options['path'] = $path;
     }
   }
 
-  return views_embed_view($view, 'default', $argument);
+  $output = $view->preview($display_type, $arguments);
+
+  if ($display_type == 'feed') {
+    drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
+    print $output;
+    return;
+  }
+  // default
+  $title = $view->get_title();
+  if (!empty($title)) {
+    drupal_set_title($title);
+  }
+
+  return $output;
 }
diff --git commitlog/includes/views/default_views/commitlog_global_commits.view.php commitlog/includes/views/default_views/commitlog_global_commits.view.php
index c854ca9..cb2cf26 100644
--- commitlog/includes/views/default_views/commitlog_global_commits.view.php
+++ commitlog/includes/views/default_views/commitlog_global_commits.view.php
@@ -306,6 +306,7 @@ $handler->override_option('access', array(
 $handler->override_option('cache', array(
   'type' => 'none',
 ));
+$handler->override_option('title', 'VCS commit messages');
 $handler->override_option('use_pager', '1');
 $handler->override_option('style_plugin', 'list');
 $handler->override_option('style_options', array(
diff --git commitlog/includes/views/default_views/commitlog_repository_commits.view.php commitlog/includes/views/default_views/commitlog_repository_commits.view.php
index 8a8fbae..5d7b498 100644
--- commitlog/includes/views/default_views/commitlog_repository_commits.view.php
+++ commitlog/includes/views/default_views/commitlog_repository_commits.view.php
@@ -307,7 +307,7 @@ $handler->override_option('arguments', array(
     'style_options' => array(),
     'wildcard' => 'all',
     'wildcard_substitution' => 'All',
-    'title' => '',
+    'title' => 'Repository %1',
     'breadcrumb' => '',
     'default_argument_type' => 'fixed',
     'default_argument' => '',
@@ -321,12 +321,6 @@ $handler->override_option('arguments', array(
     'validate_user_argument_type' => 'uid',
     'validate_user_roles' => array(
       '2' => 0,
-      '3' => 0,
-      '4' => 0,
-      '5' => 0,
-      '6' => 0,
-      '7' => 0,
-      '8' => 0,
     ),
     'relationship' => 'none',
     'default_options_div_prefix' => '',
@@ -334,23 +328,13 @@ $handler->override_option('arguments', array(
     'default_argument_user' => 0,
     'default_argument_php' => '',
     'validate_argument_node_type' => array(
-      'forum' => 0,
       'project_project' => 0,
-      'project_release' => 0,
-      'project_issue' => 0,
-      'book' => 0,
       'page' => 0,
       'story' => 0,
     ),
     'validate_argument_node_access' => 0,
     'validate_argument_nid_type' => 'nid',
-    'validate_argument_vocabulary' => array(
-      '1' => 0,
-      '5' => 0,
-      '3' => 0,
-      '2' => 0,
-      '4' => 0,
-    ),
+    'validate_argument_vocabulary' => array(),
     'validate_argument_type' => 'tid',
     'validate_argument_transform' => 0,
     'validate_user_restrict_roles' => 0,
@@ -369,3 +353,31 @@ $handler->override_option('cache', array(
 ));
 $handler->override_option('use_pager', '1');
 $handler->override_option('style_plugin', 'list');
+$handler = $view->new_display('feed', 'Feed', 'feed');
+$handler->override_option('style_plugin', 'rss');
+$handler->override_option('style_options', array(
+  'mission_description' => FALSE,
+  'description' => '',
+));
+$handler->override_option('row_plugin', 'versioncontrol_operations_rss');
+$handler->override_option('row_options', array(
+  'relationship' => 'none',
+  'single_operation_view' => 'commitlog_individual_commit',
+));
+$handler->override_option('path', 'versioncontrol/garbage/path');
+$handler->override_option('menu', array(
+  'type' => 'none',
+  'title' => '',
+  'description' => '',
+  'weight' => 0,
+  'name' => 'navigation',
+));
+$handler->override_option('tab_options', array(
+  'type' => 'none',
+  'title' => '',
+  'description' => '',
+  'weight' => 0,
+  'name' => 'navigation',
+));
+$handler->override_option('displays', array());
+$handler->override_option('sitename_title', 0);
diff --git commitlog/includes/views/default_views/commitlog_user_commits.view.php commitlog/includes/views/default_views/commitlog_user_commits.view.php
index 9db5ae6..62b9eca 100644
--- commitlog/includes/views/default_views/commitlog_user_commits.view.php
+++ commitlog/includes/views/default_views/commitlog_user_commits.view.php
@@ -307,7 +307,7 @@ $handler->override_option('arguments', array(
     'style_options' => array(),
     'wildcard' => 'all',
     'wildcard_substitution' => 'All',
-    'title' => '',
+    'title' => 'Commits by %1',
     'breadcrumb' => '',
     'default_argument_type' => 'fixed',
     'default_argument' => '',
@@ -321,12 +321,6 @@ $handler->override_option('arguments', array(
     'validate_user_argument_type' => 'uid',
     'validate_user_roles' => array(
       '2' => 0,
-      '3' => 0,
-      '4' => 0,
-      '5' => 0,
-      '6' => 0,
-      '7' => 0,
-      '8' => 0,
     ),
     'relationship' => 'none',
     'default_options_div_prefix' => '',
@@ -334,23 +328,13 @@ $handler->override_option('arguments', array(
     'default_argument_user' => 0,
     'default_argument_php' => '',
     'validate_argument_node_type' => array(
-      'forum' => 0,
       'project_project' => 0,
-      'project_release' => 0,
-      'project_issue' => 0,
-      'book' => 0,
       'page' => 0,
       'story' => 0,
     ),
     'validate_argument_node_access' => 0,
     'validate_argument_nid_type' => 'nid',
-    'validate_argument_vocabulary' => array(
-      '1' => 0,
-      '5' => 0,
-      '3' => 0,
-      '2' => 0,
-      '4' => 0,
-    ),
+    'validate_argument_vocabulary' => array(),
     'validate_argument_type' => 'tid',
     'validate_argument_transform' => 0,
     'validate_user_restrict_roles' => 0,
@@ -369,3 +353,27 @@ $handler->override_option('cache', array(
 ));
 $handler->override_option('use_pager', '1');
 $handler->override_option('style_plugin', 'list');
+$handler = $view->new_display('feed', 'Feed', 'feed');
+$handler->override_option('style_plugin', 'rss');
+$handler->override_option('style_options', array(
+  'mission_description' => FALSE,
+  'description' => '',
+));
+$handler->override_option('row_plugin', 'versioncontrol_operations_rss');
+$handler->override_option('path', 'versioncontrol/garbage/path');
+$handler->override_option('menu', array(
+  'type' => 'none',
+  'title' => '',
+  'description' => '',
+  'weight' => 0,
+  'name' => 'navigation',
+));
+$handler->override_option('tab_options', array(
+  'type' => 'none',
+  'title' => '',
+  'description' => '',
+  'weight' => 0,
+  'name' => 'navigation',
+));
+$handler->override_option('displays', array());
+$handler->override_option('sitename_title', FALSE);
diff --git includes/views/handlers/versioncontrol_handler_argument_repository_repo_id.inc includes/views/handlers/versioncontrol_handler_argument_repository_repo_id.inc
new file mode 100644
index 0000000..85db9f6
--- /dev/null
+++ includes/views/handlers/versioncontrol_handler_argument_repository_repo_id.inc
@@ -0,0 +1,22 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Contains the repo_id argument handler.
+ */
+
+/**
+ * Specialized argument handler for repo_id argument.
+ */
+class versioncontrol_handler_argument_repository_repo_id extends views_handler_argument_numeric {
+  function title_query() {
+    $titles = array();
+    $placeholders = implode(', ', array_fill(0, sizeof($this->value), '%d'));
+
+    $result = db_query("SELECT vcr.name FROM {versioncontrol_repositories} vcr WHERE vcr.repo_id IN ($placeholders)", $this->value);
+    while ($repo = db_fetch_object($result)) {
+      $titles[] = check_plain($repo->name);
+    }
+    return $titles;
+  }
+}
diff --git includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc
index 0246be2..65f3322 100644
--- includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc
+++ includes/views/plugins/versioncontrol_plugin_row_operation_rss.inc
@@ -15,6 +15,8 @@ class versioncontrol_plugin_row_operation_rss extends views_plugin_row {
   // Basic properties that let the row style follow relationships.
   public $base_table = 'versioncontrol_operations';
   public $base_field = 'vc_op_id';
+  public $revision_alias = '';
+  public $repo_id_alias = '';
 
   function construct() {
     parent::construct();
@@ -29,6 +31,12 @@ class versioncontrol_plugin_row_operation_rss extends views_plugin_row {
     $this->operations = versioncontrol_operation_load_multiple($vc_op_ids);
   }
 
+  function query() {
+    parent::query();
+    $this->revision_alias = $this->view->query->add_field($this->base_table, 'revision');
+    $this->repo_id_alias = $this->view->query->add_field($this->base_table, 'repo_id');
+  }
+
   function option_definition() {
     $options = parent::option_definition();
 
@@ -64,20 +72,18 @@ class versioncontrol_plugin_row_operation_rss extends views_plugin_row {
     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;
+    $repo_id = $row->{$this->repo_id_alias};
+    $revision = $row->{$this->revision_alias};
     $view_output = $view->preview('default', array($repo_id, $revision));
 
-    //FIXME do not assume fields!
     $item = new stdClass();
     $item->title = $view->get_title();
     $item->link = url(sprintf('commitlog/commit/%s/%s', $repo_id, $revision), array('absolute' => TRUE));
+    $item->description = $view_output;
     $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/'),
       ),
@@ -94,8 +100,6 @@ class versioncontrol_plugin_row_operation_rss extends views_plugin_row {
       }
     }
 
-    $item->description = $view_output;
-
     return theme($this->theme_functions(), $this->view, $this->options, $item, $this->field_alias);
   }
 }
diff --git includes/views/versioncontrol.views.inc includes/views/versioncontrol.views.inc
index 7e0a200..29e337a 100755
--- includes/views/versioncontrol.views.inc
+++ includes/views/versioncontrol.views.inc
@@ -39,7 +39,7 @@ function versioncontrol_views_data() {
       'handler' => 'views_handler_filter_numeric',
     ),
     'argument' => array(
-      'handler' => 'views_handler_argument_numeric',
+      'handler' => 'versioncontrol_handler_argument_repository_repo_id',
     ),
   );
   $data['versioncontrol_repositories']['name'] = array(
@@ -626,6 +626,10 @@ function versioncontrol_views_handlers() {
       'versioncontrol_handler_filter_operation_type_label' => array(
         'parent' => 'views_handler_filter_string',
       ),
+      // argument handlers
+      'versioncontrol_handler_argument_repository_repo_id' => array(
+        'parent' => 'views_handler_argument_numeric',
+      ),
     ),
   );
   return $ret;
@@ -636,10 +640,9 @@ function versioncontrol_views_handlers() {
  */
 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'),
+        'title' => t('Versioncontrol Operations as RSS items'),
         '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
@@ -648,7 +651,7 @@ function versioncontrol_views_plugins() {
         '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,
+        'uses fields' => FALSE,
         'type' => 'feed',
         'help topic' => 'style-node-rss',
       ),
-- 
1.7.2.3

