Index: release/project-release-create-history.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/project-release-create-history.php,v
retrieving revision 1.10
diff -u -p -r1.10 project-release-create-history.php
--- release/project-release-create-history.php	19 Sep 2007 17:46:10 -0000	1.10
+++ release/project-release-create-history.php	20 Feb 2008 20:47:31 -0000
@@ -80,7 +80,7 @@ if (!is_dir(BASE_DIRECTORY)) {
 
 /// @todo Add command-line args to only generate a given project/version.
 project_release_history_generate_all();
-
+project_list_generate();
 
 // ------------------------------------------------------------
 // Functions: main work
@@ -144,7 +144,7 @@ function project_release_history_generat
     $api_version = $api_terms[$api_tid];
 
     // Get project-wide data:
-    $sql = "SELECT n.title, n.nid, p.uri, prdv.major FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.nid LEFT JOIN {project_release_default_versions} prdv ON prdv.nid = n.nid AND prdv.tid = %d WHERE p.nid = %d";
+    $sql = "SELECT n.title, n.nid, p.uri, prdv.major, u.name FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.nid LEFT JOIN {project_release_default_versions} prdv ON prdv.nid = n.nid AND prdv.tid = %d INNER JOIN {users} u ON n.uid = u.uid WHERE p.nid = %d";
     $query = db_query($sql, $api_tid, $project_nid);
     if (!db_num_rows($query)) {
       wd_err(t('Project ID %pid not found', array('%pid' => $project_nid)));
@@ -159,7 +159,7 @@ function project_release_history_generat
   else {
     // Consider all API compatibility terms.
     $api_version = 'all';
-    $sql = "SELECT n.title, n.nid, p.uri, prdv.major FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.nid LEFT JOIN {project_release_default_versions} prdv ON prdv.nid = n.nid WHERE p.nid = %d";
+    $sql = "SELECT n.title, n.nid, p.uri, prdv.major, u.name FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.nid LEFT JOIN {project_release_default_versions} prdv ON prdv.nid = n.nid INNER JOIN {users} u ON n.uid = u.uid WHERE p.nid = %d";
     $query = db_query($sql, $project_nid);
     if (!db_num_rows($query)) {
       wd_err(t('Project ID %pid not found', array('%pid' => $project_nid)));
@@ -176,6 +176,12 @@ function project_release_history_generat
   $xml .= '<title>'. check_plain($project->title) ."</title>\n";
   $xml .= '<short_name>'. check_plain($project->uri) ."</short_name>\n";
   $xml .= '<link>'. url("node/$project->nid", NULL, NULL, TRUE) ."</link>\n";
+  $xml .= '<dc:creator>'. check_plain($project->name) ."</dc:creator>\n";
+  $terms =  taxonomy_node_get_terms_by_vocabulary($project->nid, _project_get_vid());
+  foreach ($terms as $term) {
+    $taxonomy_url = url("taxonomy/term/$term->tid", NULL, NULL, TRUE);
+    $xml .= '<category domain="'. $taxonomy_url .'">'. check_plain($term->name) ."</category>\n";
+  }
   $xml .= '<api_version>'. check_plain($api_version) ."</api_version>\n";
   $xml .= "<default_major>$project->major</default_major>\n";
   $xml .= "<releases>\n";
@@ -275,43 +281,61 @@ function project_release_history_generat
     $xml .= " </release>\n";
   }
   $xml .= "</releases>\n</project>\n";
-  project_release_history_write_xml($project, $api_version, $xml);
+  project_release_history_write_xml($xml, $project, $api_version);
 }
 
 
 /**
  * Write out the XML history for a given project and version to a file.
  *
+ * @param $xml
+ *   String containing the XML representation of the history.
  * @param $project
- *  An object containing (at least) the title and uri of project.
+ *   An object containing (at least) the title and uri of project.
  * @param $api_version
- *  The API compatibility version the history is for.
- * @param $xml
- *  String containing the XML representation of the history.
+ *   The API compatibility version the history is for.
  */
-function project_release_history_write_xml($project, $api_version, $xml) {
+function project_release_history_write_xml($xml, $project = NULL, $api_version = NULL) {
 
-  // Setup the filenames we'll be using.  Normally, we'd have to be
-  // extra careful with $project->uri to avoid malice here, however,
-  // that's validated on the project edit form to prevent any funny
-  // characters, so that much is safe.  The rest of these paths are
-  // just from the global variables at the top of this script, so we
-  // can trust those.  The only one we should be careful of is the
-  // taxonomy term for the API compatibility.
-  $safe_api_vers = strtr($api_version, '/', '_');
-  $project_dir = BASE_DIRECTORY .'/'. $project->uri;
-  $project_id = $project->uri .'-'. $safe_api_vers .'.xml';
-  $filename = $project_dir .'/'. $project_id;
-  $tmp_filename = $filename .'.new';
+  if (!isset($project)) {
+    // We are outputting a global project list.
+    $project_dir = BASE_DIRECTORY .'/project-list';
+    $filename = $project_dir .'/project-list-all.xml';
+    $tmp_filename = $filename .'.new';
+    $errors = array(
+      'mkdir'  => t("ERROR: mkdir(@dir) failed, can't write project list.", array('@dir' => $project_dir)),
+      'unlink' => t("ERROR: unlink(@file) failed, can't write project list.", array('@file' => $tmp_filename)),
+      'rename' => t("ERROR: rename(@old, @new) failed, can't write project list.", array('@old' => $tmp_filename, '@new' => $filename))
+    );
+  }
+  else {
+    // Setup the filenames we'll be using.  Normally, we'd have to be
+    // extra careful with $project->uri to avoid malice here, however,
+    // that's validated on the project edit form to prevent any funny
+    // characters, so that much is safe.  The rest of these paths are
+    // just from the global variables at the top of this script, so we
+    // can trust those.  The only one we should be careful of is the
+    // taxonomy term for the API compatibility.
+    $safe_api_vers = strtr($api_version, '/', '_');
+    $project_dir = BASE_DIRECTORY .'/'. $project->uri;
+    $project_id = $project->uri .'-'. $safe_api_vers .'.xml';
+    $filename = $project_dir .'/'. $project_id;
+    $tmp_filename = $filename .'.new';
+    $errors = array(
+      'mkdir'  => t("ERROR: mkdir(@dir) failed, can't write history for %project.", array('@dir' => $project_dir, '%project' => $project->title)),
+      'unlink' => t("ERROR: unlink(@file) failed, can't write history for %project.", array('@file' => $tmp_filename, '%project' => $project->title)),
+      'rename' => t("ERROR: rename(@old, @new) failed, can't write history for %project.", array('@old' => $tmp_filename, '@new' => $filename, '%project' => $project->title))
+    );
+  }
 
   // Make sure we've got the right project-specific subdirectory.
   if (!is_dir($project_dir) && !mkdir($project_dir)) {
-    wd_err(t("ERROR: mkdir(@dir) failed, can't write history for %project.", array('@dir' => $project_dir, '%project' => $project->title)));
+    wd_err($errors['mkdir']);
     return FALSE;
   }
   // Make sure the "[project]-[version].xml.new" file doesn't exist.
   if (is_file($tmp_filename) && !unlink($tmp_filename)) {
-    wd_err(t("ERROR: unlink(@file) failed, can't write history for %project.", array('@file' => $tmp_filename, '%project' => $project->title)));
+    wd_err($errors['unlink']);
     return FALSE;
   }
   // Write the XML history to "[project]-[version].xml.new".
@@ -328,12 +352,51 @@ function project_release_history_write_x
 
   // Now we can atomically rename the .new into place in the "live" spot.
   if (!_rename($tmp_filename, $filename)) {
-    wd_err(t("ERROR: rename(@old, @new) failed, can't write history for %project.", array('@old' => $tmp_filename, '@new' => $filename, '%project' => $project->title)));
+    wd_err($errors['rename']);
     return FALSE;
   }
   return TRUE;
 }
 
+/**
+ * Generate a list of all projects available on this server.
+ */
+function project_list_generate() {
+  $api_vid = _project_release_get_api_vid();
+
+  $query = db_query("SELECT n.title, n.nid, p.uri, u.name FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1");
+  if (!db_num_rows($query)) {
+    wd_err(t('No projects found on this server.'));
+    return FALSE;
+  }
+  $xml = "<projects>\n";
+  while ($project = db_fetch_object($query)) {
+    $xml .= " <project>\n";
+    $xml .= '  <title>'. check_plain($project->title) ."</title>\n";
+    $xml .= '  <short_name>'. check_plain($project->uri) ."</short_name>\n";
+    $xml .= '  <link>'. url("node/$project->nid", NULL, NULL, TRUE) ."</link>\n";
+    $xml .= '  <dc:creator>'. check_plain($project->name). "</dc:creator>\n";
+    $terms =  taxonomy_node_get_terms_by_vocabulary($project->nid, _project_get_vid());
+    foreach ($terms as $term) {
+      $taxonomy_url = url("taxonomy/term/$term->tid", NULL, NULL, TRUE);
+      $xml .= '<category domain="'. $taxonomy_url .'">'. check_plain($term->name) ."</category>\n";
+    }
+
+    // Include a list of API terms if available.
+    $term_query = db_query("SELECT DISTINCT(td.tid), td.name AS term_name FROM {project_release_nodes} prn INNER JOIN {term_node} tn ON prn.nid = tn.nid INNER JOIN {term_data} td ON tn.tid = td.tid WHERE prn.pid = %d AND td.vid = %d ORDER BY td.weight ASC", $project->nid, $api_vid);
+    $xml_api_terms = '';
+    while ($api_term = db_fetch_object($term_query)) {
+      $xml_api_terms .= '   <api_version>'. check_plain($api_term->term_name) ."</api_version>\n";
+    }      
+    if (!empty($xml_api_terms)) {
+      $xml .= "  <api_versions>\n". $xml_api_terms ."  </api_versions>\n";
+    }
+    
+    $xml .= " </project>\n";
+  }
+  $xml .= "</projects>\n";
+  project_release_history_write_xml($xml);
+}
 
 // ------------------------------------------------------------
 // Functions: utility methods
