? ProjectModule.kpf
? xmlrpc.patch
? release/project-updates-info_1.patch
Index: release/project_release.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/project_release.module,v
retrieving revision 1.16
diff -u -p -r1.16 project_release.module
--- release/project_release.module	18 Jan 2007 23:30:45 -0000	1.16
+++ release/project_release.module	28 Jan 2007 06:00:03 -0000
@@ -63,6 +63,111 @@ function project_release_menu($may_cache
 }
 
 /**
+ * Implementation of hook_xmlrpc().
+ */
+function project_release_xmlrpc() {
+  $xmlrpc = array();
+  $xmlrpc[] = array(
+    'project.version.data',
+    'project_release_data',
+    array('string', 'string'),
+    t('Provides versioning data for a single project')
+  );
+  $xmlrpc[] = array(
+    'project.version.data.multi',
+    'project_release_data',
+    array('array', 'string'),
+    t('Provides versioning data for an array of projects')
+  );
+  return $xmlrpc;
+}
+
+/**
+ * Callback for hook_xmlrpc().
+ *
+ * Return versioning data a given project or for all available projects.
+ * The version returned is the highest available for a given major and minor
+ * release. These data can be used e.g. by applications on client sites to
+ * determine whether the client sites have the latest available version.
+ *
+ * This call will only be effective for projects that have official versions.
+ *
+ * @param $project
+ *   The 'short name' (stored as 'url') of a project, or the keyword 'all'
+ *   for all projects. May be an array of projects.
+ * @param $version
+ *   The API version to get data for, as defined by the taxonomy.
+ */
+function project_release_data($project = NULL, $version = NULL) {
+  $data = array();
+
+  // stop processing when $version = $term; that's our tid. If we don't have
+  // a match, this should assume the most current.
+  $tids = project_release_compatibility_list();
+  foreach ($tids as $tid => $term) {
+    if ($version == $term) {
+      break;
+    }
+  }
+
+  $where[] = array();
+  $parameters = array();
+  $join_parameters = array();
+
+  // We load data for all projects if the 'all' keyword is used.
+  // So we need to filter by the project name (url) only if we're not
+  // loading 'all'.
+  $joins[] = "INNER JOIN {project_projects} p ON p.nid = n.pid";
+  $joins[] = "INNER JOIN {node} pn ON pn.nid = p.nid";
+  if (is_array($project)) {
+    $placeholders = array_fill(0, count($project), "'%s'");
+    $where[] = 'p.uri IN (' . implode(',', $placeholders) . ')';
+    // As long as this is the first parameters added, this is fine.
+    // If not make this addition.
+    $parameters = $project;
+  }
+  else if ($project != 'all') {
+    $where .= "AND p.uri = '%s'";
+    $parameters[] = $project;
+  }
+
+  // Restrict to the specified major version.
+  $joins[] = 'INNER JOIN {term_node} tn ON tn.nid = n.pid';
+  $where[] = 'tn.tid = %d';
+  $parameters[] = $tid;
+
+  // Restrict to only current releases
+  $joins[] = 'INNER JOIN {project_release_default_versions} prdv ON prdv.nid = n.pid AND prdv.tid = %d AND prdv.major = n.version_major';
+  $join_parameters[] = $tid;
+
+  // Restrict to only official releases
+  $where[] = 'n.rebuild = 0';
+
+  // Only published release nodes
+  $where[] = 'n.status > 0';
+
+  $where = 'WHERE '. implode(' AND ', $where) : '';
+
+  $query = "SELECT DISTINCT(n.nid), n.filepath, n.version, p.uri, p.homepage, pn.title FROM {node} n ";
+  $query .= implode(' ', $joins);
+  $query .= " WHERE " . implode(' AND ', $where);
+  $query .= " ORDER BY n.version_major DESC, n.version_minor DESC, n.version_patch DESC";
+
+  $result = db_query($query, $join_paramters + $parameters));
+  while ($project = db_fetch_object($result)) {
+    if (!isset($data[$project->uri])) {
+    $data[$project->uri] = array(
+      'name' => check_plain($project->title),
+      'version' => $project->version,
+      'homepage' => url($project->homepage, NULL, NULL, TRUE),
+      'download' => url($project->filepath, NULL, NULL, TRUE),
+    );
+  }
+
+  return $data;
+}
+
+/**
  * Callback for the main settings page.
  * @ingroup project_release_core
  */
@@ -159,7 +264,7 @@ function project_release_settings_form_v
 }
 
 /**
- * @defgroup project_release_node Drupal node-type related hooks 
+ * @defgroup project_release_node Drupal node-type related hooks
  */
 
 /**
@@ -173,7 +278,7 @@ function project_release_access($op, $no
   global $user;
   switch ($op) {
     case 'view':
-      // We want to use the identical logic for viewing projects, 
+      // We want to use the identical logic for viewing projects,
       // so we call that method directly.
       return project_project_access($op, $node);
     case 'create':
@@ -542,9 +647,9 @@ function project_release_update($node) {
 }
 
 /**
- * Helper method to take data out of a $node object and store it into 
+ * Helper method to take data out of a $node object and store it into
  * the DB as necessary. Sadly, db_query() doesn't let us store NULL in
- * the DB, since those get cast to 0. Therefore, we have to do some 
+ * the DB, since those get cast to 0. Therefore, we have to do some
  * manual effort to dynamically create the appropriate SQL depending
  * on which version fields are set in the release node.
  * @see project_release_insert
@@ -556,7 +661,7 @@ function project_release_update($node) {
  * @param $is_new Is this a new release node, or are we updating?
  */
 function project_release_db_save($node, $is_new) {
-  // If the patch field is set to a non-numeric value, we just want to 
+  // If the patch field is set to a non-numeric value, we just want to
   // keep it as a NULL in the DB, instead of casting it to a 0.
   if (isset($node->version_patch) && !is_numeric($node->version_patch)) {
     unset($node->version_patch);
@@ -645,7 +750,7 @@ function project_release_get_version_for
 }
 
 /**
- * Validates a version format string. Only alphanumeric characters and 
+ * Validates a version format string. Only alphanumeric characters and
  * [-_.] are allowed. Calls form_set_error() on error, else returns.
  * @param $form_values Array of form values passed to validate hook.
  * @param $element The name of the form element for the format string.
@@ -686,7 +791,7 @@ function project_release_get_version($re
   $variables["%api"] = '';
   $variables["#api"] = '';
   $vid = _project_release_get_api_vid();
-  if (project_release_get_api_taxonomy()) { 
+  if (project_release_get_api_taxonomy()) {
     if (isset($release->version_api_tid)) {
       $tid = $release->version_api_tid;
     }
@@ -1129,7 +1234,7 @@ function project_release_alter_release_f
       if (!user_access('administer projects')) {
         // The user doesn't have 'administer projects' permission, so
         // we restrict their options for the compatibility taxonomy.
-        if (isset($tid)) { 
+        if (isset($tid)) {
           // If we already have the term, we want to force it to stay.
           $indexes = form_get_options($form['taxonomy'][$vid], $tid);
           if ($indexes !== FALSE) {
@@ -1269,8 +1374,8 @@ function project_release_table($project,
   $tids = project_release_compatibility_list();
   if ($tids) {
     unset($tids[-1]); // get rid of that one.
-    $join = ' INNER JOIN {term_node} tn ON n.nid = tn.nid AND tn.tid in (' 
-      . implode(',', array_keys($tids)) . ') ' 
+    $join = ' INNER JOIN {term_node} tn ON n.nid = tn.nid AND tn.tid in ('
+      . implode(',', array_keys($tids)) . ') '
       . ' INNER JOIN {term_data} td ON td.tid = tn.tid ';
     $selects[] = 'tn.tid';
     $orderby[] = 'td.weight';
@@ -1295,7 +1400,7 @@ function project_release_table($project,
       break;
     case 'all':
         // If we're generating the default releases table, we want the
-        // dev snapshots to be first in the query results, so that we 
+        // dev snapshots to be first in the query results, so that we
         // skip over them and only show official releases (if any).
       $orderby[] = 'r.rebuild' . (($table_type == 'defaults') ? ' DESC' : '');
       break;
@@ -1313,7 +1418,7 @@ function project_release_table($project,
   }
   $result = db_query(db_rewrite_sql(
     "SELECT n.nid, $select r.* FROM {node} n " .
-    "INNER JOIN {project_release_nodes} r ON r.nid = n.nid " . $join . 
+    "INNER JOIN {project_release_nodes} r ON r.nid = n.nid " . $join .
     "WHERE (r.pid = %d) AND (n.status = 1) " . $where . ' ' . $order_by),
     $project->nid);
 
@@ -1345,7 +1450,7 @@ function project_release_table($project,
     if (!is_array($items[$release->tid])) {
       $items[$release->tid] = array();
     }
-    
+
     $row = array(
       // class of <tr>
       'class' => $release->rebuild ? 'release-dev' : 'release',
@@ -1422,7 +1527,7 @@ function project_release_taxonomy($op, $
 }
 
 /**
- * If taxonomy is enabled, returns the taxonomy tree for the 
+ * If taxonomy is enabled, returns the taxonomy tree for the
  * API compatibility vocabulary, otherwise, it returns false.
  */
 function project_release_get_api_taxonomy() {
