Index: project.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/project.module,v
retrieving revision 1.264
diff -u -p -r1.264 project.module
--- project.module	30 Jan 2007 08:35:26 -0000	1.264
+++ project.module	5 Feb 2007 04:02:10 -0000
@@ -648,7 +648,7 @@ function project_page_overview($termname
     $project->links = array();
     if ($version != -1) {
       if ($project->file_path) {
-        $project->links['project_download'] = project_release_download_link($project->file_path, t('Download'), TRUE);
+        $project->links['project_download'] = project_release_download_link($project->file_path, t('Download'), 'array');
       }
     }
     else {
Index: release/project_release.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/project_release.module,v
retrieving revision 1.17
diff -u -p -r1.17 project_release.module
--- release/project_release.module	29 Jan 2007 20:30:45 -0000	1.17
+++ release/project_release.module	5 Feb 2007 04:02:11 -0000
@@ -63,6 +63,142 @@ function project_release_menu($may_cache
 }
 
 /**
+ * Implementation of hook_xmlrpc().
+ */
+function project_release_xmlrpc() {
+  $xmlrpc = array();
+  $xmlrpc[] = array(
+    'project.release.data',
+    'project_release_data',
+    t('Provides versioning data for a project or 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 $api_version
+ *   The API version to get data for, as defined by the taxonomy. In Drupal
+ *   this will be 5.x, 4.7.x, 4.6.x, etc.
+ * @param $major_version
+ *   Optionally, the major version to check for. If unspecified it will use
+ *   the default major version as specified by the
+ *   {project_release_default_version} table. This should usually be blank.
+ */
+function project_release_data($project = NULL, $api_version = NULL, $major_version = NULL) {
+  $data = array();
+
+  // Handle caching for 'all' projects
+  if (!is_array($project) && $project == 'all') {
+    $cid = 'project_release_data_all:'. $api_version;
+    if ($major_version) {
+      $cid .= ':'. $major_version;
+    }
+    if ($cached = cache_get($cid, 'cache')) {
+      return $cached->data;
+    }
+  }
+
+  // Find the $tid for the API version specified.
+  // Stop processing when $api_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 ($api_version == $term) {
+      break;
+    }
+  }
+
+  $where = array();
+  $parameters = array();
+  $join_parameters = array();
+
+  // Join the release node, project and project node table.
+  $joins[] = "INNER JOIN {project_release_nodes} prn ON n.nid = prn.nid";
+  $joins[] = "INNER JOIN {project_projects} p ON p.nid = prn.pid";
+  $joins[] = "INNER JOIN {node} pn ON pn.nid = p.nid";
+
+  // If more than one project, add them all in.
+  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;
+  }
+  // Or if not 'all' add just the one.
+  else if ($project != 'all') {
+    $where[] = "p.uri = '%s'";
+    $parameters[] = $project;
+  }
+
+  // Restrict releases to the specified API version.
+  $joins[] = 'INNER JOIN {term_node} tn ON tn.nid = prn.nid';
+  $where[] = 'tn.tid = %d';
+  $parameters[] = $tid;
+
+  if (is_numeric($major_version) && $major_version > 0) {
+    $where[] = 'prn.version_major = %d';
+    $parameters[] = $major_version;
+  }
+  else {
+    // Restrict to only current releases
+    $joins[] = 'INNER JOIN {project_release_default_versions} prdv ON prdv.nid = prn.pid AND prdv.tid = %d AND prdv.major = prn.version_major';
+    $join_parameters[] = $tid;
+  }
+
+  // Restrict to only official releases
+  $where[] = 'prn.rebuild = 0';
+
+  // Only published release nodes
+  $where[] = 'n.status > 0';
+
+  $query = "SELECT DISTINCT(n.nid), prn.file_path, prn.file_date, prn.file_hash, prn.version, prn.pid, prn.version_major, prn.version_minor, prn.version_patch, prn.version_extra, p.uri, pn.title FROM {node} n ";
+  $query .= implode(' ', $joins);
+  $query .= " WHERE " . implode(' AND ', $where);
+  $query .= " ORDER BY prn.version_major DESC, prn.version_minor DESC, prn.version_patch DESC, prn.file_date DESC";
+
+  $result = db_query($query, array_merge($join_parameters, $parameters));
+  while ($release = db_fetch_object($result)) {
+    if (!isset($data[$release->uri])) {
+      $data[$release->uri] = array(
+        'name' => check_plain($release->title),
+        'version' => $release->version,
+        'version_major' => $release->version_major,
+        'version_minor' => $release->version_minor,
+        'version_patch' => $release->version_patch,
+        'version_extra' => $release->version_extra,
+        'link' => url("node/$release->pid", NULL, NULL, TRUE),
+        'download' => project_release_download_link($release->file_path, NULL, 'url'),
+        'date' => $release->file_date,
+        'md5hash' => $release->file_hash,
+      );
+    }
+  }
+
+  // Compress the data to reduce bandwidth usage. Base64 because binary data
+  // does not seem to survive the XMLRPC transfer.
+  $data = serialize(base64_encode(gzencode(serialize($data), 9, FORCE_GZIP))
+  // If we performed the query for 'all', cache the results for 1 hour.
+  if (!is_array($project) && $project == 'all') {
+    cache_set($cid, 'cache', $data, time() + (60 * 60));
+  }
+  return $data;
+}
+
+/**
  * Callback for the main settings page.
  * @ingroup project_release_core
  */
