From 68c69144cd77adeb75000ea34e806c9d1e09d298 Mon Sep 17 00:00:00 2001
From: Marco Villegas <marvil07@gmail.com>
Date: Tue, 8 May 2012 22:03:01 -0500
Subject: [PATCH] Issue #443000 by marvil07: Add another module for storing
 the relation between versioncontrol operations and project
 issues.

---
 .../versioncontrol_project_issue.info              |    7 ++
 .../versioncontrol_project_issue.install           |   48 ++++++++++++
 .../versioncontrol_project_issue.module            |   78 ++++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 versioncontrol_project_issue/versioncontrol_project_issue.info
 create mode 100644 versioncontrol_project_issue/versioncontrol_project_issue.install
 create mode 100644 versioncontrol_project_issue/versioncontrol_project_issue.module

diff --git a/versioncontrol_project_issue/versioncontrol_project_issue.info b/versioncontrol_project_issue/versioncontrol_project_issue.info
new file mode 100644
index 0000000..291b6ae
--- /dev/null
+++ b/versioncontrol_project_issue/versioncontrol_project_issue.info
@@ -0,0 +1,7 @@
+name = "Version Control / Project issue integration"
+description = "Expose some functionality that integrates project_issue and Version Control API."
+package = Version Control
+dependencies[] = versioncontrol_project
+dependencies[] = project_issue
+dependencies[] = dbtng
+core = 6.x
diff --git a/versioncontrol_project_issue/versioncontrol_project_issue.install b/versioncontrol_project_issue/versioncontrol_project_issue.install
new file mode 100644
index 0000000..b3baf20
--- /dev/null
+++ b/versioncontrol_project_issue/versioncontrol_project_issue.install
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @file
+ * Version Control / Project issue integration
+ */
+
+/**
+ * Implementation of hook_schema().
+ */
+function versioncontrol_project_issue_schema() {
+  $schema['versioncontrol_project_issue_operations'] = array(
+    'description' => 'This table associates project issue nodes with versioncontrol operations.',
+    'fields' => array(
+      'nid' => array(
+        'description' => 'Foreign key for the project issue({project_issues}.nid).',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'vc_op_id' => array(
+        'description' => 'Foreign key for the operation({versioncontrol_operations}.vc_op_id).',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('nid', 'vc_op_id'),
+  );
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function versioncontrol_project_issue_install() {
+  // Create tables.
+  drupal_install_schema('versioncontrol_project_issue');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function versioncontrol_project_issue_uninstall() {
+  // Remove tables.
+  drupal_uninstall_schema('versioncontrol_project_issue');
+}
diff --git a/versioncontrol_project_issue/versioncontrol_project_issue.module b/versioncontrol_project_issue/versioncontrol_project_issue.module
new file mode 100644
index 0000000..9cb1de7
--- /dev/null
+++ b/versioncontrol_project_issue/versioncontrol_project_issue.module
@@ -0,0 +1,78 @@
+<?php
+/**
+ * @file
+ * Version Control / Project issue integration
+ *
+ * @todo Change the mappings when a project issue is changed of project.
+ */
+
+/**
+ * Implementation of hook_versioncontrol_entity_commit_insert().
+ *
+ * Add relations on operation insert.
+ */
+function versioncontrol_project_issue_versioncontrol_entity_commit_insert(VersioncontrolOperation $operation) {
+  $operation_repository = $operation->getRepository();
+  if (!isset($operation_repository->project_nid)) {
+    // Nothing to do.
+    return;
+  }
+  $nids_on_message = versioncontrol_project_issue_get_issues_from_operation_message($operation->message);
+  if (count($nids_on_message) < 1) {
+    // Nothing to do.
+    return;
+  }
+  // Now see if they are really project issues.
+  $placeholders = implode(',', array_fill(0, count($nids_on_message), "%d"));
+  $result = db_query("SELECT nid FROM {project_issues} WHERE pid = %d AND nid IN ($placeholders)", $operation_repository->project_nid, $nids_on_message);
+  $operation_nid_maps = array();
+  while ($row = db_fetch_object($result)) {
+    $operation_nid_maps[] = array(
+      'nid' => $row->nid,
+      'vc_op_id' => $operation->vc_op_id
+    );
+  }
+  if (empty($operation_nid_maps)) {
+    // Nothing to do.
+    return;
+  }
+  // Insert mappings.
+  $insert_query = db_insert('versioncontrol_project_issue_operations')->fields(array('nid', 'vc_op_id'));
+  foreach ($operation_nid_maps as $operation_nid_map) {
+    $insert_query->values($operation_nid_map);
+  }
+  $insert_query->execute();
+}
+
+/**
+ * Implementation of hook_nodeapi().
+ */
+function versioncontrol_project_issue_nodeapi(&$node, $op, $arg) {
+  if ($node->type != 'project_issue') {
+    // Nothing to do.
+    return;
+  }
+  // Remove mappings on delete.
+  if ($op == 'delete') {
+    db_query('DELETE FROM {versioncontrol_project_issue_operations} WHERE nid = %d', $node->nid);
+  }
+}
+
+/**
+ * Implementation of hook_versioncontrol_entity_commit_delete().
+ */
+function versioncontrol_project_issue_versioncontrol_entity_commit_delete(VersioncontrolOperation $operation) {
+  db_query('DELETE FROM {versioncontrol_project_issue_operations} WHERE vc_op_id = %d', $operation->vc_op_id);
+}
+
+/**
+ * Retrieve the issues from operation message.
+ *
+ * @todo convert to a ctools plugin for different rules?
+ */
+function versioncontrol_project_issue_get_issues_from_operation_message($message) {
+  if (preg_match_all('/#(\d+)\b/', $message, $matches)) {
+    return $matches[1];
+  }
+  return array();
+}
-- 
1.7.10

