From 1ab71088d26bac013d00fda6db26b194e73d029e Mon Sep 17 00:00:00 2001
From: Marco Villegas <marvil07@gmail.com>
Date: Thu, 27 Jan 2011 23:26:07 -0500
Subject: [PATCH] feature #1039042: Add a views field handler that retrieves all operation label names.

This commit also modify commitlog_global_commits default view to use it
instead of the current versioncontrol label name views fields, that
naturally end up in one row per vc_op_id per label.
---
 .../commitlog_global_commits.view.php              |   10 ++--
 ...rsioncontrol_handler_field_operation_labels.inc |   66 ++++++++++++++++++++
 includes/views/versioncontrol.views.inc            |   26 ++++++++
 3 files changed, 97 insertions(+), 5 deletions(-)
 create mode 100644 includes/views/handlers/versioncontrol_handler_field_operation_labels.inc

diff --git commitlog/includes/views/default_views/commitlog_global_commits.view.php commitlog/includes/views/default_views/commitlog_global_commits.view.php
index e3102e4..34c7846 100644
--- commitlog/includes/views/default_views/commitlog_global_commits.view.php
+++ commitlog/includes/views/default_views/commitlog_global_commits.view.php
@@ -108,7 +108,7 @@ $handler->override_option('fields', array(
     'field' => 'date',
     'relationship' => 'none',
   ),
-  'name' => array(
+  'labels' => array(
     'label' => '',
     'alter' => array(
       'alter_text' => 0,
@@ -132,9 +132,9 @@ $handler->override_option('fields', array(
     'hide_empty' => 0,
     'empty_zero' => 0,
     'exclude' => 1,
-    'id' => 'name',
-    'table' => 'versioncontrol_labels',
-    'field' => 'name',
+    'id' => 'labels',
+    'table' => 'versioncontrol_operations',
+    'field' => 'labels',
     'relationship' => 'none',
   ),
   'revision' => array(
@@ -171,7 +171,7 @@ $handler->override_option('fields', array(
     'alter' => array(
       'text' => '<div class="commit-global">
   <h3>[date]</h3>
-  <div class="commit-info">Commit <strong>[revision]</strong> on <strong>[name]</strong></div>
+  <div class="commit-info">Commit <strong>[revision]</strong> on <strong>[labels]</strong></div>
   <div class="attribtution">[attribution]</div>
 </div>',
       'make_link' => 0,
diff --git includes/views/handlers/versioncontrol_handler_field_operation_labels.inc includes/views/handlers/versioncontrol_handler_field_operation_labels.inc
new file mode 100644
index 0000000..6b47522
--- /dev/null
+++ includes/views/handlers/versioncontrol_handler_field_operation_labels.inc
@@ -0,0 +1,66 @@
+<?php
+// $Id$
+
+/**
+ * Views Field handler to show the list of label names this operation is in.
+ */
+class versioncontrol_handler_field_operation_labels extends views_handler_field {
+  public $backends = array();
+  public $repos = array();
+
+  /**
+   * An array to store operation objects we want its labels to show.
+   */
+  public $operations = array();
+
+  function construct() {
+    parent::construct();
+    $this->backends = versioncontrol_get_backends();
+  }
+
+  /**
+   * Get a repository of the @param $vcs type.
+   */
+  function getRepository($vcs, $repo_id) {
+    if (!isset($this->repos[$repo_id])) {
+      $this->repos[$repo_id] = $this->backends[$vcs]->loadEntity('repo', array($repo_id));
+    }
+    return $this->repos[$repo_id];
+  }
+
+  function pre_render($values) {
+    parent::pre_render($values);
+
+    // Get all vc_op_ids.
+    $vc_op_ids = array();
+    $repo_ids  = array();
+    foreach ($values as $result) {
+      $vc_op_ids[$result->{$this->aliases['repo_id']}][$result->{$this->field_alias}] = TRUE;
+      $repo_data[$result->{$this->aliases['repo_id']}] = $result->{$this->aliases['vcs']};
+    }
+    $repo_ids = array_keys($repo_data);
+
+    foreach ($repo_ids as $repo_id) {
+      $vcs = $repo_data[$repo_id];
+      $repository = $this->getRepository($vcs, $repo_id);
+      $commit_ids = array_keys($vc_op_ids[$repo_id]);
+      if (!empty($commit_ids)) {
+        $commits = $repository->loadCommits($commit_ids);
+      }
+      $this->operations += $commits;
+    }
+  }
+
+  function render($values) {
+    if (!isset($this->operations[$values->{$this->field_alias}])) {
+      return '';
+    }
+    $operation = $this->operations[$values->{$this->field_alias}];
+    $label_names = array();
+    foreach ($operation->labels as $label) {
+      $label_names[] = $label->name;
+    }
+    return implode(', ', $label_names);
+  }
+
+}
diff --git includes/views/versioncontrol.views.inc includes/views/versioncontrol.views.inc
index 04e2379..46255cb 100755
--- includes/views/versioncontrol.views.inc
+++ includes/views/versioncontrol.views.inc
@@ -313,6 +313,29 @@ function versioncontrol_views_data() {
       'handler' => 'versioncontrol_handler_field_operation_message',
     ),
   );
+
+  $data['versioncontrol_operations']['labels'] = array(
+    'real field' => 'vc_op_id',
+    'title'    => t('List of label this operation is in'),
+    'help'     => t('This operation labels as a list on label names.'),
+    'field'    => array(
+      'handler' => 'versioncontrol_handler_field_operation_labels',
+      'additional fields' => array(
+        'vcs' => array('table' => 'versioncontrol_repositories', 'field' => 'vcs'),
+        'repo_id',
+      ),
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
   $data['versioncontrol_operations']['table']['join'] = array(
     'users' => array(
       'left_field' => 'uid',
@@ -590,6 +613,9 @@ function versioncontrol_views_handlers() {
       'versioncontrol_handler_field_operation_date' => array(
         'parent' => 'views_handler_field_date',
       ),
+      'versioncontrol_handler_field_operation_labels' => array(
+        'parent' => 'views_handler_field',
+      ),
       // filter handlers
       'versioncontrol_handler_filter_operation_type' => array(
         'parent' => 'views_handler_filter_in_operator',
-- 
1.7.2.3

