Index: project.css =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.css,v retrieving revision 1.35 diff -u -p -r1.35 project.css --- project.css 5 Jan 2007 00:21:08 -0000 1.35 +++ project.css 20 Jun 2008 23:17:53 -0000 @@ -1,5 +1,5 @@ /* $Id: project.css,v 1.35 2007/01/05 00:21:08 dww Exp $ */ -/* $Name: $ */ +/* $Name: HEAD $ */ .project table { width: auto; @@ -35,13 +35,11 @@ width: 150px; } -.project .node-form fieldset { - display: block; -} -.project .node-form .project-taxonomy-element { +.node-form .project-taxonomy-element { float: left; padding-right: 2em; } + ul.project-terms { padding-left: 1.5em; } Index: project.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.inc,v retrieving revision 1.124 diff -u -p -r1.124 project.inc --- project.inc 15 Mar 2008 20:09:39 -0000 1.124 +++ project.inc 20 Jun 2008 23:17:53 -0000 @@ -1,6 +1,6 @@ '; - /* Project taxonomy */ if (project_use_taxonomy()) { - drupal_add_js(drupal_get_path('module', 'project') .'/project.js'); - $tree = taxonomy_get_tree(_project_get_vid()); - $top_level = array(); - $options = array(); - foreach ($tree as $i => $term) { - if ($term->parents[0] == 0) { - $last_top = $term->tid; - $top_level[$term->tid] = check_plain($term->name); - } - else { - $options[$last_top][$term->tid] = $term->name; - } - } - // See if there are any project specific taxonomy terms already - // saved in this node (i.e. we're editing an existing project) and - // if so, extract the right default values for our custom form - // elements... - if ($node->taxonomy) { - foreach ($node->taxonomy as $tid => $obj) { - if ($top_level[$tid]) { - $current_top = $tid; - } - else { - $current_options[$tid] = $tid; - } - } - } - $form['project_taxonomy'] = array( - '#type' => 'fieldset', - '#weight' => '-30', - '#title' => t('Project categories'), - '#collapsible' => TRUE, - ); - $form['project_taxonomy']['project_type'] = array( - '#title' => t('Project type'), - '#type' => 'radios', - '#prefix' => '
', - '#suffix' => '
', - '#options' => $top_level, - '#default_value' => $current_top, - '#required' => TRUE, - ); - $select_size = max(5, 2*count($top_level)); - foreach ($options as $tid => $values) { - $form['project_taxonomy']["tid_$tid"] = array( - '#title' => t('!type categories', array('!type' => $top_level[$tid])), - '#type' => 'select', - '#multiple' => TRUE, - '#options' => $values, - '#default_value' => $current_options, - '#attributes' => array('size' => min($select_size, count($values))), - '#prefix' => '
', - '#suffix' => '
', - ); - } + //// Since this form is used relatively infrequently, don't allow the js to be aggregated. + //drupal_add_js(drupal_get_path('module', 'project') .'/project.js', 'module', 'header', FALSE, TRUE, FALSE); + //$tree = taxonomy_get_tree(_project_get_vid()); + //$top_level = array(); + //$options = array(); + //foreach ($tree as $i => $term) { + // if ($term->parents[0] == 0) { + // $last_top = $term->tid; + // $top_level[$term->tid] = check_plain($term->name); + // } + // else { + // $options[$last_top][$term->tid] = $term->name; + // } + //} + //// See if there are any project specific taxonomy terms already + //// saved in this node (i.e. we're editing an existing project) and + //// if so, extract the right default values for our custom form + //// elements... + //$current_top = NULL; + //$current_options = array(); + //if (!empty($node->taxonomy)) { + // foreach ($node->taxonomy as $tid => $obj) { + // if (isset($top_level[$tid])) { + // $current_top = $tid; + // } + // else { + // $current_options[$tid] = $tid; + // } + // } + //} + //$form['project_taxonomy'] = array( + // '#type' => 'fieldset', + // '#weight' => '-30', + // '#title' => t('Project categories'), + // '#collapsible' => TRUE, + // '#theme' => 'project_project_node_form_taxonomy', + //); + //$form['project_taxonomy']['project_type'] = array( + // '#title' => t('Project type'), + // '#type' => 'radios', + // '#options' => $top_level, + // '#default_value' => $current_top, + // '#required' => TRUE, + //); + //$select_size = max(5, 2*count($top_level)); + //foreach ($options as $tid => $values) { + // $form['project_taxonomy']["tid_$tid"] = array( + // '#title' => t('!type categories', array('!type' => $top_level[$tid])), + // '#type' => 'select', + // '#multiple' => TRUE, + // '#options' => $values, + // '#default_value' => $current_options, + // '#attributes' => array('size' => min($select_size, count($values))), + // ); + //} } /* Project properties */ @@ -83,15 +81,7 @@ function project_project_form($node) { '#maxlength' => 128, '#required' => TRUE, ); - $form['project']['body'] = array( - '#type' => 'textarea', - '#title' => t('Full description'), - '#default_value' => isset($node->body) ? $node->body : NULL, - '#cols' => 40, - '#rows' => 10, - '#required' => TRUE, - ); - $form['project']['format'] = filter_form($node->format); + $form['project']['body_field'] = node_body_field($node, t('Full description'), 1); $form['project']['uri'] = array( '#type' => 'textfield', '#title' => t('Short project name'), @@ -137,7 +127,7 @@ function project_project_form($node) { '#type' => 'textfield', '#title' => t('Changelog'), '#default_value' => isset($node->changelog) ? $node->changelog : NULL, - '#size' => 40, + '#size' => 40, '#maxlength' => 255, '#description' => t('Link to changelog.'), ); @@ -158,7 +148,6 @@ function project_project_form($node) { '#description' => t('Link to a live demo.'), ); - $form['#suffix'] = ''; return $form; } @@ -169,7 +158,7 @@ function project_project_validate(&$node } // Make sure title isn't already in use - if (db_num_rows(db_query("SELECT nid FROM {node} WHERE type = '%s' AND status = 1 AND title = '%s' AND nid <> %d", $node->type, $node->title, $node->nid))) { + if (db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = '%s' AND status = %d AND title = '%s' AND nid <> %d", $node->type, 1, $node->title, $node->nid))) { form_set_error('title', t('This project name is already in use.')); } @@ -194,16 +183,11 @@ function project_project_validate(&$node } } } - if (in_array(strtolower($node->uri), $reserved_names) || db_num_rows(db_query("SELECT nid FROM {project_projects} WHERE uri = '%s' AND nid <> %d", $node->uri, $node->nid))) { + if (in_array(strtolower($node->uri), $reserved_names) || db_result(db_query("SELECT COUNT(*) FROM {project_projects} WHERE uri = '%s' AND nid <> %d", $node->uri, $node->nid))) { form_set_error('uri', t('This project name is already in use.')); } } - // We need a description. - if (empty($node->body)) { - form_set_error('body', t('You must add a project description.')); - } - // Make sure all URL fields actually contain URLs. $fields = array( 'homepage' => t('Homepage'), @@ -218,7 +202,7 @@ function project_project_validate(&$node } // Validate the project-specific sub-categories, if any... - if (project_use_taxonomy() && $node->project_type) { + if (project_use_taxonomy() && isset($node->project_type)) { $tree = taxonomy_get_tree(_project_get_vid()); $top_level = array(); foreach ($tree as $i => $term) { @@ -244,12 +228,17 @@ function project_project_set_breadcrumb( $breadcrumb[] = l(t('Home'), NULL); // Find out if the site has created a menu name for /project and use that + // @TODO: In D6, multiple menu links can point to the same path. So there's + // not really an equivalent for the 3 lines below, according to chx. He + // suggested using "SELECT * FROM {menu_links} ml INNER JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.link_path='project" + // but on the drupalorg_testing profile at least that returns two links, one in the primary links block + // and one on the regular navigation bar. $pid = $_menu['path index']['project']; $name = $_menu['items'][$pid]['title']; $breadcrumb[] = l($name, 'project', array('title' => t('Browse projects'))); - if (!empty($node) && project_use_taxonomy()) { - $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid INNER JOIN {term_node} r ON t.tid = r.tid WHERE h.parent = 0 AND t.vid = %d AND r.nid = %d', 't', 'tid'), _project_get_vid(), $node->nid); + if (!empty($node->nid) && project_use_taxonomy()) { + $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid INNER JOIN {term_node} r ON t.tid = r.tid WHERE h.parent = %d AND t.vid = %d AND r.vid = %d', 't', 'tid'), 0, _project_get_vid(), $node->vid); $term = db_fetch_object($result); $breadcrumb[] = l($term->name, 'project/'. $term->name); } @@ -310,10 +299,10 @@ function project_project_view($node, $te ); $links = array(); if ($view_issues) { - $links['all_support'] = l(t('View all support requests'), 'project/issues/'. $node->uri, null, 'categories=support&states=all', null); - $links['pending_support'] = l(t('View pending support requests'), 'project/issues/'. $node->uri, null, 'categories=support', null); - $links['pending_bugs'] = l(t('View pending bug reports'), 'project/issues/'. $node->uri, null, 'categories=bug', null); - $links['pending_features'] = l(t('View pending feature requests'), 'project/issues/'. $node->uri, null, 'categories=feature', null); + $links['all_support'] = l(t('View all support requests'), 'project/issues/'. $node->uri, array('attributes' => null, 'query' => 'categories=support&states=all', 'fragment' => null)); + $links['pending_support'] = l(t('View pending support requests'), 'project/issues/'. $node->uri, array('attributes' => null, 'query' => 'categories=support', 'fragment' => null)); + $links['pending_bugs'] = l(t('View pending bug reports'), 'project/issues/'. $node->uri, array('attributes' => null, 'query' => 'categories=bug', 'fragment' => null)); + $links['pending_features'] = l(t('View pending feature requests'), 'project/issues/'. $node->uri, array('attributes' => null, 'query' => 'categories=feature', 'fragment' => null)); } if ($make_issues) { $links['request_support'] = l(t('Request support'), 'node/add/project_issue/'. $node->uri .'/support'); @@ -333,8 +322,8 @@ function project_project_view($node, $te ); $links = array(); if ($view_issues) { - $links['pending_patches'] = l(t('View pending patches'), 'project/issues/'. $node->uri, null, 'states=8,13,14', null); - $links['available_tasks'] = l(t('View available tasks'), 'project/issues/'. $node->uri, null, 'categories=task', null); + $links['pending_patches'] = l(t('View pending patches'), 'project/issues/'. $node->uri, array('attributes' => null, 'query' => 'states=8,13', 'absolute' => TRUE, 'html' => TRUE)); + $links['available_tasks'] = l(t('View available tasks'), 'project/issues/'. $node->uri, array('attributes' => null, 'query' => 'categories=task', 'fragment' => null)); $links['pending_issues'] = l(t('View all pending issues'), 'project/issues/'. $node->uri); } @@ -356,7 +345,7 @@ function project_project_view($node, $te // Only add the section if there are links for the section. if (!empty($values['links'])) { $node->content[$section] = array( - '#value' => theme('item_list', $values['links'], $values['name']), + '#value' => theme('item_list', $values['links'], isset($values['name']) ? $values['name'] : NULL), '#weight' => !empty($values['weight']) ? $values['weight'] : 0, ); } @@ -376,11 +365,12 @@ function project_project_load($node) { * @see project_nodeapi(). */ function project_project_nodeapi(&$node, $op, $arg) { + $language = isset($node->language) ? $node->language : ''; switch ($op) { case 'insert': _project_save_taxonomy($node); if (module_exists('path')) { - path_set_alias("node/$node->nid", "project/$node->uri"); + path_set_alias("node/$node->nid", "project/$node->uri", NULL, $language); } break; @@ -388,7 +378,7 @@ function project_project_nodeapi(&$node, _project_save_taxonomy($node); if (module_exists('path')) { path_set_alias("node/$node->nid"); // Clear existing alias. - path_set_alias("node/$node->nid", "project/$node->uri"); + path_set_alias("node/$node->nid", "project/$node->uri", NULL, $language); } break; } @@ -408,9 +398,7 @@ function project_project_delete($node) { db_query('DELETE FROM {project_projects} WHERE nid = %d', $node->nid); } -function project_project_access($op, $node) { - global $user; - +function project_project_access($op, $node, $account) { switch ($op) { case 'view': // Since this function is shared for project_release nodes, we have to @@ -426,11 +414,11 @@ function project_project_access($op, $no } break; case 'create': - if ($user->uid && user_access('maintain projects')) { + if ($account->uid && user_access('maintain projects')) { // Since this CVS access checking is non-standard, we need to // special-case uid 1 to always allow everything. - if ($user->uid != 1 && module_exists('cvs') && variable_get('cvs_restrict_project_creation', 1)) { - return db_result(db_query("SELECT uid FROM {cvs_accounts} WHERE uid = %d AND status = %d", $user->uid, CVS_APPROVED)) ? TRUE : FALSE; + if ($account->uid != 1 && module_exists('cvs') && variable_get('cvs_restrict_project_creation', 1)) { + return db_result(db_query("SELECT uid FROM {cvs_accounts} WHERE uid = %d AND status = %d", $account->uid, CVS_APPROVED)) ? TRUE : FALSE; } else { return TRUE; @@ -456,7 +444,7 @@ function project_project_retrieve($key = return node_load(array('nid' => $key, 'type' => 'project_project')); } else { - $nid = db_result(db_query("SELECT nid FROM {project_projects} WHERE uri = '%s'", $key), 0); + $nid = db_result(db_query("SELECT nid FROM {project_projects} WHERE uri = '%s' LIMIT %d", $key, 1)); if (!$nid) { return new StdClass(); } @@ -510,27 +498,27 @@ function _project_save_taxonomy(&$node) // This way, we're sure to clear out things that have been changed. $vid = _project_get_vid(); $result = db_query('SELECT tid FROM {term_data} WHERE vid = %d', $vid); - $items = array(); + $args = array($node->vid); while ($item = db_fetch_object($result)) { - $items[] = "tid = $item->tid"; + $args[] = $item->tid; } - if ($items) { - $sql = 'DELETE FROM {term_node} WHERE nid = %d AND ('. implode(' OR ', $items) . ')'; - db_query($sql, $node->nid); + if (count($args) > 1) { + $sql = 'DELETE FROM {term_node} WHERE vid = %d AND tid IN ('. db_placeholders($args) .')'; + db_query($sql, $args); } $tid = $node->project_type; - _project_db_save_taxonomy($node->nid, $tid); + _project_db_save_taxonomy($node->nid, $tid, $node->vid); $tid_field = 'tid_' . $tid; if (isset($node->$tid_field)) { foreach ($node->$tid_field as $tid) { - _project_db_save_taxonomy($node->nid, $tid); + _project_db_save_taxonomy($node->nid, $tid, $node->vid); } } } } -function _project_db_save_taxonomy($nid, $tid) { - db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $tid); +function _project_db_save_taxonomy($nid, $tid, $vid) { + db_query('INSERT INTO {term_node} (nid, tid, vid) VALUES (%d, %d, %d)', $nid, $tid, $vid); } /** @@ -555,3 +543,17 @@ function project_page_link_alter($node, $function($node, $all_links); } } + +/** + * Adds the 'project-taxonomy-element' div to the project_type + * and term select box on the project_project node form. + */ +function theme_project_project_node_form_taxonomy($form) { + $output = ''; + foreach (element_children($form) as $child) { + $output .= '
'; + $output .= drupal_render($form[$child]); + $output .= '
'; + } + return $output; +} \ No newline at end of file Index: project.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.info,v retrieving revision 1.2 diff -u -p -r1.2 project.info --- project.info 13 Jun 2007 19:33:16 -0000 1.2 +++ project.info 20 Jun 2008 23:17:53 -0000 @@ -2,3 +2,5 @@ name = Project description = Provides a project node type and browsing of projects. package = Project +dependencies[] = views +core = 6.x \ No newline at end of file Index: project.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.install,v retrieving revision 1.20 diff -u -p -r1.20 project.install --- project.install 8 Mar 2008 16:48:12 -0000 1.20 +++ project.install 20 Jun 2008 23:17:53 -0000 @@ -1,51 +1,21 @@ t('The base table for project_project nodes.'), + 'fields' => array( + 'nid' => array( + 'description' => t('Primary Key: The {node}.nid of the project_project node.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'uri' => array( + 'description' => t('The short name of the project.'), + 'type' => 'varchar', + 'length' => 50, + 'not null' => TRUE, + 'default' => '', + ), + 'homepage' => array( + 'description' => t("An external link to the project's homepage."), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'changelog' => array( + 'description' => t('An external link to a log of changes for the project.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'cvs' => array( + 'description' => t('Path of the CVS repository for the project.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'demo' => array( + 'description' => t('An external link to a demonstration site for the project.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'documentation' => array( + 'description' => t('An external link to documentation for the project.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'screenshots' => array( + 'description' => t('An external link screenshots of the project.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'license' => array( + 'description' => t('An external link to the license of the project.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'primary key' => array('nid'), + 'indexes' => array( + 'project_projects_uri' => array(array('uri', 8)), + ), ); - - foreach ($tables as $table) { - $res = array(); - if ($can_use_subselect) { - $res = update_sql("DELETE FROM $table WHERE nid NOT IN (SELECT nid FROM {node})"); - $ret[] = $res; - } - else { - $result = db_query("SELECT p.nid FROM $table p LEFT JOIN {node} n ON p.nid = n.nid WHERE n.nid IS NULL"); - $nids = array(); - while ($nid = db_fetch_object($result)) { - $nids[] = $nid->nid; - } - if (!empty($nids)) { - $res = update_sql("DELETE FROM $table WHERE nid IN (" . implode(',', $nids) . ')'); - $ret[] = $res; - } - } - if ($res['success']) { - $num = db_affected_rows(); - $ret[] = array('success' => TRUE, 'query' => check_plain("$num rows deleted from $table")); - } - } - return $ret; -} - -function project_update_4() { - $ret = array(); - - // PostgreSQL needs CREATE TABLE foobar _AS_ SELECT ... - $AS = ($GLOBALS['db_type'] == 'pgsql') ? 'AS' : ''; - - // Create temporary table to build the new {project_projects} and - // {project_issue_projects} tables from. - $ret[] = update_sql("CREATE TABLE {project_projects_tmp} $AS SELECT * FROM {project_projects}"); - - if (db_table_exists('project_issue_projects')) { - $ret[] = update_sql("DROP TABLE {project_issue_projects}"); - } - $ret[] = update_sql("DROP TABLE {project_projects}"); - - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - $ret[] = update_sql("CREATE TABLE {project_projects} ( - nid int(10) unsigned NOT NULL default '0', - uri varchar(50) NOT NULL default '', - homepage varchar(255) NOT NULL default '', - changelog varchar(255) NOT NULL default '', - cvs varchar(255) NOT NULL default '', - demo varchar(255) NOT NULL default '', - release_directory varchar(255) NOT NULL default '', - version int(10) unsigned NOT NULL default '0', - mail varchar(255) NOT NULL default '', - documentation varchar(255) not null default '', - screenshots varchar(255) not null default '', - license varchar(255) not null default '', - PRIMARY KEY (`nid`), - KEY project_projects_uri (uri(8)) - ) /*!40100 DEFAULT CHARACTER SET utf8 */;"); - $ret[] = update_sql("CREATE TABLE {project_issue_projects} ( - nid int(10) unsigned NOT NULL default '0', - issues tinyint(4) NOT NULL default '0', - components text, - help text, - mail_digest varchar(255) NOT NULL default '', - mail_copy varchar(255) NOT NULL default '', - mail_copy_filter varchar(255) NOT NULL default '', - mail_copy_filter_state varchar(255) NOT NULL default '', - mail_reminder tinyint(4) NOT NULL default '0', - PRIMARY KEY (nid) - ) /*!40100 DEFAULT CHARACTER SET utf8 */;"); - break; - case 'pgsql': - $ret[] = update_sql("CREATE TABLE {project_projects} ( - nid int NOT NULL default '0', - uri varchar(50) NOT NULL default '', - homepage varchar(255) NOT NULL default '', - changelog varchar(255) NOT NULL default '', - cvs varchar(255) NOT NULL default '', - demo varchar(255) NOT NULL default '', - release_directory varchar(255) NOT NULL default '', - version int NOT NULL default '0', - mail varchar(255) not null default '', - screenshots varchar(255) default '' not null, - documentation varchar(255) default '' not null, - license varchar(255) default '' not null, - PRIMARY KEY (nid) - );"); - $ret[] = update_sql("CREATE TABLE {project_issue_projects} ( - nid int NOT NULL default '0', - issues smallint NOT NULL default '0', - components text, - help text, - mail_digest varchar(255) not null default '', - mail_copy varchar(255) not null default '', - mail_copy_filter varchar(255) not null default '', - mail_copy_filter_state varchar(255) default '' not null, - mail_reminder smallint NOT NULL default '0', - PRIMARY KEY (nid) - );"); - break; - } - - $ret[] = update_sql("INSERT INTO {project_projects} SELECT DISTINCT nid, uri, homepage, changelog, cvs, demo, release_directory, version, mail, documentation, screenshots, license FROM {project_projects_tmp}"); - $ret[] = update_sql("INSERT INTO {project_issue_projects} SELECT DISTINCT nid, issues, components, help, mail_digest, mail_copy, mail_copy_filter, mail_copy_filter_state, mail_reminder FROM {project_projects_tmp}"); - - $ret[] = update_sql("DROP TABLE {project_projects_tmp}"); - - foreach (array('reply_to', 'digest_last', 'digest_interval', 'reminder_last', 'reminder_interval') as $varname) { - $val = variable_get("project_$varname", NULL); - if (isset($val)) { - variable_set("project_issue_$varname", $val); - $ret[] = update_sql("DELETE FROM {variable} WHERE name = 'project_" . $varname . "'"); - } - } - - return $ret; -} - -/** - * 5.x specific updates. - */ - -/** - * Remove a stale variable setting. - */ -function project_update_5000() { - variable_del('project_support_forum'); - return array(); -} - -/** - * Get rid of the per-project mail address (used only for the issue - * email From: header) which has numerous problems. - * See http://drupal.org/node/36619 and http://drupal.org/node/189210 - */ -function project_update_5001() { - $ret = array(); - // PgSQL and MySQL have the same syntax for this. - $ret[] = update_sql('ALTER TABLE {project_projects} DROP COLUMN mail'); - return $ret; -} - -/** - * Get rid of the 'version' column in the {project_projects} table. - * See http://drupal.org/node/231392 - */ -function project_update_5002() { - $ret = array(); - // PgSQL and MySQL have the same syntax for this. - $ret[] = update_sql('ALTER TABLE {project_projects} DROP COLUMN version'); - return $ret; -} - -/** - * Get rid of the 'release_directory' column in the {project_projects} table. - * See http://drupal.org/node/231558 - */ -function project_update_5003() { - $ret = array(); - // PgSQL and MySQL have the same syntax for this. - $ret[] = update_sql('ALTER TABLE {project_projects} DROP COLUMN release_directory'); - return $ret; + return $schema; } Index: project.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.js,v retrieving revision 1.2 diff -u -p -r1.2 project.js --- project.js 13 Jul 2007 21:11:08 -0000 1.2 +++ project.js 20 Jun 2008 23:17:53 -0000 @@ -1,10 +1,9 @@ /* $Id: project.js,v 1.2 2007/07/13 21:11:08 dww Exp $ */ -Drupal.projectAutoAttach = function () { +Drupal.behaviors.projectAuto = function (context) { // The initially selected term, if any. var tid; - $('div.project-taxonomy-element input') - .each(function () { + $('div.project-taxonomy-element input:not(.projectAuto-processed)', context).addClass('projectAuto-processed').each(function () { if (this.checked) { tid = this.value; } @@ -33,8 +32,3 @@ Drupal.projectSetTaxonomy = function (ti } }); } - -// Global killswitch. -if (Drupal.jsEnabled) { - $(document).ready(Drupal.projectAutoAttach); -} Index: project.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/project.module,v retrieving revision 1.313 diff -u -p -r1.313 project.module --- project.module 11 Jun 2008 18:19:41 -0000 1.313 +++ project.module 20 Jun 2008 23:17:53 -0000 @@ -1,25 +1,25 @@ '. t('The project module makes special use of the taxonomy (category) system. A special vocabulary, %vocabulary_name, has been created automatically.', array('%vocabulary_name' => $vocabulary->name)) .'

'; $text .= '

'. t('To take full advantage of project categorization, add at least two levels of terms to this vocabulary. The first level will be the basic project types, e.g., "Modules", "Themes", "Translations".') .'

'; $text .= '

'. t('Subterms of each of these types will be the categories that users can select to classify the projects. For example, "Modules" might have sub-terms including "Mail" and "XML".') .'

'; @@ -51,6 +51,9 @@ function _project_taxonomy_help($vid = 0 function project_block($op = 'list', $delta = 0) { if ($op == 'list') { $blocks[0]['info'] = t('Project navigation'); + // Note: We can get by with using BLOCK_CACHE_PER_ROLE below because + // block caching is disabled when node access control modules are in use. + $blocks[0]['cache'] = BLOCK_CACHE_PER_ROLE; return $blocks; } else if ($op == 'view') { @@ -211,41 +214,44 @@ function project_find_alias($query, $tab * Callback for the main settings page. */ function project_settings_form() { - $sort_methods = drupal_map_assoc(array_keys(module_invoke_all('project_sort_methods', 'methods'))); - - if (project_use_taxonomy()) { - - // For now, date-based browsing doesn't work once you disable - // taxonomy (only because the code involved is rather complicated - // and needs to be majorly refactored and cleaned up). - $form['project_sort_method'] = array( - '#type' => 'radios', - '#title' => t('Default sort option'), - '#default_value' => variable_get('project_sort_method', 'category'), - '#options' => $sort_methods, - '#description' => t('Default sorting option to use on the overview page'), - ); - $form['sort_methods'] = array( - '#type' => 'fieldset', - '#title' => t('Enabled sorting options'), - '#description' => t('Each type of project on your site will have its own project browsing page at %link. Each browsing page can be configured for different browsing options (by name, by date, etc). The settings below determine which browsing methods are available for each project type.', array('%link' => url('project', NULL, NULL, TRUE) . '/[type]')), - ); - $tree = taxonomy_get_tree(_project_get_vid(), 0 , -1, 1); - foreach ($tree as $term) { - $form['sort_methods']['project_sort_method_used_' . $term->tid] = array( - '#type' => 'checkboxes', - '#title' => $term->name, - '#default_value' => array_filter(variable_get('project_sort_method_used_'. $term->tid, array_keys($sort_methods))), - '#options' => $sort_methods, - ); - } - } - $form['project_browse_nodes'] = array( - '#type' => 'select', '#title' => t('Number of projects to list in paged browsing'), - '#default_value' => variable_get('project_browse_nodes', 30), - '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 45, 50)), - '#description' => t('The default maximum number of projects to list when browsing lists, e.g., by category.') - ); + $form = array(); + // @TODO: We should be able to delete these settings below since they won't + // be necessary with views handling project browsing. + //$sort_methods = drupal_map_assoc(array_keys(module_invoke_all('project_sort_methods', 'methods'))); + // + //if (project_use_taxonomy()) { + // + // // For now, date-based browsing doesn't work once you disable + // // taxonomy (only because the code involved is rather complicated + // // and needs to be majorly refactored and cleaned up). + // $form['project_sort_method'] = array( + // '#type' => 'radios', + // '#title' => t('Default sort option'), + // '#default_value' => variable_get('project_sort_method', 'category'), + // '#options' => $sort_methods, + // '#description' => t('Default sorting option to use on the overview page'), + // ); + // $form['sort_methods'] = array( + // '#type' => 'fieldset', + // '#title' => t('Enabled sorting options'), + // '#description' => t('Each type of project on your site will have its own project browsing page at %link. Each browsing page can be configured for different browsing options (by name, by date, etc). The settings below determine which browsing methods are available for each project type.', array('%link' => url('project', array('absolute' => TRUE)) . '/[type]')), + // ); + // $tree = taxonomy_get_tree(_project_get_vid(), 0 , -1, 1); + // foreach ($tree as $term) { + // $form['sort_methods']['project_sort_method_used_' . $term->tid] = array( + // '#type' => 'checkboxes', + // '#title' => $term->name, + // '#default_value' => array_filter(variable_get('project_sort_method_used_'. $term->tid, array_keys($sort_methods))), + // '#options' => $sort_methods, + // ); + // } + //} + //$form['project_browse_nodes'] = array( + // '#type' => 'select', '#title' => t('Number of projects to list in paged browsing'), + // '#default_value' => variable_get('project_browse_nodes', 30), + // '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 45, 50)), + // '#description' => t('The default maximum number of projects to list when browsing lists, e.g., by category.') + //); return system_settings_form($form); } @@ -286,11 +292,14 @@ function _project_get_vid() { * Implementation of hook_term_path(). */ function project_term_path($term) { + // Make sure we have the entire term object. + $term = taxonomy_get_term($term->tid); + // The path must include the first-level term name for this term. $tree = taxonomy_get_tree(_project_get_vid()); $parents = taxonomy_get_parents_all($term->tid); foreach($parents as $parent) { - $ancestors[] = $parent->tid; + $ancestors[] = $parent->tid; } foreach ($tree as $t) { if (in_array($t->tid, $ancestors) && $t->depth == 0) { @@ -316,102 +325,142 @@ function project_taxonomy($op, $type, $a } } -function project_menu($may_cache) { +/** + * Determine if the currently logged in user could have access to any project_project nodes. + */ +function project_project_access_any() { + return user_access('access projects') || user_access('access own projects') || user_access('administer projects'); +} + +function project_menu() { $items = array(); - global $user; - if ($may_cache) { - // User pages: - $access_all = user_access('access projects'); - $access_own = user_access('access own projects'); - $access_admin = user_access('administer projects'); - $access = $access_all || $access_own || $access_admin; - - $items[] = array('path' => 'project', - 'title' => t('Projects'), - 'callback' => 'project_page_overview', - 'access' => $access, - 'type' => MENU_NORMAL_ITEM); - - $items[] = array('path' => 'project/autocomplete', - 'title' => t('Autocomplete project'), - 'callback' => 'project_autocomplete', - 'access' => $access, - 'type' => MENU_CALLBACK); - - // Project browsing pages - if (project_use_taxonomy()) { - $default_sort = variable_get('project_sort_method', 'category'); - $sort_methods = module_invoke_all('project_sort_methods', 'methods'); - $terms = taxonomy_get_tree(_project_get_vid()); - $releases = variable_get('project_release_browse_versions', 0); - foreach ($terms as $i => $term) { - // Only use the first-level terms. - if ($term->depth == 0) { - $items[] = array('path' => 'project/'. $term->name, - 'title' => $term->name, - 'access' => $access, - 'type' => MENU_NORMAL_ITEM, - 'weight' => $term->weight, - 'callback arguments' => array($term->name)); - $j = 0; - $term_methods = array_keys(array_filter(variable_get('project_sort_method_used_'. $term->tid, $sort_methods))); - foreach ($term_methods as $sort_method) { - $items[] = array('path' => 'project/' . $term->name . '/'. $sort_method, - 'title' => t('Browse by !sort_method', array('!sort_method' => $sort_method)), - 'access' => $access, - // It's a default task if a) sort method matches default, or b) default sort isn't - // in the list of sort methods, and it's the first tab. - 'type' => (($sort_method == $default_sort || (($j == 0) && !in_array($default_sort, $term_methods))) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK), - 'weight' => ($sort_method == $default_sort) ? -10 : $j, - 'callback arguments' => array($term->name, $sort_method)); - $j++; - } - } - } - } + // @TODO: This menu definition should be deleted. Make sure that views only shows + // this menu item when the user has the appropriate access privs. + //$items['project'] = array( + // 'title' => 'Projects', + // 'page callback' => 'project_page_overview', + // 'access callback' => 'project_project_access_any', + // 'type' => MENU_NORMAL_ITEM); + + $items['project/autocomplete'] = array( + 'title' => 'Autocomplete project', + 'page callback' => 'project_autocomplete', + 'access callback' => 'project_project_access_any', + 'type' => MENU_CALLBACK); + + // Project browsing pages + // TODO: We can remove this block below when we add views support. + //if (project_use_taxonomy()) { + // $default_sort = variable_get('project_sort_method', 'category'); + // $sort_methods = module_invoke_all('project_sort_methods', 'methods'); + // $terms = taxonomy_get_tree(_project_get_vid()); + // $releases = variable_get('project_release_browse_versions', 0); + // foreach ($terms as $i => $term) { + // // Only use the first-level terms. + // if ($term->depth == 0) { + // $items['project/'. $term->name] = array( + // 'title' => $term->name, // TODO: Fix? + // 'access callback' => 'project_check_access_any', + // 'type' => MENU_NORMAL_ITEM, + // 'weight' => $term->weight, + // 'page arguments' => array($term->name), + // ); + // $j = 0; + // $term_methods = array_keys(array_filter(variable_get('project_sort_method_used_'. $term->tid, $sort_methods))); + // foreach ($term_methods as $sort_method) { + // $items['project/' . $term->name . '/'. $sort_method] = array( + // 'title' => "Browse by $sort_method", // TODO: Fix? + // 'access callback' => 'project_check_access_any', + // // It's a default task if a) sort method matches default, or b) default sort isn't + // // in the list of sort methods, and it's the first tab. + // 'type' => (($sort_method == $default_sort || (($j == 0) && !in_array($default_sort, $term_methods))) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK), + // 'weight' => ($sort_method == $default_sort) ? -10 : $j, + // 'page arguments' => array($term->name, $sort_method)); + // $j++; + // } + // } + // } + //} + + // Developers + $items['project/developers'] = array( + 'title' => 'Developers', + 'page callback' => 'project_developers', + 'access callback' => 'project_project_access_any', + 'type' => MENU_CALLBACK, + ); + + // CVS messages: + $items['project/cvs'] = array( + 'title' => 'CVS', + 'page callback' => 'project_cvs', + 'access callback' => 'project_project_access_any', + 'type' => MENU_CALLBACK, + ); + + // Administration pages + $items['admin/project'] = array( + 'title' => 'Project administration', + 'description' => 'Administrative interface for project management and related modules.', + 'page callback' => 'system_admin_menu_block_page', + 'access arguments' => array('administer projects'), + 'file' => 'system.admin.inc', + 'file path' => drupal_get_path('module', 'system'), + 'type' => MENU_NORMAL_ITEM, + ); + // @TODO: We can most likely delete this menu item, since there are + // no longer any project module specific settings since views is being used. + //$items['admin/project/project-settings'] = array( + // 'title' => 'Project settings', + // 'description' => 'Configure the behavior and appearance of the project browsing pages and other settings for the Project module.', + // 'page callback' => 'drupal_get_form', + // 'page arguments' => array('project_settings_form'), + // 'access arguments' => array('administer projects'), + // 'type' => MENU_NORMAL_ITEM, + //); + + $items['node/%project_edit_project/edit/project'] = array( + 'title' => 'Project', + 'page callback' => 'node_page', + 'page arguments' => array(1), + 'access callback' => 'node_access', + 'access arguments' => array('update', 1), + 'weight' => -5, 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + return $items; +} - // Developers - $items[] = array('path' => 'project/developers', 'title' => t('Developers'), 'callback' => 'project_developers', 'access' => $access, 'type' => MENU_CALLBACK); - // CVS messages: - $items[] = array('path' => 'project/cvs', 'title' => t('CVS'), 'callback' => 'project_cvs', 'access' => $access, 'type' => MENU_CALLBACK); +/** + * Implementation of hook_init(). + */ +function project_init() { + drupal_add_css(drupal_get_path('module', 'project') .'/project.css'); - // Administration pages - $items[] = array( - 'path' => 'admin/project', - 'title' => t('Project administration'), - 'description' => t('Administrative interface for project management and related modules.'), - 'callback' => 'system_admin_menu_block_page', - 'access' => $access_admin, - 'type' => MENU_NORMAL_ITEM, - ); - $items[] = array( - 'path' => 'admin/project/project-settings', - 'title' => t('Project settings'), - 'description' => t('Configure the behavior and appearance of the project browsing pages and other settings for the Project module.'), - 'callback' => 'drupal_get_form', - 'callback arguments' => array('project_settings_form'), - 'access' => $access_admin, - 'type' => MENU_NORMAL_ITEM, - ); + if (module_exists('views')) { + module_load_include ('inc', 'project', 'project.views'); } - else { - drupal_add_css(drupal_get_path('module', 'project') .'/project.css'); - if (arg(0) == 'node' && is_numeric(arg(1))) { - $node = node_load(arg(1)); - if ($node->type == 'project_project' && node_access('update', $node) && - (module_exists('project_issue') || module_exists('project_release'))) { - $items[] = array( - 'path' => 'node/'. arg(1) .'/edit/project', - 'title' => t('Project'), - 'callback' => 'node_page', - 'weight' => -5, 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - } - } +} + +/** + * Menu loader callback. Load a project_project node if the given + * nid is a project_project node and if the user has permission to edit + * the project and if either the project_issue or project_release module + * exists. + */ +function project_edit_project_load($nid) { + if (!is_numeric($nid)) { + return FALSE; } - return $items; + $node = node_load($nid); + if (!isset($node->type) || $node->type != 'project_project') { + return FALSE; + } + if (!module_exists('project_issue') && !module_exists('project_release')) { + return FALSE; + } + return $node; } function project_check_admin_access($project, $cvs_access = NULL) { @@ -432,7 +481,7 @@ function project_check_admin_access($pro // If $cvs_access is not defined, check to make sure the user has cvs access // and that the user's cvs account is approved. if (project_use_cvs($project_obj) && !isset($cvs_access)) { - if (db_num_rows(db_query("SELECT * FROM {cvs_accounts} WHERE uid = %d AND status = %d", $user->uid, CVS_APPROVED))) { + if (db_result(db_query("SELECT COUNT(*) FROM {cvs_accounts} WHERE uid = %d AND status = %d", $user->uid, CVS_APPROVED))) { $cvs_access = TRUE; } else { @@ -445,7 +494,7 @@ function project_check_admin_access($pro return TRUE; } if (project_use_cvs($project_obj) && $cvs_access) { - if (db_num_rows(db_query("SELECT * FROM {cvs_project_maintainers} WHERE uid = %d AND nid = %d", $user->uid, $project_obj->nid))) { + if (db_result(db_query("SELECT COUNT(*) FROM {cvs_project_maintainers} WHERE uid = %d AND nid = %d", $user->uid, $project_obj->nid))) { return TRUE; } } @@ -458,7 +507,7 @@ function project_check_admin_access($pro * taxonomy.module's form_alter() so we can do our own taxonomy * selection. */ -function project_form_alter($form_id, &$form) { +function project_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'project_project_node_form') { $vid = _project_get_vid(); if (isset($form['taxonomy'][$vid])) { @@ -466,7 +515,7 @@ function project_form_alter($form_id, &$ } // If there are no children elements, we should unset the entire // thing so we don't end up with an empty fieldset. - if (!element_children($form['taxonomy'])) { + if (!empty($form['taxonomy']) && (!element_children($form['taxonomy']))) { unset($form['taxonomy']); } @@ -514,311 +563,312 @@ function project_page() { } } +// @TODO Delete this function if possible. function project_page_overview($termname = NULL, $sort_method = NULL) { - global $form_values; - - project_project_set_breadcrumb(); - $sort_methods = module_invoke_all('project_sort_methods', 'methods'); - - $output = ''; - if (module_exists('project_release') && variable_get('project_release_browse_versions', 0)) { - $version_form = drupal_get_form('project_release_version_filter_form'); - $output .= $version_form; - // Read in requested version, if any. - $version = isset($_SESSION['project_version']) ? $_SESSION['project_version'] : variable_get('project_release_overview', -1); - } - - // If browsing by taxonomy, only fetch projects for this term. - if (project_use_taxonomy()) { - $vid = _project_get_vid(); - if ($termname) { - - $type = db_fetch_object(db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_hierarchy} th ON t.tid = th.tid WHERE t.vid = %d AND th.parent = 0 AND t.name = '%s'", 't', 'tid'), $vid, $termname)); - // Bad project category passed, return page not found. - if (!$type) { - return drupal_not_found(); - } - if (!$sort_method) { - // For the default, we use the overall default if enabled for this term, and if not we use the first enabled method. - $term_methods = array_filter(variable_get('project_sort_method_used_' . $type->tid, array_keys($sort_methods))); - $sort_method = in_array(variable_get('project_sort_method', 'category'), $term_methods) ? variable_get('project_sort_method', 'category') : array_shift($term_methods); - } - - if ($type->description) { - $output .= '

' . filter_xss($type->description) . '

'; - } - - $module = $sort_methods[$sort_method]; - // Bad sort method passed, return page not found. - if (!isset($module)) { - return drupal_not_found(); - } - if (module_invoke($module, 'project_sort_methods', 'set term', $sort_method)) { - $tree = taxonomy_get_tree(_project_get_vid(), $type->tid); - $terms = array(); - if ($tree) { - $tids = array(); - if (variable_get('project_release_browse_versions', 0)) { - $version_params = array(); - if ($version != -1) { - $version_where = 'tr.tid = %d'; - $version_params[] = $version; - } - else { - $placeholders = array(); - $active_tids = project_release_compatibility_list(); - foreach ($active_tids as $tid => $api_term) { - $placeholders[] = '%d'; - $version_params[] = $tid; - } - $version_where = 'tr.tid IN ('. implode(',', $placeholders) .')'; - } - // Find all terms associated with the requested version. - $result = db_query("SELECT tp.tid, COUNT(DISTINCT(n.nid)) AS count FROM {term_node} tp INNER JOIN {project_release_nodes} p ON tp.nid = p.pid INNER JOIN {node} n ON n.nid = p.pid INNER JOIN {term_node} tr ON tr.nid = p.nid WHERE $version_where AND (n.status = 1) GROUP BY tp.tid", $version_params); - $tids = array(); - while ($item = db_fetch_object($result)) { - $tids[$item->tid] = $item->count; - } - } - foreach ($tree as $cterm) { - if (!variable_get('project_release_browse_versions', 0) || ($version == -1) || array_key_exists($cterm->tid, $tids)) { - if ($tids[$cterm->tid]) { - $cterm->count = $tids[$cterm->tid]; - } - else { - // We don't use taxonomy_term_count_nodes() because it includes child terms' counts. - $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 AND t.tid = %d GROUP BY t.tid'), $cterm->tid); - $term = db_fetch_object($result); - $cterm->count = $term->c; - } - $terms[] = $cterm; - } - } - } - - // Look for a specific category term. - if ($arg = arg(3)) { - // Bad term, return page not found. - if (!($term = taxonomy_get_term($arg))) { - return drupal_not_found(); - } - } - } - // The sorting method is not supported by the module, so any term passed is invalid. - // Return page not found if one is found. - elseif (arg(3)) { - return drupal_not_found(); - } - - // Set the default elements that will be used to construct the SQL statement. - $sql_elements = project_empty_query(); - $sql_elements['fields']['pieces'] = array( - 'DISTINCT(n.nid)', - 'n.title', - 'n.sticky', - 'n.type', - 'nr.teaser', - 'nr.format', - ); - $sql_elements['from']['pieces'] = array( - '{node} n ' - ); - $sql_elements['joins']['pieces'] = array( - 'INNER JOIN {node_revisions} nr ON n.vid = nr.vid', - 'INNER JOIN {project_projects} p ON n.nid = p.nid', - 'LEFT JOIN {term_node} r ON n.nid = r.nid' - ); - $sql_elements['wheres']['pieces'] = array( - 'n.status = 1', - 'r.tid = %d' - ); - $sql_elements['parameters']['pieces'] = array( - isset($term) ? $term->tid : $type->tid - ); - - // If the site has enabled issue tracking via the project_issue - // module, we want to add 1 more field and JOIN to our query so - // we can provide the link for "Bugs and feature requests"... - if (module_exists('project_issue')) { - $sql_elements['fields']['pieces'][] = 'pip.issues'; - $sql_elements['joins']['pieces'][] = 'INNER JOIN {project_issue_projects} pip ON n.nid = pip.nid'; - } - - // Only the 'pieces' are returned; the prefix and glue elements remain unchanged. - $sql_settings = module_invoke($module, 'project_sort_methods', 'sql_settings', $sort_method); - if (empty($sql_settings)) { - $sql_settings = array(); - } - - if (module_exists('project_release')) { - $project_release_sql = array( - 'joins' => array('INNER JOIN {project_release_projects} prp ON n.nid = prp.nid'), - 'wheres' => array('prp.releases = 1'), - ); - $sql_settings = array_merge_recursive($sql_settings, $project_release_sql); - } - - if (variable_get('project_release_browse_versions', 0)) { - $release_settings = array( - 'fields' => array('prn.file_path', 'prn.version', 'MAX(prn.file_date) AS changed', 'COUNT(*) AS release_count'), - 'group_bys' => array('n.nid'), - ); - $release_settings['joins'] = array( - 'INNER JOIN {project_release_nodes} prn ON n.nid = prn.pid', - 'INNER JOIN {term_node} tr ON tr.nid = prn.nid', - 'INNER JOIN {node} rn ON rn.nid = prn.nid', - ); - $release_settings['wheres'][] = 'rn.status = 1'; - if ($version != -1) { - $release_settings['joins'][] = 'INNER JOIN {project_release_supported_versions} prsv ON prsv.nid = p.nid AND prsv.tid = tr.tid'; - $release_settings['wheres'][] = 'tr.tid = %d'; - $release_settings['wheres'][] = 'prsv.supported = 1'; - $release_settings['parameters'][] = $version; - } - else { - $placeholders = array(); - $active_tids = project_release_compatibility_list(); - foreach ($active_tids as $tid => $compatibility_term) { - $placeholders[] = '%d'; - $release_settings['parameters'][] = $tid; - } - $where = 'tr.tid IN ('. implode(',', $placeholders) .')'; - $release_settings['wheres'][] = $where; - - // We need to grab the uid for the project node, so - // that node_access() will work properly without a full - // node_load() when we're generating the download table in - // project_release_table(). - $release_settings['fields'][] = 'n.uid'; - } - $sql_settings = array_merge_recursive($sql_settings, $release_settings); - } - - // Merge in $sql_elements - if (!empty($sql_settings)) { - foreach(array_keys($sql_settings) as $key) { - $sql_elements[$key]['pieces'] = array_merge($sql_elements[$key]['pieces'], $sql_settings[$key]); - $sql_elements[$key]['pieces'] = array_unique($sql_elements[$key]['pieces']); - } - } - - $parameters = $sql_elements['parameters']['pieces']; - - $sql = project_build_query($sql_elements); - - $pager = module_invoke($module, 'project_sort_methods', 'pager', $sort_method); - if ($pager) { - $first_field = array_shift($sql_elements['fields']['pieces']); - if (count($sql_elements['group_bys']['pieces'])) { - $first_field = 'DISTINCT(' . $sql_elements['group_bys']['pieces'][0] . ')'; - $sql_elements['group_bys']['pieces'] = array(); - } - $sql_elements['fields']['pieces'] = array("COUNT($first_field)"); - // ORDER BY can screw up COUNT(DISTINCT), and we don't care - // about the order for the count query. - unset($sql_elements['order_bys']); - $count_query = project_build_query($sql_elements); - $result = pager_query($sql, variable_get('project_browse_nodes', 30), 0, $count_query, $parameters); - } - else { - $result = db_query($sql, $parameters); - } - - // If we've just switched versions, we may have a term requested but no matching projects. - // In that case, we returned an uncollapsed fieldset. - if (module_invoke($module, 'project_sort_methods', 'set term', $sort_method)) { - $output .= theme('fieldset', array('#title' => t('Categories'), '#collapsible' => TRUE, '#collapsed' => (arg(3) && db_num_rows($result)) ? TRUE : FALSE, '#children' => theme('project_term_list', $terms, "project/$termname/$sort_method"))); - if (!arg(3) || !db_num_rows($result)) { - return $output; - } - drupal_set_title(t('@project_type: %category', array('@project_type' => $type->name, '%category' => $term->name))); - } - else { - drupal_set_title(check_plain($type->name)); - } - } - // If taxonomy is enabled but no termname is selected, show a list of terms to choose from. - else { - $tree = taxonomy_get_tree($vid, 0, -1, 1); - $items = array(); - foreach ($tree as $term) { - $items[] = theme('project_type', $term); - } - drupal_set_title(t('Project types')); - return theme('item_list', $items); - } - } - // If taxonomy is not enabled, fetch all projects - else { - // Any terms passed without taxonomy module enabled are bogus -- return page not found. - if (isset($termname)) { - return drupal_not_found(); - } - // If the site has enabled issue tracking via the project_issue - // module, we want to add 1 more field and JOIN to our query so - // we can provide the link for "Bugs and feature requests"... - if (module_exists('project_issue')) { - $ISSUES = ', pip.issues'; - $ISSUE_JOIN ='INNER JOIN {project_issue_projects} pip ON n.nid = pip.nid'; - } - $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, nr.teaser, nr.format$ISSUES FROM {node} n INNER JOIN {node_revisions} nr ON n.vid = nr.vid $ISSUE_JOIN WHERE n.status = 1 AND n.type = 'project_project' ORDER BY n.title ASC")); - } - $projects = ''; - $class = 'even'; - while ($project = db_fetch_object($result)) { - $project->body = check_markup($project->teaser, $project->format, FALSE); - if (module_exists('taxonomy')) { - $project->taxonomy = taxonomy_node_get_terms($project->nid); - if (isset($type)) { - // Hide the top-level project type term from the links, but add it to - // the $project object for theme_project_summary() to use if it wants. - unset($project->taxonomy[$type->tid]); - $project->term = $termname; - } - $project->terms = taxonomy_link('taxonomy terms', $project); - } - - // Make sure we have the latest release - if (isset($project->release_count) && $project->release_count > 1 && $version != -1) { - $latest = db_fetch_object(db_query_range("SELECT file_path, version, file_date FROM {project_release_nodes} p INNER JOIN {node} n ON p.nid = n.nid INNER JOIN {term_node} t ON p.nid = t.nid LEFT JOIN {project_release_supported_versions} prsv ON p.pid = prsv.nid AND prsv.tid = t.tid AND prsv.major = p.version_major WHERE p.pid = %d AND t.tid = %d AND prsv.supported = 1 AND n.status = 1 ORDER BY prsv.nid DESC, p.rebuild ASC, p.version_major ASC, p.version_minor DESC, p.version_patch DESC, p.file_date DESC", $project->nid, $version, 0, 1)); - $project->file_path = $latest->file_path; - $project->version = $latest->version; - } - - $project->links = array(); - if ($version != -1) { - if ($project->file_path) { - $project->links['project_download'] = theme('project_release_download_link', $project->file_path, t('Download'), 'array'); - } - } - else { - $project->download_table = theme('project_release_table_overview', $project, 'recommended', 'all', t('Version'), FALSE); - } - - $project->links['project_more_info'] = array( - 'title' => t('Find out more'), - 'href' => "node/$project->nid", - ); - if ($project->issues) { - $project->links['project_issues'] = array( - 'title' => t('Bugs and feature requests'), - 'href' => "project/issues/$project->nid", - ); - } - if (module_invoke($module, 'project_sort_methods', 'group by date', $sort_method) && $date = _project_date($project->changed)) { - $projects .= "

$date

"; - } - $project->class = ($class == 'even') ? 'odd': 'even'; - $projects .= theme('project_summary', $project); - $class = $project->class; - } - - $output .= '
' . $projects . '
'; - - if (!empty($pager)) { - $output .= theme('pager', NULL, variable_get('project_browse_nodes', 30)); - } - return $output; +// global $form_values; +// +// project_project_set_breadcrumb(); +// $sort_methods = module_invoke_all('project_sort_methods', 'methods'); +// +// $output = ''; +// if (module_exists('project_release') && variable_get('project_release_browse_versions', 0)) { +// $version_form = drupal_get_form('project_release_version_filter_form'); +// $output .= $version_form; +// // Read in requested version, if any. +// $version = isset($_SESSION['project_version']) ? $_SESSION['project_version'] : variable_get('project_release_overview', -1); +// } +// +// // If browsing by taxonomy, only fetch projects for this term. +// if (project_use_taxonomy()) { +// $vid = _project_get_vid(); +// if ($termname) { +// +// $type = db_fetch_object(db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_hierarchy} th ON t.tid = th.tid WHERE t.vid = %d AND th.parent = 0 AND t.name = '%s'", 't', 'tid'), $vid, $termname)); +// // Bad project category passed, return page not found. +// if (!$type) { +// return drupal_not_found(); +// } +// if (!$sort_method) { +// // For the default, we use the overall default if enabled for this term, and if not we use the first enabled method. +// $term_methods = array_filter(variable_get('project_sort_method_used_' . $type->tid, array_keys($sort_methods))); +// $sort_method = in_array(variable_get('project_sort_method', 'category'), $term_methods) ? variable_get('project_sort_method', 'category') : array_shift($term_methods); +// } +// +// if ($type->description) { +// $output .= '

' . filter_xss($type->description) . '

'; +// } +// +// $module = $sort_methods[$sort_method]; +// // Bad sort method passed, return page not found. +// if (!isset($module)) { +// return drupal_not_found(); +// } +// if (module_invoke($module, 'project_sort_methods', 'set term', $sort_method)) { +// $tree = taxonomy_get_tree(_project_get_vid(), $type->tid); +// $terms = array(); +// if ($tree) { +// $tids = array(); +// if (variable_get('project_release_browse_versions', 0)) { +// $version_params = array(); +// if ($version != -1) { +// $version_where = 'tr.tid = %d'; +// $version_params[] = $version; +// } +// else { +// $placeholders = array(); +// $active_tids = project_release_compatibility_list(); +// foreach ($active_tids as $tid => $api_term) { +// $placeholders[] = '%d'; +// $version_params[] = $tid; +// } +// $version_where = 'tr.tid IN ('. implode(',', $placeholders) .')'; +// } +// // Find all terms associated with the requested version. +// $result = db_query("SELECT tp.tid, COUNT(DISTINCT(n.nid)) AS count FROM {term_node} tp INNER JOIN {project_release_nodes} p ON tp.nid = p.pid INNER JOIN {node} n ON n.nid = p.pid INNER JOIN {term_node} tr ON tr.nid = p.nid WHERE $version_where AND (n.status = 1) GROUP BY tp.tid", $version_params); +// $tids = array(); +// while ($item = db_fetch_object($result)) { +// $tids[$item->tid] = $item->count; +// } +// } +// foreach ($tree as $cterm) { +// if (!variable_get('project_release_browse_versions', 0) || ($version == -1) || array_key_exists($cterm->tid, $tids)) { +// if ($tids[$cterm->tid]) { +// $cterm->count = $tids[$cterm->tid]; +// } +// else { +// // We don't use taxonomy_term_count_nodes() because it includes child terms' counts. +// $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 AND t.tid = %d GROUP BY t.tid'), $cterm->tid); +// $term = db_fetch_object($result); +// $cterm->count = $term->c; +// } +// $terms[] = $cterm; +// } +// } +// } +// +// // Look for a specific category term. +// if ($arg = arg(3)) { +// // Bad term, return page not found. +// if (!($term = taxonomy_get_term($arg))) { +// return drupal_not_found(); +// } +// } +// } +// // The sorting method is not supported by the module, so any term passed is invalid. +// // Return page not found if one is found. +// elseif (arg(3)) { +// return drupal_not_found(); +// } +// +// // Set the default elements that will be used to construct the SQL statement. +// $sql_elements = project_empty_query(); +// $sql_elements['fields']['pieces'] = array( +// 'DISTINCT(n.nid)', +// 'n.title', +// 'n.sticky', +// 'n.type', +// 'nr.teaser', +// 'nr.format', +// ); +// $sql_elements['from']['pieces'] = array( +// '{node} n ' +// ); +// $sql_elements['joins']['pieces'] = array( +// 'INNER JOIN {node_revisions} nr ON n.vid = nr.vid', +// 'INNER JOIN {project_projects} p ON n.nid = p.nid', +// 'LEFT JOIN {term_node} r ON n.nid = r.nid' +// ); +// $sql_elements['wheres']['pieces'] = array( +// 'n.status = 1', +// 'r.tid = %d' +// ); +// $sql_elements['parameters']['pieces'] = array( +// isset($term) ? $term->tid : $type->tid +// ); +// +// // If the site has enabled issue tracking via the project_issue +// // module, we want to add 1 more field and JOIN to our query so +// // we can provide the link for "Bugs and feature requests"... +// if (module_exists('project_issue')) { +// $sql_elements['fields']['pieces'][] = 'pip.issues'; +// $sql_elements['joins']['pieces'][] = 'INNER JOIN {project_issue_projects} pip ON n.nid = pip.nid'; +// } +// +// // Only the 'pieces' are returned; the prefix and glue elements remain unchanged. +// $sql_settings = module_invoke($module, 'project_sort_methods', 'sql_settings', $sort_method); +// if (empty($sql_settings)) { +// $sql_settings = array(); +// } +// +// if (module_exists('project_release')) { +// $project_release_sql = array( +// 'joins' => array('INNER JOIN {project_release_projects} prp ON n.nid = prp.nid'), +// 'wheres' => array('prp.releases = 1'), +// ); +// $sql_settings = array_merge_recursive($sql_settings, $project_release_sql); +// } +// +// if (variable_get('project_release_browse_versions', 0)) { +// $release_settings = array( +// 'fields' => array('prn.file_path', 'prn.version', 'MAX(prn.file_date) AS changed', 'COUNT(*) AS release_count'), +// 'group_bys' => array('n.nid'), +// ); +// $release_settings['joins'] = array( +// 'INNER JOIN {project_release_nodes} prn ON n.nid = prn.pid', +// 'INNER JOIN {term_node} tr ON tr.nid = prn.nid', +// 'INNER JOIN {node} rn ON rn.nid = prn.nid', +// ); +// $release_settings['wheres'][] = 'rn.status = 1'; +// if ($version != -1) { +// $release_settings['joins'][] = 'INNER JOIN {project_release_supported_versions} prsv ON prsv.nid = p.nid AND prsv.tid = tr.tid'; +// $release_settings['wheres'][] = 'tr.tid = %d'; +// $release_settings['wheres'][] = 'prsv.supported = 1'; +// $release_settings['parameters'][] = $version; +// } +// else { +// $placeholders = array(); +// $active_tids = project_release_compatibility_list(); +// foreach ($active_tids as $tid => $compatibility_term) { +// $placeholders[] = '%d'; +// $release_settings['parameters'][] = $tid; +// } +// $where = 'tr.tid IN ('. implode(',', $placeholders) .')'; +// $release_settings['wheres'][] = $where; +// +// // We need to grab the uid for the project node, so +// // that node_access() will work properly without a full +// // node_load() when we're generating the download table in +// // project_release_table(). +// $release_settings['fields'][] = 'n.uid'; +// } +// $sql_settings = array_merge_recursive($sql_settings, $release_settings); +// } +// +// // Merge in $sql_elements +// if (!empty($sql_settings)) { +// foreach(array_keys($sql_settings) as $key) { +// $sql_elements[$key]['pieces'] = array_merge($sql_elements[$key]['pieces'], $sql_settings[$key]); +// $sql_elements[$key]['pieces'] = array_unique($sql_elements[$key]['pieces']); +// } +// } +// +// $parameters = $sql_elements['parameters']['pieces']; +// +// $sql = project_build_query($sql_elements); +// +// $pager = module_invoke($module, 'project_sort_methods', 'pager', $sort_method); +// if ($pager) { +// $first_field = array_shift($sql_elements['fields']['pieces']); +// if (count($sql_elements['group_bys']['pieces'])) { +// $first_field = 'DISTINCT(' . $sql_elements['group_bys']['pieces'][0] . ')'; +// $sql_elements['group_bys']['pieces'] = array(); +// } +// $sql_elements['fields']['pieces'] = array("COUNT($first_field)"); +// // ORDER BY can screw up COUNT(DISTINCT), and we don't care +// // about the order for the count query. +// unset($sql_elements['order_bys']); +// $count_query = project_build_query($sql_elements); +// $result = pager_query($sql, variable_get('project_browse_nodes', 30), 0, $count_query, $parameters); +// } +// else { +// $result = db_query($sql, $parameters); +// } +// +// // If we've just switched versions, we may have a term requested but no matching projects. +// // In that case, we returned an uncollapsed fieldset. +// if (module_invoke($module, 'project_sort_methods', 'set term', $sort_method)) { +// $output .= theme('fieldset', array('#title' => t('Categories'), '#collapsible' => TRUE, '#collapsed' => (arg(3) && db_num_rows($result)) ? TRUE : FALSE, '#children' => theme('project_term_list', $terms, "project/$termname/$sort_method"))); +// if (!arg(3) || !db_num_rows($result)) { +// return $output; +// } +// drupal_set_title(t('@project_type: %category', array('@project_type' => $type->name, '%category' => $term->name))); +// } +// else { +// drupal_set_title(check_plain($type->name)); +// } +// } +// // If taxonomy is enabled but no termname is selected, show a list of terms to choose from. +// else { +// $tree = taxonomy_get_tree($vid, 0, -1, 1); +// $items = array(); +// foreach ($tree as $term) { +// $items[] = theme('project_type', $term); +// } +// drupal_set_title(t('Project types')); +// return theme('item_list', $items); +// } +// } +// // If taxonomy is not enabled, fetch all projects +// else { +// // Any terms passed without taxonomy module enabled are bogus -- return page not found. +// if (isset($termname)) { +// return drupal_not_found(); +// } +// // If the site has enabled issue tracking via the project_issue +// // module, we want to add 1 more field and JOIN to our query so +// // we can provide the link for "Bugs and feature requests"... +// if (module_exists('project_issue')) { +// $ISSUES = ', pip.issues'; +// $ISSUE_JOIN ='INNER JOIN {project_issue_projects} pip ON n.nid = pip.nid'; +// } +// $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, nr.teaser, nr.format$ISSUES FROM {node} n INNER JOIN {node_revisions} nr ON n.vid = nr.vid $ISSUE_JOIN WHERE n.status = 1 AND n.type = 'project_project' ORDER BY n.title ASC")); +// } +// $projects = ''; +// $class = 'even'; +// while ($project = db_fetch_object($result)) { +// $project->body = check_markup($project->teaser, $project->format, FALSE); +// if (module_exists('taxonomy')) { +// $project->taxonomy = taxonomy_node_get_terms($project->nid); +// if (isset($type)) { +// // Hide the top-level project type term from the links, but add it to +// // the $project object for theme_project_summary() to use if it wants. +// unset($project->taxonomy[$type->tid]); +// $project->term = $termname; +// } +// $project->terms = taxonomy_link('taxonomy terms', $project); +// } +// +// // Make sure we have the latest release +// if (isset($project->release_count) && $project->release_count > 1 && $version != -1) { +// $latest = db_fetch_object(db_query_range("SELECT file_path, version, file_date FROM {project_release_nodes} p INNER JOIN {node} n ON p.nid = n.nid INNER JOIN {term_node} t ON p.nid = t.nid LEFT JOIN {project_release_default_versions} prdv ON p.pid = prdv.nid AND prdv.tid = t.tid AND prdv.major = p.version_major WHERE p.pid = %d AND t.tid = %d AND n.status = 1 ORDER BY prdv.nid DESC, p.rebuild ASC, p.version_major ASC, p.version_minor DESC, p.version_patch DESC, p.file_date DESC", $project->nid, $version, 0, 1)); +// $project->file_path = $latest->file_path; +// $project->version = $latest->version; +// } +// +// $project->links = array(); +// if ($version != -1) { +// if ($project->file_path) { +// $project->links['project_download'] = theme('project_release_download_link', $project->file_path, t('Download'), 'array'); +// } +// } +// else { +// $project->download_table = theme('project_release_table_overview', $project, 'recommended', 'all', t('Version'), FALSE); +// } +// +// $project->links['project_more_info'] = array( +// 'title' => t('Find out more'), +// 'href' => "node/$project->nid", +// ); +// if ($project->issues) { +// $project->links['project_issues'] = array( +// 'title' => t('Bugs and feature requests'), +// 'href' => "project/issues/$project->nid", +// ); +// } +// if (module_invoke($module, 'project_sort_methods', 'group by date', $sort_method) && $date = _project_date($project->changed)) { +// $projects .= "

$date

"; +// } +// $project->class = ($class == 'even') ? 'odd': 'even'; +// $projects .= theme('project_summary', $project); +// $class = $project->class; +// } +// +// $output .= '
' . $projects . '
'; +// +// if (!empty($pager)) { +// $output .= theme('pager', NULL, variable_get('project_browse_nodes', 30)); +// } +// return $output; } /** @@ -888,15 +938,6 @@ function project_empty_query() { ); } -// TODO: this should probably be moved to cvs.module... -function project_user($type, $edit, &$user, $category = NULL) { - if ($type == 'view') { - if ($projects = module_invoke('cvs', 'get_contributed_projects', $user->uid)) { - return array(t('Projects') => $projects); - } - } -} - /** * Provide settings data related to methods for sorting projects. * @@ -1001,13 +1042,20 @@ function _project_date($timestamp) { */ function project_projects_select_options(&$project_urls, $issues = TRUE, $key_prefix = NULL) { $projects = array(); + $ISSUE_JOIN = ''; + $ISSUE_WHERE = ''; + $args_use_taxonomy = array(1, 0); // n.status, h.parent + $args_no_taxonomy = array(1); // n.status if ($issues && module_exists('project_issue')) { $ISSUE_JOIN ='INNER JOIN {project_issue_projects} pip ON n.nid = pip.nid'; - $ISSUE_WHERE = 'AND pip.issues = 1'; + $ISSUE_WHERE = 'AND pip.issues = %d'; + $args_use_taxonomy[] = 1; + $args_no_taxonomy[] = 1; } if (project_use_taxonomy()) { $vid = _project_get_vid(); - $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, d.name, p.uri FROM {project_projects} p INNER JOIN {node} n ON n.nid = p.nid $ISSUE_JOIN LEFT JOIN {term_node} t ON t.nid = n.nid INNER JOIN {term_data} d ON t.tid = d.tid INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE n.status = 1 $ISSUE_WHERE AND d.vid = %d AND h.parent = 0 GROUP BY n.nid, n.title, d.name, p.uri, d.weight ORDER BY d.weight, n.title"), $vid); + $args_use_taxonomy[] = $vid; + $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, d.name, p.uri FROM {project_projects} p INNER JOIN {node} n ON n.nid = p.nid $ISSUE_JOIN LEFT JOIN {term_node} t ON t.vid = n.vid INNER JOIN {term_data} d ON t.tid = d.tid INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE n.status = %d AND h.parent = %d $ISSUE_WHERE AND d.vid = %d GROUP BY n.nid, n.title, d.name, p.uri, d.weight ORDER BY d.weight, n.title"), $args_use_taxonomy); while ($project = db_fetch_object($result)) { if (isset($project->name)) { if (!isset($projects[$project->name])) { @@ -1024,7 +1072,7 @@ function project_projects_select_options } } else { - $result = db_query(db_rewrite_sql("SELECT n.nid, p.uri, n.title FROM {project_projects} p INNER JOIN {node} n ON n.nid = p.nid $ISSUE_JOIN WHERE n.status = 1 $ISSUE_WHERE ORDER BY n.title")); + $result = db_query(db_rewrite_sql("SELECT n.nid, p.uri, n.title FROM {project_projects} p INNER JOIN {node} n ON n.nid = p.nid $ISSUE_JOIN WHERE n.status = %d $ISSUE_WHERE ORDER BY n.title"), $args_no_taxonomy); while ($project = db_fetch_object($result)) { $projects[$key_prefix . $project->nid] = $project->title; if (is_array($project_urls)) { @@ -1051,9 +1099,9 @@ function project_quick_navigate_form() { return $form; } -function project_quick_navigate_form_submit($form_id, $form_values) { - if (!empty($form_values['project_goto']) && (string)$form_values['project_goto'] != '0') { - drupal_goto($form_values['project_goto']); +function project_quick_navigate_form_submit($form, &$form_state) { + if (!empty($form_state['values']['project_goto']) && (string)$form_state['values']['project_goto'] != '0') { + drupal_goto($form_state['values']['project_goto']); } } @@ -1063,7 +1111,7 @@ function theme_project_term_list($terms, $depth = 0; $output = "\n\n"; @@ -1137,7 +1185,7 @@ function project_autocomplete($string) { $t = $project->title; $matches[$prefix . $t] = check_plain($project->title); } - print drupal_to_js($matches); +// print drupal_to_js($matches); exit(); } } @@ -1161,3 +1209,32 @@ function project_use_cvs($project) { } } +/** + * Implementation of hook_theme(). + */ +function project_theme() { + return array( + 'project_term_list' => array( + 'arguments' => array( + 'terms' => NULL, + 'path' => NULL, + ), + ), + 'project_type' => array( + 'arguments' => array( + 'term' => NULL, + ), + ), + 'project_summary' => array( + 'arguments' => array( + 'project' => NULL, + ), + ), + 'project_project_node_form_taxonomy' => array( + 'arguments' => array( + 'form' => NULL, + ), + ), + ); +} + Index: project.views.inc =================================================================== RCS file: project.views.inc diff -N project.views.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ project.views.inc 20 Jun 2008 23:17:53 -0000 @@ -0,0 +1,285 @@ + array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + + // uri + $data['project_projects']['uri'] = array( + 'title' => t('Short name'), + 'help' => t('The short name (uri) of a project.'), + 'field' => array( + 'group' => t('Project'), + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // homepage + $data['project_projects']['homepage'] = array( + 'title' => t('Homepage'), + 'help' => t("The project's homepage."), + 'field' => array( + 'group' => t('Project'), + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // changelog + $data['project_projects']['changelog'] = array( + 'title' => t('Changelog'), + 'help' => t("The project's changelog."), + 'field' => array( + 'group' => t('Project'), + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // cvs + $data['project_projects']['cvs'] = array( + 'title' => t('CVS directory'), + 'help' => t("The project's cvs directory."), + 'field' => array( + 'group' => t('Project'), + //'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // demo + $data['project_projects']['demo'] = array( + 'title' => t('Demonstration'), + 'help' => t('Link to a demonstration of the project.'), + 'field' => array( + 'group' => t('Project'), + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // documentation + $data['project_projects']['documentation'] = array( + 'title' => t('Documentation'), + 'help' => t("The project's documentation."), + 'field' => array( + 'group' => t('Project'), + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // screenshots + $data['project_projects']['screenshots'] = array( + 'title' => t('Screenshots'), + 'help' => t("The project's screenshots."), + 'field' => array( + 'group' => t('Project'), + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // license + $data['project_projects']['license'] = array( + 'title' => t('License'), + 'help' => t('The license used for the project.'), + 'field' => array( + 'group' => t('Project'), + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + return $data; +} + + +/** + * Implementation of hook_views_plugins(). + */ +function project_views_plugins() { + return array( + 'module' => 'project', + //'style' => array( + // 'project_overview' => array( + // 'title' => t('Project overview'), + // 'help' => t('Displays the default summary view'), + // 'handler' => 'views_plugin_style_summary', + // 'theme' => 'project_view_plugin_overview', + // 'type' => 'summary', // only shows up as a summary style + // 'uses options' => TRUE, + // ), + //), + 'argument validator' => array( + 'project_term' => array( + 'title' => t('Project type term'), + 'handler' => 'project_views_plugin_argument_validate_project_type_term', + ), + ), + ); +} + + + +// +///** +// * Display a view as a project_overview style. +// */ +//function template_preprocess_project_view_plugin_overview(&$vars) { +// $view = $vars['view']; +// $result = $view->result; +// $options = $view->style_handler->options; +// $handler = $view->style_handler; +// +// $columns = $options['columns']; +// +// $rows = array(); +// +// if ($options['alignment'] == 'horizontal') { +// $row = array(); +// foreach ($vars['rows'] as $count => $item) { +// $row[] = $item; +// if (($count + 1) % $columns == 0) { +// $rows[] = $row; +// $row = array(); +// } +// } +// if ($row) { +// $rows[] = $row; +// } +// } +// else { +// $num_rows = floor(count($vars['rows']) / $columns); +// // The remainders are the 'odd' columns that are slightly longer. +// $remainders = count($vars['rows']) % $columns; +// $row = 0; +// $col = 0; +// foreach ($vars['rows'] as $count => $item) { +// $rows[$row][$col] = $item; +// $row++; +// +// if (!$remainders && $row == $num_rows) { +// $row = 0; +// $col++; +// } +// else if ($remainders && $row == $num_rows + 1) { +// $row = 0; +// $col++; +// $remainders--; +// } +// } +// } +// $vars['rows'] = $rows; +//} + +/** + * @} + */ \ No newline at end of file Index: project.views_default.inc =================================================================== RCS file: project.views_default.inc diff -N project.views_default.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ project.views_default.inc 20 Jun 2008 23:17:53 -0000 @@ -0,0 +1,671 @@ +name = 'project_types'; + $view->description = 'A list of project types with descriptions.'; + $view->tag = 'project'; + $view->view_php = ''; + $view->base_table = 'term_data'; + $view->is_cacheable = '0'; + $view->api_version = 2; + $view->disabled = FALSE; // Edit this to true to make a default view disabled initially + $view->display = array(); + $display = new views_display; + $display->id = 'default'; + $display->display_title = 'Defaults'; + $display->display_plugin = 'default'; + $display->position = '1'; + $display->display_options = array( + 'style_plugin' => 'list', + 'style_options' => array( + 'type' => 'ul', + ), + 'row_plugin' => 'fields', + 'row_options' => array(), + 'relationships' => array(), + 'fields' => array( + 'name' => array( + 'id' => 'name', + 'table' => 'term_data', + 'field' => 'name', + 'label' => 'Term', + 'relationship' => 'none', + 'link_to_taxonomy' => 1, + ), + 'description' => array( + 'id' => 'description', + 'table' => 'term_data', + 'field' => 'description', + 'label' => 'Term description', + 'relationship' => 'none', + ), + ), + 'sorts' => array(), + 'arguments' => array(), + 'filters' => array( + 'vid' => array( + 'id' => 'vid', + 'table' => 'term_data', + 'field' => 'vid', + 'operator' => 'in', + 'value' => array( + '1' => 1, + ), + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Expose', + ), + ), + 'tid' => array( + 'id' => 'tid', + 'table' => 'term_node', + 'field' => 'tid', + 'operator' => 'or', + 'value' => array( + '1' => '1', + '2' => '2', + '3' => '3', + '4' => '4', + '5' => '5', + '6' => '6', + ), + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'type' => 'select', + 'vid' => '1', + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Expose', + ), + 'reduce_duplicates' => 0, + ), + ), + 'items_per_page' => 10, + 'distinct' => 1, + ); + $view->display['default'] = $display; + $display = new views_display; + $display->id = 'page'; + $display->display_title = 'Page'; + $display->display_plugin = 'page'; + $display->position = '2'; + $display->display_options = array( + 'defaults' => array( + 'access' => TRUE, + 'title' => TRUE, + 'header' => TRUE, + 'header_format' => TRUE, + 'header_empty' => TRUE, + 'footer' => TRUE, + 'footer_format' => TRUE, + 'footer_empty' => TRUE, + 'empty' => TRUE, + 'empty_format' => TRUE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'offset' => TRUE, + 'use_pager' => TRUE, + 'pager_element' => TRUE, + 'use_more' => TRUE, + 'distinct' => TRUE, + 'link_display' => TRUE, + 'style_plugin' => TRUE, + 'style_options' => TRUE, + 'row_plugin' => TRUE, + 'row_options' => TRUE, + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => TRUE, + 'arguments' => TRUE, + 'filters' => TRUE, + ), + 'relationships' => array(), + 'fields' => array(), + 'sorts' => array(), + 'arguments' => array(), + 'filters' => array(), + 'path' => 'project', + 'menu' => array( + 'type' => 'normal', + 'title' => 'Projects', + 'weight' => '0', + ), + ); + $view->display['page'] = $display; + $views[$view->name] = $view; + + + $view = new view; + $view->name = 'project_overview'; + $view->description = 'A view for browsing projects.'; + $view->tag = 'project'; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = '0'; + $view->api_version = 2; + $view->disabled = FALSE; // Edit this to true to make a default view disabled initially + $view->display = array(); + $display = new views_display; + $display->id = 'default'; + $display->display_title = 'Defaults'; + $display->display_plugin = 'default'; + $display->position = '1'; + $display->display_options = array( + 'style_plugin' => 'list', + 'style_options' => array( + 'type' => 'ul', + ), + 'row_plugin' => 'fields', + 'row_options' => array( + 'inline' => array(), + 'separator' => '', + ), + 'relationships' => array(), + 'fields' => array( + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => 'Title', + 'relationship' => 'none', + 'link_to_node' => 1, + ), + 'uri_2' => array( + 'id' => 'uri_2', + 'table' => 'project_projects', + 'field' => 'uri', + 'label' => 'Short name', + 'relationship' => 'none', + 'link_to_node' => 1, + ), + 'demo' => array( + 'id' => 'demo', + 'table' => 'project_projects', + 'field' => 'demo', + 'label' => 'Demonstration', + ), + 'documentation' => array( + 'id' => 'documentation', + 'table' => 'project_projects', + 'field' => 'documentation', + 'label' => 'Documentation', + 'relationship' => 'none', + 'display_as_link' => 1, + ), + 'homepage' => array( + 'id' => 'homepage', + 'table' => 'project_projects', + 'field' => 'homepage', + 'label' => 'Homepage', + 'relationship' => 'none', + 'display_as_link' => 1, + ), + 'license' => array( + 'id' => 'license', + 'table' => 'project_projects', + 'field' => 'license', + 'label' => 'License', + 'relationship' => 'none', + 'display_as_link' => 1, + ), + 'screenshots' => array( + 'id' => 'screenshots', + 'table' => 'project_projects', + 'field' => 'screenshots', + 'label' => 'Screenshots', + ), + ), + 'sorts' => array( + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'order' => 'ASC', + 'relationship' => 'none', + ), + ), + 'arguments' => array( + 'name' => array( + 'id' => 'name', + 'table' => 'term_data', + 'field' => 'name', + 'default_action' => 'summary asc', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => 1, + 'override' => 0, + 'items_per_page' => '25', + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '%1', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'glossary' => 0, + 'limit' => '0', + 'case' => 'none', + 'path_case' => 'none', + 'transform_dash' => 0, + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'project_project' => 0, + 'book' => 0, + 'page' => 0, + 'story' => 0, + ), + 'validate_argument_php' => '', + 'add_table' => 0, + 'require_value' => 0, + ), + ), + 'filters' => array( + 'type' => array( + 'id' => 'type', + 'table' => 'node', + 'field' => 'type', + 'operator' => 'in', + 'value' => array( + 'project_project' => 'project_project', + ), + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Expose', + ), + ), + 'status' => array( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => 1, + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Expose', + ), + ), + 'tid' => array( + 'id' => 'tid', + 'table' => 'term_node', + 'field' => 'tid', + 'operator' => 'or', + 'value' => array(), + 'group' => 0, + 'exposed' => TRUE, + 'expose' => array( + 'operator' => '', + 'identifier' => 'api', + 'label' => 'API Version', + 'optional' => 1, + 'single' => 0, + 'remember' => 1, + ), + 'type' => 'select', + 'vid' => '2', + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Hide', + ), + 'reduce_duplicates' => 0, + ), + ), + 'items_per_page' => 30, + 'use_pager' => '1', + 'pager_element' => 0, + 'offset' => 0, + 'access' => array( + 'type' => 'perm', + 'role' => array( + '3' => 0, + '1' => 0, + '2' => 0, + '6' => 0, + '5' => 0, + '4' => 0, + '7' => 0, + ), + 'perm' => 'access projects', + ), + 'title' => 'Default title', + ); + $view->display['default'] = $display; + $display = new views_display; + $display->id = 'page'; + $display->display_title = 'Page: Browse by category'; + $display->display_plugin = 'page'; + $display->position = '2'; + $display->display_options = array( + 'defaults' => array( + 'access' => TRUE, + 'title' => TRUE, + 'header' => FALSE, + 'header_format' => FALSE, + 'header_empty' => FALSE, + 'footer' => TRUE, + 'footer_format' => TRUE, + 'footer_empty' => TRUE, + 'empty' => TRUE, + 'empty_format' => TRUE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'offset' => TRUE, + 'use_pager' => TRUE, + 'pager_element' => TRUE, + 'use_more' => TRUE, + 'distinct' => TRUE, + 'link_display' => TRUE, + 'style_plugin' => TRUE, + 'style_options' => TRUE, + 'row_plugin' => TRUE, + 'row_options' => TRUE, + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => TRUE, + 'arguments' => FALSE, + 'filters' => TRUE, + ), + 'relationships' => array(), + 'fields' => array(), + 'sorts' => array(), + 'arguments' => array( + 'tid' => array( + 'id' => 'tid', + 'table' => 'term_node', + 'field' => 'tid', + 'default_action' => 'not found', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '%1', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'taxonomy_term', + 'validate_fail' => 'not found', + 'break_phrase' => 0, + 'add_table' => 1, + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'project_project' => 0, + 'book' => 0, + 'page' => 0, + 'story' => 0, + ), + 'validate_argument_vocabulary' => array( + '1' => 1, + '3' => 0, + '2' => 0, + '4' => 0, + ), + 'validate_argument_type' => 'convert', + 'validate_argument_php' => '', + 'require_value' => 0, + 'reduce_duplicates' => 0, + ), + 'tid_1' => array( + 'id' => 'tid_1', + 'table' => 'term_node', + 'field' => 'tid', + 'default_action' => 'not found', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '%1: %2', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'taxonomy_term', + 'validate_fail' => 'not found', + 'break_phrase' => 0, + 'add_table' => 1, + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'project_project' => 0, + 'book' => 0, + 'page' => 0, + 'story' => 0, + ), + 'validate_argument_vocabulary' => array( + '1' => 1, + '3' => 0, + '2' => 0, + '4' => 0, + ), + 'validate_argument_type' => 'tid', + 'validate_argument_php' => '', + 'require_value' => 0, + 'reduce_duplicates' => 0, + ), + ), + 'path' => 'project/%/category/%', + 'menu' => array( + 'type' => 'default tab', + 'title' => 'Browse by category', + 'weight' => '0', + ), + 'tab_options' => array( + 'type' => 'normal', + 'title' => 'Project modules', + 'weight' => '0', + ), + 'header' => 'this is the header', + 'header_format' => '1', + 'header_empty' => 0, + ); + $view->display['page'] = $display; + $display = new views_display; + $display->id = 'page_1'; + $display->display_title = 'Page: Browse by date'; + $display->display_plugin = 'page'; + $display->position = '3'; + $display->display_options = array( + 'defaults' => array( + 'access' => TRUE, + 'title' => TRUE, + 'header' => TRUE, + 'header_format' => TRUE, + 'header_empty' => TRUE, + 'footer' => TRUE, + 'footer_format' => TRUE, + 'footer_empty' => TRUE, + 'empty' => TRUE, + 'empty_format' => TRUE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'offset' => TRUE, + 'use_pager' => TRUE, + 'pager_element' => TRUE, + 'use_more' => TRUE, + 'distinct' => TRUE, + 'link_display' => TRUE, + 'style_plugin' => TRUE, + 'style_options' => TRUE, + 'row_plugin' => TRUE, + 'row_options' => TRUE, + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => FALSE, + 'arguments' => TRUE, + 'filters' => TRUE, + ), + 'relationships' => array(), + 'fields' => array(), + 'sorts' => array( + 'changed' => array( + 'id' => 'changed', + 'table' => 'node', + 'field' => 'changed', + 'order' => 'DESC', + 'granularity' => 'day', + 'relationship' => 'none', + ), + ), + 'arguments' => array(), + 'filters' => array(), + 'path' => 'project/%/date', + 'menu' => array( + 'type' => 'tab', + 'title' => 'Browse by date', + 'weight' => '0', + ), + ); + $view->display['page_1'] = $display; + $display = new views_display; + $display->id = 'page_2'; + $display->display_title = 'Page: Browse by name'; + $display->display_plugin = 'page'; + $display->position = '4'; + $display->display_options = array( + 'defaults' => array( + 'access' => TRUE, + 'title' => TRUE, + 'header' => TRUE, + 'header_format' => TRUE, + 'header_empty' => TRUE, + 'footer' => TRUE, + 'footer_format' => TRUE, + 'footer_empty' => TRUE, + 'empty' => TRUE, + 'empty_format' => TRUE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'offset' => TRUE, + 'use_pager' => TRUE, + 'pager_element' => TRUE, + 'use_more' => TRUE, + 'distinct' => TRUE, + 'link_display' => TRUE, + 'style_plugin' => TRUE, + 'style_options' => TRUE, + 'row_plugin' => TRUE, + 'row_options' => TRUE, + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => FALSE, + 'arguments' => TRUE, + 'filters' => TRUE, + ), + 'relationships' => array(), + 'fields' => array(), + 'sorts' => array( + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'order' => 'ASC', + 'relationship' => 'none', + ), + ), + 'arguments' => array(), + 'filters' => array(), + 'path' => 'project/%/name', + 'menu' => array( + 'type' => 'tab', + 'title' => 'Browse by name', + 'weight' => '0', + ), + ); + $view->display['page_2'] = $display; + $display = new views_display; + $display->id = 'attachment'; + $display->display_title = 'Attachment'; + $display->display_plugin = 'attachment'; + $display->position = '5'; + $display->display_options = array( + 'defaults' => array( + 'access' => TRUE, + 'title' => TRUE, + 'header' => TRUE, + 'header_format' => TRUE, + 'header_empty' => TRUE, + 'footer' => TRUE, + 'footer_format' => TRUE, + 'footer_empty' => TRUE, + 'empty' => TRUE, + 'empty_format' => TRUE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'offset' => TRUE, + 'use_pager' => TRUE, + 'pager_element' => TRUE, + 'use_more' => TRUE, + 'distinct' => TRUE, + 'link_display' => TRUE, + 'style_plugin' => TRUE, + 'style_options' => TRUE, + 'row_plugin' => TRUE, + 'row_options' => TRUE, + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => TRUE, + 'arguments' => TRUE, + 'filters' => TRUE, + ), + 'relationships' => array(), + 'fields' => array(), + 'sorts' => array(), + 'arguments' => array(), + 'filters' => array(), + 'attachment_position' => 'before', + 'inherit_arguments' => TRUE, + 'displays' => array( + 'default' => 0, + 'page' => 0, + 'page_1' => 0, + 'page_2' => 0, + ), + ); + $view->display['attachment'] = $display; + $views[$view->name] = $view; + + return $views; +} \ No newline at end of file Index: release/package-release-nodes.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/release/package-release-nodes.php,v retrieving revision 1.29 diff -u -p -r1.29 package-release-nodes.php --- release/package-release-nodes.php 29 Mar 2008 08:33:35 -0000 1.29 +++ release/package-release-nodes.php 20 Jun 2008 23:17:53 -0000 @@ -2,7 +2,7 @@ $project_id)), l(t('view'), 'node/' . $project_id)); + wd_msg("Starting to package snapshot releases for project id: @project_id.", array('@project_id' => $project_id), l(t('view'), 'node/' . $project_id)); } } else { - wd_err(t("ERROR: package_releases() called with unknown type: %type", array('%type' => $type))); + wd_err("ERROR: package_releases() called with unknown type: %type", array('%type' => $type)); return; } $args = array(); + $args[] = 1; // Account for np.status = 1. + $args[] = 1; // Account for prp.releases = 1. + $args[] = (int)_project_release_get_api_vid(); if (!empty($project_id)) { $where .= ' AND prn.pid = %d'; - $args[] = $project_id; + $where_args[] = $project_id; } - $vid = (int)_project_release_get_api_vid(); - - $query = db_query("SELECT pp.uri, prn.nid, prn.pid, prn.tag, prn.version, prn.version_major, td.tid, c.directory, c.rid FROM {project_release_nodes} prn $rel_node_join INNER JOIN {term_node} tn ON prn.nid = tn.nid INNER JOIN {term_data} td ON tn.tid = td.tid INNER JOIN {project_projects} pp ON prn.pid = pp.nid INNER JOIN {node} np ON prn.pid = np.nid INNER JOIN {project_release_projects} prp ON prp.nid = prn.pid INNER JOIN {cvs_projects} c ON prn.pid = c.nid WHERE np.status = 1 AND prp.releases = 1 AND td.vid = $vid " . $where . ' ORDER BY pp.uri', $args); + $args = $args + $where_args; + $query = db_query("SELECT pp.uri, prn.nid, prn.pid, prn.tag, prn.version, prn.version_major, td.tid, c.directory, c.rid FROM {project_release_nodes} prn $rel_node_join INNER JOIN {term_node} tn ON prn.nid = tn.nid INNER JOIN {term_data} td ON tn.tid = td.tid INNER JOIN {project_projects} pp ON prn.pid = pp.nid INNER JOIN {node} np ON prn.pid = np.nid INNER JOIN {project_release_projects} prp ON prp.nid = prn.pid INNER JOIN {cvs_projects} c ON prn.pid = c.nid WHERE np.status = %d AND prp.releases = %d AND td.vid = %d " . $where . ' ORDER BY pp.uri', $args); $num_built = 0; $num_considered = 0; @@ -242,10 +250,10 @@ function package_releases($type, $projec } if ($num_built || $type == 'branch') { if (!empty($project_id)) { - wd_msg(t("Done packaging releases for @uri from !plural: !num_built built, !num_considered considered.", array('@uri' => $uri, '!plural' => $plural, '!num_built' => $num_built, '!num_considered' => $num_considered))); + wd_msg("Done packaging releases for @uri from !plural: !num_built built, !num_considered considered.", array('@uri' => $uri, '!plural' => $plural, '!num_built' => $num_built, '!num_considered' => $num_considered)); } else { - wd_msg(t("Done packaging releases from !plural: !num_built built, !num_considered considered.", array('!plural' => $plural, '!num_built' => $num_built, '!num_considered' => $num_considered))); + wd_msg("Done packaging releases from !plural: !num_built built, !num_considered considered.", array('!plural' => $plural, '!num_built' => $num_built, '!num_considered' => $num_considered)); } } @@ -296,7 +304,7 @@ function package_release_core($nid, $uri // Fix any .info files foreach ($info_files as $file) { if (!fix_info_file_version($file, $uri, $version)) { - wd_err(t("ERROR: Failed to update version in %file, aborting packaging", array('%file' => $file)), $view_link); + wd_err("ERROR: Failed to update version in %file, aborting packaging", array('%file' => $file), $view_link); return false; } } @@ -308,7 +316,7 @@ function package_release_core($nid, $uri // As soon as the tarball exists, we want to update the DB about it. package_release_update_node($nid, $file_path); - wd_msg(t("%id has changed, re-packaged.", array('%id' => $id)), $view_link); + wd_msg("%id has changed, re-packaged.", array('%id' => $id), $view_link); // Don't consider failure to remove this directory a build failure. drupal_exec("$rm -rf $tmp_dir/$id"); @@ -350,7 +358,7 @@ function package_release_contrib($nid, $ return false; } if (!is_dir($fulldir)) { - wd_err(t("ERROR: %dir does not exist after cvs export %rev", array('%dir' => $fulldir, '%rev' => $rev)), $view_link); + wd_err("ERROR: %dir does not exist after cvs export %rev", array('%dir' => $fulldir, '%rev' => $rev), $view_link); return false; } if (!drupal_chdir($basedir)) { @@ -370,7 +378,7 @@ function package_release_contrib($nid, $ // Fix any .info files foreach ($info_files as $file) { if (!fix_info_file_version($file, $uri, $version)) { - wd_err(t("ERROR: Failed to update version in %file, aborting packaging", array('%file' => $file)), $view_link); + wd_err("ERROR: Failed to update version in %file, aborting packaging", array('%file' => $file), $view_link); return false; } } @@ -414,7 +422,7 @@ function package_release_contrib($nid, $ // As soon as the tarball exists, update the DB package_release_update_node($nid, $file_path); - wd_msg(t("%id has changed, re-packaged.", array('%id' => $id)), $view_link); + wd_msg("%id has changed, re-packaged.", array('%id' => $id), $view_link); // Don't consider failure to remove this directory a build failure. drupal_exec("$rm -rf $tmp_dir/$basedir/$uri"); @@ -456,7 +464,7 @@ function package_release_contrib_pre_d6_ } } else { - wd_err(t("ERROR: %uri translation does not contain a %uri_po file for version %version, not packaging", array('%uri' => $uri, '%uri_po' => "$uri.po", '%version' => $version)), $view_link); + wd_err("ERROR: %uri translation does not contain a %uri_po file for version %version, not packaging", array('%uri' => $uri, '%uri_po' => "$uri.po", '%version' => $version), $view_link); return FALSE; } @@ -474,7 +482,7 @@ function package_release_contrib_d6_tran // Rename text files to $name[1].$uri.txt so there will be no conflict // with core text files when the package is deployed. if (!rename("$uri/$file", "$uri/$name[1].$uri.txt")) { - wd_err(t("ERROR: Unable to rename text files in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version)), $view_link); + wd_err("ERROR: Unable to rename text files in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version), $view_link); return FALSE; } } @@ -482,7 +490,7 @@ function package_release_contrib_d6_tran // Generate stats information about the .po file handled. if (!drupal_exec("$msgfmt --statistics $uri/$file 2>> $uri/STATUS.$uri.txt")) { - wd_err(t("ERROR: Unable to generate statistics for %file in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version, '%file' => $file)), $view_link); + wd_err("ERROR: Unable to generate statistics for %file in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version, '%file' => $file), $view_link); return FALSE; } @@ -512,11 +520,11 @@ function package_release_contrib_d6_tran // Create target folder and copy file there, while removing fuzzies. $target_dir = dirname($uri_target); if (!is_dir($target_dir) && !mkdir($target_dir, 0777, TRUE)) { - wd_err(t("ERROR: Unable to generate directory structure in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version)), $view_link); + wd_err("ERROR: Unable to generate directory structure in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version), $view_link); return FALSE; } if (!drupal_exec("$msgattrib --no-fuzzy $uri/$file -o $uri_target")) { - wd_err(t("ERROR: Unable to filter fuzzy strings and copying the translation files in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version)), $view_link); + wd_err("ERROR: Unable to filter fuzzy strings and copying the translation files in %uri translation in version %version, not packaging", array('%uri' => $uri, '%version' => $version), $view_link); return FALSE; } @@ -540,13 +548,13 @@ function package_release_contrib_d6_tran function verify_packages($task, $project_id) { global $dest_root; $do_repair = $task == 'repair' ? TRUE : FALSE; - $args = array(); + $args = array(1); $where = ''; if (!empty($project_id)) { $where = ' AND prn.pid = %d'; $args[] = $project_id; } - $query = db_query("SELECT prn.nid, prn.file_path, prn.file_date, prn.file_hash FROM {project_release_nodes} prn INNER JOIN {node} n ON prn.nid = n.nid WHERE n.status = 1 AND prn.file_path <> '' $where", $args); + $query = db_query("SELECT prn.nid, prn.file_path, prn.file_date, prn.file_hash FROM {project_release_nodes} prn INNER JOIN {node} n ON prn.nid = n.nid WHERE n.status = %d AND prn.file_path <> '' $where", $args); while ($release = db_fetch_object($query)) { // Grab all the results into RAM to free up the DB connection for // when we need to update the DB to correct metadata or log messages. @@ -575,7 +583,7 @@ function verify_packages($task, $project if (!is_file($full_path)) { $num_not_exist++; - wd_err(t('WARNING: %file does not exist.', array('%file' => $full_path)), $view_link); + wd_err('WARNING: %file does not exist.', array('%file' => $full_path), $view_link); continue; } $real_date = filemtime($full_path); @@ -603,20 +611,20 @@ function verify_packages($task, $project } if (!$valid_date && !$valid_hash) { - wd_check(t('All file meta data for %file is incorrect: saved date: !db_date (!db_date_raw), real date: !real_date (!real_date_raw); saved md5hash: @db_hash, real md5hash: @real_hash', $variables), $view_link); + wd_check('All file meta data for %file is incorrect: saved date: !db_date (!db_date_raw), real date: !real_date (!real_date_raw); saved md5hash: @db_hash, real md5hash: @real_hash', $variables, $view_link); } else if (!$valid_date) { - wd_check(t('File date for %file is incorrect: saved date: !db_date (!db_date_raw), real date: !real_date (!real_date_raw)', $variables), $view_link); + wd_check('File date for %file is incorrect: saved date: !db_date (!db_date_raw), real date: !real_date (!real_date_raw)', $variables, $view_link); } else { // !$valid_hash - wd_check(t('File md5hash for %file is incorrect: saved: @db_hash, real: @real_hash', $variables), $view_link); + wd_check('File md5hash for %file is incorrect: saved: @db_hash, real: @real_hash', $variables, $view_link); } if (!$do_repair) { $num_need_repair++; } else if (!db_query("UPDATE {project_release_nodes} SET file_hash = '%s', file_date = %d WHERE nid = %d", $real_hash, $real_date, $nid)) { - wd_err(t('ERROR: db_query() failed trying to update metadata for %file', array('%file' => $file_path)), $view_link); + wd_err('ERROR: db_query() failed trying to update metadata for %file', array('%file' => $file_path), $view_link); $num_failed++; } else { @@ -632,21 +640,21 @@ function verify_packages($task, $project '!num_wrong_hash' => $num_wrong_hash, ); if ($num_failed) { - wd_err(t('ERROR: unable to repair !num_failed releases due to db_query() failures.', array('!num_failed' => $num_failed))); + wd_err('ERROR: unable to repair !num_failed releases due to db_query() failures.', array('!num_failed' => $num_failed)); } if ($num_not_exist) { - wd_err(t('ERROR: !num_not_exist files are in the database but do not exist on disk.', array('!num_not_exist' => $num_not_exist))); + wd_err('ERROR: !num_not_exist files are in the database but do not exist on disk.', array('!num_not_exist' => $num_not_exist)); } if ($do_repair) { - wd_check(t('Done checking releases: !num_repaired repaired, !num_wrong_date invalid dates, !num_wrong_hash invalid md5 hashes, !num_considered considered.', $num_vars)); + wd_check('Done checking releases: !num_repaired repaired, !num_wrong_date invalid dates, !num_wrong_hash invalid md5 hashes, !num_considered considered.', $num_vars); } else { if (empty($project_id)) { - wd_check(t('Done checking releases: !num_need_repair need repairing, !num_wrong_date invalid dates, !num_wrong_hash invalid md5 hashes, !num_considered considered.', $num_vars)); + wd_check('Done checking releases: !num_need_repair need repairing, !num_wrong_date invalid dates, !num_wrong_hash invalid md5 hashes, !num_considered considered.', $num_vars); } else { $num_vars['@project_id'] = $project_id; - wd_check(t('Done checking releases for project id @project_id: !num_need_repair need repairing, !num_wrong_date invalid dates, !num_wrong_hash invalid md5 hashes, !num_considered considered.', $num_vars), l(t('view'), 'node/' . $project_id)); + wd_check('Done checking releases for project id @project_id: !num_need_repair need repairing, !num_wrong_date invalid dates, !num_wrong_hash invalid md5 hashes, !num_considered considered.', $num_vars, l(t('view'), 'node/' . $project_id)); } } } @@ -666,7 +674,7 @@ function drupal_exec($cmd) { // Made sure we grab stderr, too... exec("$cmd 2>&1", $output, $rval); if ($rval) { - wd_err(t("ERROR: %cmd failed with status !rval", array('%cmd' => $cmd, '!rval' => $rval)) . '
' . implode("\n", array_map('htmlspecialchars', $output)));
+    wd_err("ERROR: %cmd failed with status !rval" . '
' . implode("\n", array_map('htmlspecialchars', $output)), array('%cmd' => $cmd, '!rval' => $rval));
     return false;
   }
   return true;
@@ -679,7 +687,7 @@ function drupal_exec($cmd) {
  */
 function drupal_chdir($dir) {
   if (!chdir($dir)) {
-    wd_err(t("ERROR: Can't chdir(@dir)", array('@dir' => $dir)));
+    wd_err("ERROR: Can't chdir(@dir)", array('@dir' => $dir));
     return false;
   }
   return true;
@@ -694,31 +702,31 @@ function wprint($var) {
  * Wrapper function for watchdog() to log notice messages. Uses a
  * different watchdog message type depending on the task (branch vs. tag).
  */
-function wd_msg($msg, $link = NULL) {
+function wd_msg($msg, $variables = array(), $link = NULL) {
   global $task;
-  watchdog('package_' . $task, $msg, WATCHDOG_NOTICE, $link);
+  watchdog('package_' . $task, $msg, $variables, WATCHDOG_NOTICE, $link);
   echo $msg ."\n";
 }
 
 /**
  * Wrapper function for watchdog() to log error messages.
  */
-function wd_err($msg, $link = NULL) {
+function wd_err($msg, $variables = array(), $link = NULL) {
   global $wd_err_msg;
   if (!isset($wd_err_msg)) {
     $wd_err_msg = array();
   }
-  watchdog('package_error', $msg, WATCHDOG_ERROR, $link);
-  echo $msg ."\n";
-  $wd_err_msg[] = $msg;
+  watchdog('package_error', $msg, $variables, WATCHDOG_ERROR, $link);
+  echo t($msg, $variables) ."\n";
+  $wd_err_msg[] = t($msg, $variables);
 }
 
 /**
  * Wrapper function for watchdog() to log messages about checking
  * package metadata.
  */
-function wd_check($msg, $link = NULL) {
-  watchdog('package_check', $msg, WATCHDOG_NOTICE, $link);
+function wd_check($msg, $variables = array(), $link = NULL) {
+  watchdog('package_check', $msg, $variables, WATCHDOG_NOTICE, $link);
   echo $msg ."\n";
 }
 
@@ -733,7 +741,7 @@ function initialize_tmp_dir($task) {
   global $tmp_dir, $tmp_root;
 
   if (!is_dir($tmp_root)) {
-    wd_err(t("ERROR: tmp_root: @dir is not a directory", array('@dir' => $tmp_root)));
+    wd_err("ERROR: tmp_root: @dir is not a directory", array('@dir' => $tmp_root));
     exit(1);
   }
 
@@ -743,7 +751,7 @@ function initialize_tmp_dir($task) {
     drupal_exec("$rm -rf $tmp_dir/*");
   }
   else if (!@mkdir($tmp_dir)) {
-    wd_err(t("ERROR: mkdir(@dir) failed", array('@dir' => $tmp_dir)));
+    wd_err("ERROR: mkdir(@dir) failed", array('@dir' => $tmp_dir));
     exit(1);
   }
 }
@@ -783,15 +791,15 @@ function fix_info_file_version($file, $u
   $info .= "\n";
 
   if (!chmod($file, 0644)) {
-    wd_err(t("ERROR: chmod(@file, 0644) failed", array('@file' => $file)));
+    wd_err("ERROR: chmod(@file, 0644) failed", array('@file' => $file));
     return false;
   }
   if (!$info_fd = fopen($file, 'ab')) {
-    wd_err(t("ERROR: fopen(@file, 'ab') failed", array('@file' => $file)));
+    wd_err("ERROR: fopen(@file, 'ab') failed", array('@file' => $file));
     return false;
   }
   if (!fwrite($info_fd, $info)) {
-    wd_err(t("ERROR: fwrite(@file) failed", array('@file' => $file)) . '
' . $info);
+    wd_err("ERROR: fwrite(@file) failed". '
' . $info, array('@file' => $file));
     return false;
   }
   return true;
@@ -817,12 +825,12 @@ function package_release_update_node($ni
   db_query("UPDATE {project_release_nodes} SET file_path = '%s', file_hash = '%s', file_date = %d WHERE nid = %d", $file_path, $file_hash, $file_date, $nid);
 
   // Don't auto-publish security updates.
-  if ($task == 'tag' && db_num_rows(db_query("SELECT * FROM {term_node} WHERE nid = %d AND tid = %d", $nid, SECURITY_UPDATE_TID))) {
-    watchdog('package_security', t("Not auto-publishing security update release."), WATCHDOG_NOTICE, l(t('view'), 'node/'. $nid));
+  if ($task == 'tag' && db_result(db_query("SELECT COUNT(*) FROM {term_node} WHERE nid = %d AND tid = %d", $nid, SECURITY_UPDATE_TID))) {
+    watchdog('package_security', "Not auto-publishing security update release.", array(), WATCHDOG_NOTICE, l(t('view'), 'node/'. $nid));
     return;
   }
 
-  db_query("UPDATE {node} SET status = 1 WHERE nid = %d", $nid);
+  db_query("UPDATE {node} SET status = %d WHERE nid = %d", 1, $nid);
 }
 
 /**
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.13
diff -u -p -r1.13 project-release-create-history.php
--- release/project-release-create-history.php	11 Jun 2008 03:13:12 -0000	1.13
+++ release/project-release-create-history.php	20 Jun 2008 23:17:53 -0000
@@ -2,7 +2,7 @@
  BASE_DIRECTORY)));
+  wd_err("ERROR: History directory (%directory) does not exist, aborting.\n", array('%directory' => BASE_DIRECTORY));
   exit(1);
 }
 
@@ -91,7 +91,7 @@ project_list_generate();
  */
 function project_release_history_generate_all() {
   $api_terms = project_release_compatibility_list();
-  wd_msg(t('Generating XML release history files for all projects.'));
+  wd_msg('Generating XML release history files for all projects.');
 
   // Generate all.xml files for projects with releases.
   $query = db_query("SELECT DISTINCT(pid) FROM {project_release_nodes}");
@@ -104,14 +104,14 @@ function project_release_history_generat
 
   // Generate XML files based on API compatibility.
   $tids = array_keys($api_terms);
-  $placeholders = implode(',', array_fill(0, count($tids), '%d'));
+  $placeholders = db_placeholders($tids);
   $query = db_query("SELECT DISTINCT(prn.pid), tn.tid FROM {project_release_nodes} prn INNER JOIN {term_node} tn ON prn.nid = tn.nid WHERE tn.tid IN ($placeholders)", $tids);
   $i = 0;
   while ($project = db_fetch_object($query)) {
     project_release_history_generate_project_xml($project->pid, $project->tid);
     $i++;
   }
-  wd_msg(t('Completed XML release history files for @num_projects.', array('@num_projects' => format_plural($i, '1 project/version pair', '@count project/version pairs'))));
+  wd_msg('Completed XML release history files for @num_projects.', array('@num_projects' => format_plural($i, '1 project/version pair', '@count project/version pairs')));
 }
 
 /**
@@ -138,7 +138,7 @@ function project_release_history_generat
     // Restrict output to a specific API compatibility term.
     $api_terms = project_release_compatibility_list();
     if (!isset($api_terms[$api_tid])) {
-      wd_err(t('API compatibility term %tid not found.', array('%tid' => $api_tid)));
+      wd_err('API compatibility term %tid not found.', array('%tid' => $api_tid));
       return FALSE;
     }
     $api_version = $api_terms[$api_tid];
@@ -153,11 +153,16 @@ function project_release_history_generat
     $sql = "SELECT n.title, n.nid, n.status, p.uri, u.name AS username FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.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)));
+
+  $project_found = FALSE;
+  while ($project = db_fetch_object($query)) {
+    $project_found = TRUE;
+  }
+
+  if (!$project_found) {
+    wd_err('Project ID %pid not found', array('%pid' => $project_nid));
     return FALSE;
   }
-  $project = db_fetch_object($query);
 
   $xml = ''. check_plain($project->title) ."\n";
   $xml .= ''. check_plain($project->uri) ."\n";
@@ -206,7 +211,7 @@ function project_release_history_generat
   }
 
   $xml .= ''. $project_status ."\n";
-  $xml .= ''. url("node/$project->nid", NULL, NULL, TRUE) ."\n";
+  $xml .= ''. url("node/$project->nid", array('absolute' => TRUE)) ."\n";
 
   // Now, build the query for all the releases for this project and term.
   $joins = array();
@@ -244,7 +249,8 @@ function project_release_history_generat
     // duplicate release nodes and ensure we're just looking at the API term,
     // we need to add a WHERE clause for the API vocabulary id.
     $joins[] = "INNER JOIN {term_data} td ON tn.tid = td.tid";
-    $where[] = 'td.vid = '. _project_release_get_api_vid();
+    $where[] = 'td.vid = %d';
+    $parameters[] = _project_release_get_api_vid();
     $fields[] = 'td.weight';
   }
 
@@ -284,7 +290,7 @@ function project_release_history_generat
     if ($release->status) {
       // Published, so we should include the links.
       $xml .= "  published\n";
-      $xml .= '  '. url("node/$release->nid", NULL, NULL, TRUE) ."\n";
+      $xml .= '  '. url("node/$release->nid", array('absolute' => TRUE)) ."\n";
       if (!empty($release->file_path)) {
         $download_link = theme('project_release_download_link', $release->file_path, NULL, TRUE);
         $xml .= '  '. $download_link['href'] ."\n";
@@ -336,9 +342,9 @@ function project_release_history_write_x
     $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))
+      'mkdir'  => array("ERROR: mkdir(@dir) failed, can't write project list.", array('@dir' => $project_dir)),
+      'unlink' => array("ERROR: unlink(@file) failed, can't write project list.", array('@file' => $tmp_filename)),
+      'rename' => array("ERROR: rename(@old, @new) failed, can't write project list.", array('@old' => $tmp_filename, '@new' => $filename))
     );
     $full_xml = '\n". $xml ."\n";
   }
@@ -356,30 +362,30 @@ function project_release_history_write_x
     $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))
+      'mkdir'  => array("ERROR: mkdir(@dir) failed, can't write history for %project.", array('@dir' => $project_dir, '%project' => $project->title)),
+      'unlink' => array("ERROR: unlink(@file) failed, can't write history for %project.", array('@file' => $tmp_filename, '%project' => $project->title)),
+      'rename' => array("ERROR: rename(@old, @new) failed, can't write history for %project.", array('@old' => $tmp_filename, '@new' => $filename, '%project' => $project->title))
     );
     $full_xml = '\n". $xml ."\n";
   }
 
   // Make sure we've got the right project-specific subdirectory.
   if (!is_dir($project_dir) && !mkdir($project_dir)) {
-    wd_err($errors['mkdir']);
+    wd_err($errors['mkdir'][0], $errors['mkdir'][1]);
     return FALSE;
   }
   // Make sure the "[project]-[version].xml.new" file doesn't exist.
   if (is_file($tmp_filename) && !unlink($tmp_filename)) {
-    wd_err($errors['unlink']);
+    wd_err($errors['unlink'][0], $errors['unlink'][1]);
     return FALSE;
   }
   // Write the XML history to "[project]-[version].xml.new".
   if (!$hist_fd = fopen($tmp_filename, 'xb')) {
-    wd_err(t("ERROR: fopen(@file, 'xb') failed", array('@file' => $tmp_filename)));
+    wd_err("ERROR: fopen(@file, 'xb') failed", array('@file' => $tmp_filename));
     return FALSE;
   }
   if (!fwrite($hist_fd, $full_xml)) {
-    wd_err(t("ERROR: fwrite(@file) failed", array('@file' => $tmp_filename)) . '
' . check_plain($full_xml));
+    wd_err("ERROR: fwrite(@file) failed" . '
' . check_plain($full_xml), array('@file' => $tmp_filename));
     return FALSE;
   }
   // We have to close this handle before we can rename().
@@ -387,7 +393,7 @@ 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($errors['rename']);
+    wd_err($errors['rename'][0], $errors['rename'][1]);
     return FALSE;
   }
   return TRUE;
@@ -449,15 +455,15 @@ function project_list_generate() {
 /**
  * Wrapper function for watchdog() to log notice messages.
  */
-function wd_msg($msg, $link = NULL) {
-  watchdog('release_history', $msg, WATCHDOG_NOTICE, $link);
+function wd_msg($msg, $variables = array(), $link = NULL) {
+  watchdog('release_history', $msg, $variables, WATCHDOG_NOTICE, $link);
 }
 
 /**
  * Wrapper function for watchdog() to log error messages.
  */
-function wd_err($msg, $link = NULL) {
-  watchdog('release_hist_err', $msg, WATCHDOG_ERROR, $link);
+function wd_err($msg, $variables=array(), $link = NULL) {
+  watchdog('release_hist_err', $msg, $variables, WATCHDOG_ERROR, $link);
 }
 
 /**
Index: release/project_release.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/project_release.css,v
retrieving revision 1.6
diff -u -p -r1.6 project_release.css
--- release/project_release.css	6 Mar 2008 06:41:44 -0000	1.6
+++ release/project_release.css	20 Jun 2008 23:17:53 -0000
@@ -1,20 +1,12 @@
 /* $Id: project_release.css,v 1.6 2008/03/06 06:41:44 dww Exp $ */
-/* $Name:  $ */
+/* $Name: HEAD $ */
 
-.project-release .node-form .version-elements fieldset .form-item {
+.node-form fieldset .version-elements .form-item {
   float: left;
   padding-right: 0.8em;
   margin: 0.05em 0.1em;
 }
 
-.project-release .node-form fieldset:after {
-  content: ".";
-  display: block;
-  height: 0;
-  clear: both;
-  visibility: hidden;
-}
-
 /***************************
 * CSS for tables of releases
 */
Index: release/project_release.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/project_release.info,v
retrieving revision 1.3
diff -u -p -r1.3 project_release.info
--- release/project_release.info	9 Aug 2007 23:38:52 -0000	1.3
+++ release/project_release.info	20 Jun 2008 23:17:53 -0000
@@ -2,4 +2,7 @@
 name = Project releases
 description = Provides a release node type to represent releases of projects.
 package = Project
-dependencies = project taxonomy
+dependencies[] = project
+dependencies[] = taxonomy
+dependencies[] = views
+core = 6.x
Index: release/project_release.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/project_release.install,v
retrieving revision 1.16
diff -u -p -r1.16 project_release.install
--- release/project_release.install	19 Jan 2008 07:10:59 -0000	1.16
+++ release/project_release.install	20 Jun 2008 23:17:53 -0000
@@ -1,138 +1,22 @@
  1, 'not null' => TRUE));
-      break;
-  }
-  return $ret;
-}
+function project_release_schema() {
+  $schema['project_release_nodes'] = array(
+    'description' => t('The base table for project_project nodes.'),
+    'fields' => array(
+      'nid' => array(
+        'description' => t('Primary Key: The {node}.nid of the project_release node.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'pid' => array(
+        'description' => t('The {project_projects}.nid of the project_project node with which the project_release node is associated.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'version' => array(
+        'description' => t('A string containing the full version of a release. The format of this string for a given project is dictated by {project_release_projects}.version_format.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'tag' => array(
+        'description' => t('The name of a CVS branch or tag on which a release is based.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'file_path' => array(
+        'description' => t('The path to the downloadable file for the release.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'file_date' => array(
+        'description' => t('A Unix timestamp indicating when the file was created.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'file_hash' => array(
+        'description' => t('An MD5 hash of the file.'),
+        'type' => 'varchar',
+        'length' => 32,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'rebuild' => array(
+        'description' => t('A flag indicating whether or not the file associated with a release should be rebuilt periodically. For official releases this should be 0, for development snapshots it should be 1.'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => FALSE,
+        'not null' => FALSE,
+        'default' => 0,
+      ),
+      'version_major' => array(
+        'description' => t('The major version number of a release.'),
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => FALSE,
+        'default' => NULL,
+      ),
+      'version_minor' => array(
+        'description' => t('The minor version number of a release.'),
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => FALSE,
+        'default' => NULL,
+      ),
+      'version_patch' => array(
+        'description' => t('The patch level version number of a release.'),
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => FALSE,
+        'default' => NULL,
+      ),
+      'version_extra' => array(
+        'description' => t('A text string that can be used to provide additional information about a release.  Ex: BETA'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => FALSE,
+        'default' => NULL,
+      ),
+    ),
+    'primary key' => array('nid'),
+    'indexes' => array(
+      'project_releases_pid' => array('pid')
+    ),
+  );
 
-/**
- * Add a cache table {cache_project_release}.
- */
-function project_release_update_5000() {
-  $ret = array();
-  switch ($GLOBALS['db_type']) {
-    case 'mysql':
-    case 'mysqli':
-      $ret[] = update_sql("CREATE TABLE IF NOT EXISTS {cache_project_release} (
-        cid varchar(255) BINARY NOT NULL default '',
-        data longblob,
-        expire int NOT NULL default '0',
-        created int NOT NULL default '0',
-        headers text,
-        PRIMARY KEY (cid),
-        INDEX expire (expire)
-      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
-      break;
-    case 'pgsql':
-      if (!db_table_exists('cache_project_release')) {
-        $ret[] = update_sql("CREATE TABLE {cache_project_release} (
-          cid varchar(255) NOT NULL default '',
-          data bytea,
-          expire int NOT NULL default '0',
-          created int NOT NULL default '0',
-          headers text,
-          PRIMARY KEY (cid)
-        )");
-        $ret[] = update_sql("CREATE INDEX {cache_project_release}_expire_idx ON {cache_project_release} (expire)");
-      }
-      break;
-  }
-  return $ret;
-}
+  $schema['project_release_projects'] = array(
+    'description' => t('Table used to store release specific information about projects.'),
+    'fields' => array(
+      'nid' => array(
+        'description' => t('Primary Key: The {project_projects}.nid of the project_project node.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'releases' => array(
+        'description' => t('A flag indicating whether or not releases are enabled for a project.'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => FALSE,
+        'not null' => TRUE,
+        'default' => 1,
+      ),
+      'version_format' => array(
+        'description' => t('A string used to designate the format of the {project_release_nodes}.version field for releases of a project.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+    ),
+    'primary key' => array('nid'),
+    'indexes' => array(
+      'project_release_projects_releases' => array('releases')
+    ),
+  );
 
-/**
- * Remove variables from dead code for serving XML history files, which is
- * now handled by project-release-serve-history.php instead.
- */
-function project_release_update_5001() {
-  $ret = array();
-  $variables = array(
-    'project_release_history_xml',
-    'project_release_history_directory',
+  $schema['project_release_supported_versions'] = array(
+    'description' => t('Table used to store information about which major versions of a project are supported and/or recommended.'),
+    'fields' => array(
+      'nid' => array(
+        'description' => t('Primary Key: The {project_projects}.nid of the project_project node.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tid' => array(
+        'description' => t('Primary Key: The {term_data}.tid of the API compatability version associated with a major version of a project.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'major' => array(
+        'description' => t('Primary Key: The {project_release_nodes}.version_major of a release node.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'supported' => array(
+        'description' => t('A flag to indicate whether or not a given major version of a project is supported.'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 1,
+      ),
+      'recommended' => array(
+        'description' => t('A flag to indicate whether or not a given major version of a project is recommended.'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'snapshot' => array(
+        'description' => t('A flag to indicate whether or not snapshot releases of a major version of a project should be shown in the release download table.'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('nid', 'tid', 'major'),
   );
-  foreach ($variables as $variable) {
-    variable_del($variable);
-    $ret[] = array('success' => TRUE, 'query' => "variable_del($variable)");
-  }
-  return $ret;
-}
 
-/**
- * Remove a dead variable from before project_release.module existed.
- */
-function project_release_update_5002() {
-  $ret = array();
-  variable_del('project_release_unmoderate');
-  $ret[] = array('success' => TRUE, 'query' => "variable_del('project_release_unmoderate')");
-  return $ret;
-}
+  $schema['project_release_package_errors'] = array(
+    'description' => t('Table used to store error messages generated by the scripts that package project_release nodes into tarballs.'),
+    'fields' => array(
+      'nid' => array(
+        'description' => t('Primary Key: The {node}.nid of the project_release node.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'messages' => array(
+        'description' => t('The text of any error messages created by the packaging scripts.'),
+        'type' => 'text',
+        'not null' => FALSE,
+      )
+    ),
+    'primary key' => array('nid'),
+  );
 
-/**
- * Add {project_release_package_errors} table to track packaging errors.
- */
-function project_release_update_5003() {
-  $ret = array();
-  switch ($GLOBALS['db_type']) {
-    case 'mysql':
-    case 'mysqli':
-      $ret[] = update_sql("CREATE TABLE IF NOT EXISTS {project_release_package_errors} (
-          nid int unsigned NOT NULL default '0',
-          messages text NOT NULL,
-          PRIMARY KEY (nid)
-        ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
-      break;
-    case 'pgsql':
-      if (!db_table_exists('project_release_package_errors')) {
-        $ret[] = update_sql("CREATE TABLE {project_release_package_errors} (
-          nid int NOT NULL default '0',
-          messages text,
-          PRIMARY KEY (nid)
-        )");
-      }
-      break;
-  }
-  return $ret;
+  $schema['cache_project_release'] = array(
+    'description' => t('Cache table used to store the project release download tables.'),
+    'fields' => array(
+      'cid' => array(
+        'description' => t('Primary Key: Unique cache ID.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'data' => array(
+        'description' => t('A collection of data to cache.'),
+        'type' => 'blob',
+        'not null' => FALSE,
+        'size' => 'big',
+      ),
+      'expire' => array(
+        'description' => t('A Unix timestamp indicating when the cache entry should expire, or 0 for never.'),
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'created' => array(
+        'description' => t('A Unix timestamp indicating when the cache entry was created.'),
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'headers' => array(
+        'description' => t('Any custom HTTP headers to be added to cached data.'),
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'serialized' => array(
+        'description' => t('A flag to indicate whether content is serialized (1) or not (0).'),
+        'type' => 'int',
+        'size' => 'small',
+        'not null' => TRUE,
+        'default' => 0
+      ),
+    ),
+    'primary key' => array('cid'),
+    'indexes' => array(
+      'expire' => array('expire')
+    ),
+  );
+  return $schema;
 }
 
 /**
- * Add the new {project_release_supported_versions} table, transfer data
- * from {project_release_default_versions} and {project_release_projects},
- * and drop the stale table and columns.
+ * Add the 'serialized' field to the {cache_project_release} table.
  */
-function project_release_update_5200() {
+function project_release_update_6000() {
+  $spec = array(
+    'type' => 'int',
+    'size' => 'small',
+    'default' => 0,
+    'not null' => TRUE,
+  );
   $ret = array();
-  switch ($GLOBALS['db_type']) {
-    case 'mysql':
-    case 'mysqli':
-      $ret[] = update_sql("CREATE TABLE IF NOT EXISTS {project_release_supported_versions} (
-          nid int unsigned NOT NULL default '0',
-          tid int unsigned NOT NULL default '0',
-          major int unsigned NOT NULL default '0',
-          supported tinyint unsigned NOT NULL default '1',
-          recommended tinyint unsigned NOT NULL default '0',
-          snapshot tinyint unsigned NOT NULL default '0',
-          PRIMARY KEY (nid, tid, major)
-        ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
-      break;
-    case 'pgsql':
-      if (!db_table_exists('project_release_supported_versions')) {
-        $ret[] = update_sql("CREATE TABLE {project_release_supported_versions} (
-            nid int NOT NULL default '0',
-            tid int NOT NULL default '0',
-            major int NOT NULL default '0',
-            supported smallint NOT NULL default '1',
-            recommended smallint NOT NULL default '0',
-            snapshot smallint NOT NULL default '0',
-            PRIMARY KEY (nid, tid, major)
-          );");
-      }
-      break;
-  }
-  // Now, populate the table with the existing data. First, populate all the
-  // recommended majors versions from {project_release_default_versions}.
-  $ret[] = update_sql("INSERT INTO {project_release_supported_versions} (nid, tid, major, supported, recommended, snapshot) SELECT prdv.nid, prdv.tid, prdv.major, 1, 1, prp.snapshot_table FROM {project_release_default_versions} prdv INNER JOIN {project_release_projects} prp ON prdv.nid = prp.nid");
-
-  // Now, fill in all the non-recommended versions. For the migration path, we
-  // assume that if it's not recommended, it's also not supported. Project
-  // maintainers will have to manually visit the new UI if they want to
-  // specify multiple supported versions.
-  $vid = _project_release_get_api_vid();
-  $ret[] = update_sql("INSERT INTO {project_release_supported_versions} (nid, tid, major, supported, recommended, snapshot) SELECT DISTINCT prn.pid, tn.tid, prn.version_major, 0, 0, 0 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 INNER JOIN {node} n ON prn.nid = n.nid LEFT JOIN {project_release_default_versions} prdv ON prdv.nid = prn.pid AND prdv.tid = tn.tid AND prdv.major = prn.version_major WHERE n.status = 1 AND td.vid = $vid AND prn.version_major IS NOT NULL AND prdv.major IS NULL");
-
-  // Finally, drop the stale table and column.
-  // While testing the upgrade path, these are both commented out for now:
-  //$ret[] = update_sql('DROP TABLE {project_release_default_versions}');
-  //$ret[] = update_sql("ALTER TABLE {project_release_projects} DROP snapshot_table");
-
+  db_add_field($ret, 'cache_project_release', 'serialized', $spec);
   return $ret;
-}
+}
\ No newline at end of file
Index: release/project_release.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/release/project_release.module,v
retrieving revision 1.69
diff -u -p -r1.69 project_release.module
--- release/project_release.module	11 Jun 2008 18:14:55 -0000	1.69
+++ release/project_release.module	20 Jun 2008 23:17:53 -0000
@@ -1,6 +1,6 @@
 type) || $node->type != 'project_project') {
+    return FALSE;
+  }
+  return $node;
+}
+
+/**
  * Implementation of hook_menu()
  * @ingroup project_release_core
  */
-function project_release_menu($may_cache) {
+function project_release_menu() {
   $items = array();
-  global $user;
-
-  $access_create = node_access('create', 'project_release');
 
-  if (!$may_cache) {
-    if (arg(0) == 'node' && is_numeric(arg(1))) {
-      $node = node_load(arg(1));
-      if ($node->type == 'project_project') {
-        $items[] = array(
-          'path' => 'node/'. arg(1) .'/release',
-          'title' => t('Releases'),
-          'callback' => 'project_release_project_releases',
-          'access' => node_access('view', $node),
-          'type' => MENU_CALLBACK,
-        );
-        if (node_access('update', $node)) {
-          $items[] = array(
-            'path' => 'node/'. arg(1) .'/release/overview',
-            'title' => t('Overview'),
-            'callback' => 'project_release_project_releases',
-            'access' => node_access('view', $node),
-            'type' => MENU_CALLBACK,
-          );
-          $items[] = array(
-            'path' => 'node/'. arg(1) .'/edit/releases',
-            'title' => t('Releases'),
-            'callback' => 'project_release_project_edit_releases',
-            'type' => MENU_LOCAL_TASK,
-          );
-        }
-      }
-    }
-    if (arg(0) == 'node' && arg(1) == 'add' && arg(2) == 'project-release' && is_numeric(arg(3))) {
-      $items[] = array(
-        'path' => 'node/add/project-release/'. arg(3),
-        'callback' => 'node_add',
-        'callback arguments' => array('project-release'),
-        'access' => $access_create,
-        'type' => MENU_CALLBACK,
-      );
-    }
-
-    drupal_add_css(drupal_get_path('module', 'project_release') .'/project_release.css');
-    project_release_get_api_taxonomy();
-  }
-  else {    // $may_cache
-    $items[] = array(
-      'path' => 'admin/project/project-release-settings',
-      'description' => t('Configure the default version string for releases and other settings for the Project release module.'),
-      'title' => t('Project release settings'),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => 'project_release_settings_form',
-      'access' => user_access('administer projects'),
-      'weight' => 1,
-      'type' => MENU_NORMAL_ITEM,
-    );
-    // Special menu item for the "first page" of submitting a new release.
-    // Instead of the treachery of a true multipage form, we just have
-    // a simple form at node/add/project-release that provides a project
-    // selector which redirects to node/add/project-release/[project-nid].
-    $types = node_get_types();
-    $items[] = array(
-      'path' => 'node/add/project-release',
-      'title' => check_plain($types['project_release']->name),
-      'callback' => 'project_release_pick_project_page',
-      'callback arguments' => array($types['project_release']->name),
-      'access' => $access_create,
-      'type' => MENU_NORMAL_ITEM,
-    );
-  }
+  $items['node/%project_release_project/edit/releases'] = array(
+    'title' => 'Releases',
+    'page callback' => 'project_release_project_edit_releases',
+    'page arguments' => array(1),
+    'access callback' => 'node_access',
+    'access arguments' => array('update', 1),
+    'type' => MENU_LOCAL_TASK,
+  );
+
+  $items['node/add/project-release/%project_release_project'] = array(
+    'page callback' => 'node_add',
+    'page arguments' => array('project-release'),
+    'access callback' => 'node_access',
+    'access arguments' => array('create', 'project_release'),
+    'file' => 'node.pages.inc',
+    'file path' => drupal_get_path('module', 'node'),
+    'type' => MENU_CALLBACK,
+  );
+
+  $items['admin/project/project-release-settings'] = array(
+    'description' => 'Configure the default version string for releases and other settings for the Project release module.',
+    'title' => 'Project release settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('project_release_settings_form'),
+    'access arguments' => array('administer projects'),
+    'weight' => 1,
+    'type' => MENU_NORMAL_ITEM,
+  );
   return $items;
 }
 
 /**
+ * Implementation of hook_menu_alter().
+ */
+function project_release_menu_alter(&$callbacks) {
+  $callbacks['node/add/project-release']['page callback'] = 'drupal_get_form';
+  $callbacks['node/add/project-release']['page arguments'] = array('project_release_pick_project_form');
+}
+
+/**
  * Callback for the main settings page.
  * @ingroup project_release_core
  */
@@ -117,7 +107,7 @@ function project_release_settings_form()
     foreach ($tree as $term) {
       $terms[$term->tid] = check_plain($term->name);
     }
-    $vocab = taxonomy_get_vocabulary(_project_release_get_api_vid());
+    $vocab = taxonomy_vocabulary_load(_project_release_get_api_vid());
     $tids = variable_get('project_release_active_compatibility_tids', '');
     $form['project_release_active_compatibility_tids'] = array(
       '#type' => 'checkboxes',
@@ -155,23 +145,23 @@ function project_release_settings_form()
   return system_settings_form($form);
 }
 
-function project_release_settings_form_validate($form_id, $form_values, $form) {
-  if (!empty($form_values['project_release_directory'])) {
+function project_release_settings_form_validate($form, &$form_state) {
+  if (!empty($form_state['values']['project_release_directory'])) {
     form_set_error('project_release_directory', t('Release directory setting has been deprecated.'));
   }
-  $tids = $form_values['project_release_active_compatibility_tids'];
-  $default_tid = $form_values['project_release_overview'];
+  $tids = $form_state['values']['project_release_active_compatibility_tids'];
+  $default_tid = $form_state['values']['project_release_overview'];
   if ($default_tid != -1 && !$tids[$default_tid]) {
-    $vocab = taxonomy_get_vocabulary(_project_release_get_api_vid());
+    $vocab = taxonomy_vocabulary_load(_project_release_get_api_vid());
     form_set_error('project_release_overview', t('Project release overview must be one of the active @vocab terms', array('@vocab' => $vocab->name)));
   }
 
   // Make sure the default version format has no bad characters.
-  _project_release_validate_format_string($form_values, 'project_release_default_version_format');
+  _project_release_validate_format_string($form_state['values'], 'project_release_default_version_format');
 
   // If set, the project_release_download_base must end with a '/'
-  if (!empty($form_values['project_release_download_base'])) {
-    if (substr($form_values['project_release_download_base'], -1) != '/') {
+  if (!empty($form_state['values']['project_release_download_base'])) {
+    if (substr($form_state['values']['project_release_download_base'], -1) != '/') {
        form_set_error('project_release_download_base', t('The %download_base_setting should end with a slash.', array('%download_base_setting' => t('Download link base URL'))));
     }
   }
@@ -188,13 +178,12 @@ function project_release_settings_form_v
  * TODO: Maybe we should add new permissions for accessing release
  * nodes, but for now, we're just using the existing project perms.
  */
-function project_release_access($op, $node) {
-  global $user;
+function project_release_access($op, $node, $account) {
   switch ($op) {
     case 'view':
       // We want to use the identical logic for viewing projects,
       // so we call that method directly.
-      return project_project_access($op, $node);
+      return project_project_access($op, $node, $account);
     case 'create':
       // Due to how node_menu() works, we have to allow anyone with
       // permission to maintain a project to be able to create a
@@ -204,7 +193,7 @@ function project_release_access($op, $no
       // enforce more closely in project_release_form(). As with the
       // 'view' case above, we want the identical logic as project
       // nodes, so we call that hook, instead of duplicating code.
-      return project_project_access($op, $node);
+      return project_project_access($op, $node, $account);
     case 'update':
       // We can't just use project_project_access() here, since we
       // need to check access to the project itself, not the release
@@ -236,6 +225,19 @@ function project_release_node_info() {
  */
 function project_release_form($release) {
   if (arg(1) == 'add') {
+    // Initialize variables and $release object properties to eliminate notices.
+    $is_edit = FALSE;
+    $admin = NULL;
+    $release->version_major = NULL;
+    $release->version_minor = NULL;
+    $release->version_patch = NULL;
+    $release->version_extra = NULL;
+    $release->tag = '';
+    $release->version = '';
+    $release->file_path = '';
+    $release->file_hash = '';
+    $release->file_date = 0;
+    $release->version_api_tid = NULL;
     $release->pid = arg(3);
     $project = node_load($release->pid);
     project_project_set_breadcrumb($project, TRUE);
@@ -262,8 +264,7 @@ function project_release_form($release) 
     global $user;
     $admin = user_access('administer projects');
     $is_edit = true;
-    $project->nid = $release->pid;
-    $project = node_load($project);
+    $project = node_load($release->pid);
     $breadcrumb[] = l($project->title, 'node/'. $project->nid);
     $breadcrumb[] = l(t('Releases'), 'node/'. $project->nid . '/release');
     project_project_set_breadcrumb($project, $breadcrumb);
@@ -271,17 +272,14 @@ function project_release_form($release) 
   }
 
   $form['#attributes'] = array("enctype" => "multipart/form-data");
-  $form['#prefix'] = '
'; - $form['#suffix'] = '
'; if ($is_edit) { $form['rel_id'] = array( '#type' => 'fieldset', '#title' => t('Release identification'), - '#prefix' => '
', - '#suffix' => '
', '#weight' => -4, '#collapsible' => TRUE, + '#theme' => 'project_release_node_form_version_elements', ); } _project_release_form_add_text_element($form['rel_id']['title'], t('Title'), $release->title, $is_edit, $admin, true, 40, 128); @@ -295,19 +293,14 @@ function project_release_form($release) '#type' => 'fieldset', '#title' => t('Version number elements'), '#collapsible' => TRUE, - '#prefix' => '
', - '#suffix' => '
', + '#theme' => 'project_release_node_form_version_elements', ); $modify = $admin || !$is_edit; $form['validate_version'] = array('#type' => 'hidden', '#value' => 1); - _project_release_form_add_version_element($form, $release, $modify, $format, - 'major', t('Major')); - _project_release_form_add_version_element($form, $release, $modify, $format, - 'minor', t('Minor')); - _project_release_form_add_version_element($form, $release, $modify, $format, - 'patch', t('Patch-level')); - _project_release_form_add_version_element($form, $release, $modify, $format, - 'extra', t('Extra identifier'), t('Optionally specify other identifying information for this version, for example "beta-1", "rc-1" or "dev". In most cases, this should be left blank.'), 40); + _project_release_form_add_version_element($form, $release, $modify, $format, 'major', t('Major')); + _project_release_form_add_version_element($form, $release, $modify, $format, 'minor', t('Minor')); + _project_release_form_add_version_element($form, $release, $modify, $format, 'patch', t('Patch-level')); + _project_release_form_add_version_element($form, $release, $modify, $format, 'extra', t('Extra identifier'), t('Optionally specify other identifying information for this version, for example "beta-1", "rc-1" or "dev". In most cases, this should be left blank.'), 40); $form['file'] = array( '#type' => 'fieldset', @@ -315,39 +308,30 @@ function project_release_form($release) '#collapsible' => TRUE, ); if (empty($release->file_path)) { - $file = file_check_upload('file'); + $file = file_save_upload('file'); $form['file']['file'] = array( '#title' => t('File'), '#type' => 'file', - '#description' => ($file ? t('A file named %filename has already been uploaded. If you upload another file %filename will be replaced.', array('%filename' => $file->filename)) : t('Choose the file that will be associated with this release.')), + '#description' => (!empty($file) ? t('A file named %filename has already been uploaded. If you upload another file %filename will be replaced.', array('%filename' => $file->filename)) : t('Choose the file that will be associated with this release.')), ); } - $form['body_filter'] = array( - '#type' => 'fieldset', - '#title' => t('Description'), - '#collapsible' => TRUE, - ); - $form['body_filter']['body'] = array( - '#title' => t('Body'), - '#type' => 'textarea', - '#default_value' => $release->body, - '#rows' => 10, - '#cols' => 40, - '#required' => $admin ? FALSE : TRUE, - '#description' => t('Enter a description of this release, such as a list of the major changes or updates.'), - ); - $form['body_filter']['format'] = filter_form($release->format); + $form['body_field'] = node_body_field($release, t('Release notes'), !$admin); + // Add a description to the body field. + $form['body_field']['body']['#description'] = t('Enter a description of this release, such as a list of the major changes or updates.'); _project_release_form_add_text_element($form['tag']['tag'], t('Tag'), $release->tag, $is_edit, $admin, true, 40, 255); $form['tag']['rebuild'] = array( '#type' => 'value', - '#value' => $release->rebuild, + '#value' => empty($release->rebuild) ? 0 : $release->rebuild, ); _project_release_form_add_text_element($form['file']['file_path'], t('File path'), $release->file_path, $is_edit, $admin, false, 40, 255); - _project_release_form_add_text_element($form['file']['file_hash'], t('File md5 hash'), $release->file_hash, $is_edit, false); - _project_release_form_add_text_element($form['file']['file_date'], t('File date'), $release->file_date, $is_edit, false); + _project_release_form_add_text_element($form['file']['file_hash'], t('File md5 hash'), $release->file_hash, $is_edit, false, FALSE); + _project_release_form_add_text_element($form['file']['file_date'], t('File date'), $release->file_date, $is_edit, false, FALSE); + // Add a custom validation function. + $form['#validate'][] = 'project_release_node_form_validate'; + $form['#submit'][] = 'project_release_node_form_submit'; return $form; } @@ -414,12 +398,22 @@ function _project_release_form_add_versi * @see project_release_form * @ingroup project_release_internal * - * @param $form Reference to form element to add - * @param $title Translatable title of the form element - * @param $value The value to use in the form - * @param $is_edit Boolean indicating if we're editing or creating - * @param $admin Boolean for if the edit is by a project administrator - * @param $required Boolean for if the field should be required + * @param $form + * Reference to form element to add. + * @param $title + * Translatable title of the form element. + * @param $value + * The value to use in the form. + * @param $is_edit + * Boolean indicating if we're editing or creating. + * @param $admin + * Boolean for if the edit is by a project administrator. + * @param $required + * Boolean for if the field should be required. + * @param $size + * Value to use for the '#size' property. + * @param $maxlength + * Value to use for the '#maxlength' property. */ function _project_release_form_add_text_element(&$form, $title, $value, $is_edit, $admin, $required = true, $size = 40, $maxlength = 50) { if ($is_edit && !empty($value)) { @@ -427,6 +421,7 @@ function _project_release_form_add_text_ '#type' => 'textfield', '#title' => $title, '#default_value' => $value, + '#value' => $value, '#required' => $required, '#size' => $size, '#maxlength' => $maxlength, @@ -443,64 +438,63 @@ function _project_release_form_add_text_ } } -/** - * Implementation of hook_validate(). - * @ingroup project_release_node - */ -function project_release_validate(&$edit, $form) { - global $form_values; - - if ($_POST['validate_version']) { - if (!isset($edit->version_major) && !isset($edit->version_minor) && - !isset($edit->version_patch) && - (!($edit->version_extra) || $edit->version_extra === '')) { +function project_release_node_form_validate(&$form, $form_state) { + if (!empty($form_state['values']['validate_version'])) { + if (!isset($form_state['values']['version_major']) && !isset($form_state['values']['version_minor']) && + !isset($form_state['values']['version_patch']) && + (!($form_state['values']['version_extra']) || $form_state['values']['version_extra'] === '')) { form_set_error('version_major', t('You must fill in some version information.')); // TODO: find a better form value to mark as the error? } foreach (array('version_major' => 'Major version number', 'version_minor' => 'Minor version number') as $field => $name) { - $val = $edit->$field; + $val = $form_state['values'][$field]; if (isset($val) && $val !== '' && !is_numeric($val)) { form_set_error($field, t('!name must be a number.', array('!name' => $name))); } } - $val = $edit->version_patch; + $val = $form_state['values']['version_patch']; if (isset($val) && $val !== '' && !is_numeric($val) && $val != 'x') { form_set_error('version_patch', t("Patch-level version number must be numeric or the letter 'x'.")); } } - if ($file = file_check_upload('file')) { - if ($file = file_save_upload($file)) { + // @TODO: Need to add in some validation here. + $validators = array( + + ); + if ($file = file_save_upload('file', $validators, file_directory_path())) { + if (!empty($file)) { // Using $form_values here is an ugly hack, but the caching mechanism - // in file_check_upload() causes problems if we can't pass this object + // in file_check_upload() causes problems if we can't pass this object // @TODO: Edit comment, since file_check_upload() doesn't exist. // to the file_save_upload() call in the submit function which actually // saves the file. - $form_values['release_file'] = $file; + $form_state['project_release']['release_file'] = $file; $filepath = file_create_path($file->filepath); - form_set_value($form['file']['file_path'], $file->filepath); - form_set_value($form['file']['file_date'], filemtime($filepath)); - form_set_value($form['file']['file_hash'], md5_file($filepath)); + form_set_value($form['file']['file_path'], $file->filepath, $form_state); + form_set_value($form['file']['file_date'], filemtime($filepath), $form_state); + form_set_value($form['file']['file_hash'], md5_file($filepath), $form_state); } else { form_set_error('file', t('There was a problem uploading the specified file.')); } } + if (project_release_get_api_taxonomy()) { $vid = _project_release_get_api_vid(); - if (isset($edit->taxonomy)) { - $tid = $edit->taxonomy[$vid]; + if (isset($form_state['values']['taxonomy'])) { + $tid = $form_state['values']['taxonomy'][$vid]; } - elseif (isset($edit->$vid)) { - $tid = $edit->$vid; + elseif (isset($form_state['values']['$vid'])) { + $tid = $form_state['values']['$vid']; } if (isset($tid) && is_numeric($tid)) { - $edit->version_api_tid = $tid; + $form_state['values']['version_api_tid'] = $tid; } } // With cvs.module installed, this validation is already handled. // We only want to do it here if we're *not* doing the N-page form... - if (!project_use_cvs($edit) && !isset($edit->nid) && project_release_exists($edit)) { + if (!project_use_cvs($form_state['values']['pid']) && !isset($form_state['values']['nid']) && project_release_exists($form_state['values'])) { // TODO: is there a better form element to mark with this error? form_set_error('version_patch', t('This version already exists for this project.')); } @@ -519,16 +513,30 @@ function project_release_validate(&$edit // TODO: Magic re-setting to "%project_name %version" ?? } elseif (isset($edit->version) && $edit->version !== '') { - form_set_value($form['title'], "$project_name $edit->version"); + form_set_value($form['title'], "$project_name $edit->version", $form_state); } elseif (isset($edit->project)) { $version = project_release_get_version((object)$edit, $edit->project); - form_set_value(array('#parents' => array('version')), $version); + form_set_value(array('#parents' => array('version')), $version, $form_state); $title = $edit->project->title; - form_set_value($form['title'], "$title $version"); + form_set_value($form['title'], "$title $version", $form_state); } } +function project_release_node_form_submit(&$form, $form_state) { + //// Handle file upload data. + //$file_data = new stdClass(); + //if (isset($form_values['release_file'])) { + // $file_data = file_save_upload($form_values['release_file'], file_directory_path()); + // // If a file was uploaded, this is what we need to use. + // $file_path = $file_data->filepath; + //} + //else { + // // If there's no upload, save whatever value is already in $node. + // $file_path = $node->file_path; + //} +} + /** * Implementation of hook_load(). * @ingroup project_release_node @@ -584,32 +592,31 @@ 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) { - global $form_values; - // 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); } - // Handle file upload data. - $file_data = new stdClass(); - if (isset($form_values['release_file'])) { - $file_data = file_save_upload($form_values['release_file'], file_directory_path()); - // If a file was uploaded, this is what we need to use. - $file_path = $file_data->filepath; - } - else { - // If there's no upload, save whatever value is already in $node. - $file_path = $node->file_path; - } + // @TODO: Fix the file handling here--we just need to save the file now. + //// Handle file upload data. + //$file_data = new stdClass(); + //if (isset($form_values['release_file'])) { + // $file_data = file_save_upload($form_values['release_file'], file_directory_path()); + // // If a file was uploaded, this is what we need to use. + // $file_path = $file_data->filepath; + //} + //else { + // // If there's no upload, save whatever value is already in $node. + // $file_path = $node->file_path; + //} $types = array( 'pid' => "%d", 'version' => "'%s'", 'tag' => "'%s'", 'file_path' => "'%s'", 'file_date' => "%d", 'file_hash' => "'%s'", 'rebuild' => "%d", ); $values = array( 'pid' => $node->pid, 'version' => $node->version, - 'tag' => $node->tag, 'file_path' => $file_path, + 'tag' => $node->tag, 'file_path' => $node->file_path, 'file_date' => $node->file_date, 'file_hash' => $node->file_hash, 'rebuild' => $node->rebuild, ); @@ -655,15 +662,15 @@ function project_release_db_save($node, function project_release_check_supported_versions($pid, $tid, $major, $delete) { if ($delete) { // Make sure this isn't the last release node for the given major. - $active_branch_releases = db_result(db_query("SELECT COUNT(DISTINCT(r.nid)) FROM {project_release_nodes} r INNER JOIN {node} n ON n.nid = r.nid INNER JOIN {term_node} tn ON tn.nid = n.nid WHERE r.pid = %d AND tn.tid = %d AND n.status = 1 AND r.version_major = %d", $pid, $tid, $major)); + $active_branch_releases = db_result(db_query("SELECT COUNT(DISTINCT(r.nid)) FROM {project_release_nodes} r INNER JOIN {node} n ON n.nid = r.nid INNER JOIN {term_node} tn ON tn.nid = n.nid WHERE r.pid = %d AND tn.tid = %d AND n.status = %d AND r.version_major = %d", $pid, $tid, 1, $major)); if (empty($active_branch_releases)) { // Remove the bogus record. db_query("DELETE FROM {project_release_supported_versions} WHERE nid = %d AND tid = %d AND major = %d", $pid, $tid, $major); - $num_recommended = db_result(db_query("SELECT COUNT(*) FROM {project_release_supported_versions} WHERE nid = %d AND tid = %d AND supported = 1 AND recommended = 1", $pid, $tid)); + $num_recommended = db_result(db_query("SELECT COUNT(*) FROM {project_release_supported_versions} WHERE nid = %d AND tid = %d AND supported = %d AND recommended = %d", $pid, $tid, 1, 1)); if ($num_recommended > 1) { // Something seriously bogus, clear out the values and start over. - db_query("UPDATE {project_release_supported_versions} SET recommended = 0 WHERE nid = %d AND tid = %d", $pid, $tid); + db_query("UPDATE {project_release_supported_versions} SET recommended = %d WHERE nid = %d AND tid = %d", 0, $pid, $tid); $num_recommended = 0; } @@ -671,9 +678,9 @@ function project_release_check_supported // We no longer have a recommended major for this API/tid, so select a // sensible default, if possible. Find the lowest supported major // number that has a published release. - $lowest_major = db_result(db_query("SELECT MIN(r.version_major) FROM {project_release_nodes} r INNER JOIN {project_release_supported_versions} prsv ON r.pid = prsv.nid INNER JOIN {node} n ON n.nid = r.nid INNER JOIN {term_node} tn ON tn.nid = n.nid WHERE r.pid = %d AND tn.tid = %d AND prsv.supported = 1 AND n.status = 1", $pid, $tid)); + $lowest_major = db_result(db_query("SELECT MIN(r.version_major) FROM {project_release_nodes} r INNER JOIN {project_release_supported_versions} prsv ON r.pid = prsv.nid INNER JOIN {node} n ON n.nid = r.nid INNER JOIN {term_node} tn ON tn.nid = n.nid WHERE r.pid = %d AND tn.tid = %d AND prsv.supported = %d AND n.status = %d", $pid, $tid, 1, 1)); if ($lowest_major !== NULL && $lowest_major !== FALSE) { - db_query("UPDATE {project_release_supported_versions} SET supported = 1, recommended = 1 WHERE nid = %d AND tid = %d AND major = %d", $pid, $tid, $lowest_major); + db_query("UPDATE {project_release_supported_versions} SET supported = %d, recommended = %d WHERE nid = %d AND tid = %d AND major = %d", 1, 1, $pid, $tid, $lowest_major); } } } @@ -682,7 +689,7 @@ function project_release_check_supported // Adding or editing a release. // First make sure this branch has at least 1 published release node - $published_releases = db_result(db_query("SELECT COUNT(*) FROM {project_release_nodes} r INNER JOIN {node} n ON n.nid = r.nid INNER JOIN {term_node} tn ON tn.nid = n.nid WHERE r.pid = %d AND r.version_major = %d AND tn.tid = %d AND n.status = 1", $pid, $major, $tid)); + $published_releases = db_result(db_query("SELECT COUNT(*) FROM {project_release_nodes} r INNER JOIN {node} n ON n.nid = r.nid INNER JOIN {term_node} tn ON tn.nid = n.nid WHERE r.pid = %d AND r.version_major = %d AND tn.tid = %d AND n.status = %d", $pid, $major, $tid, 1)); if ($published_releases) { // We have at least 1 published release, so make sure we have an entry // for this major version in {project_release_supported_versions}. @@ -706,7 +713,7 @@ function project_release_check_supported $recommended = 0; } if (isset($recommended)) { - db_query("INSERT INTO {project_release_supported_versions} (nid, tid, major, supported, recommended, snapshot) VALUES (%d, %d, %d, 1, %d, 0)", $pid, $tid, $major, $recommended); + db_query("INSERT INTO {project_release_supported_versions} (nid, tid, major, supported, recommended, snapshot) VALUES (%d, %d, %d, %d, %d, %d)", $pid, $tid, $major, 1, $recommended, 0); } } } @@ -828,7 +835,7 @@ function project_release_view($node, $te $output = ''; if (project_use_cvs($project) && isset($node->tag)) { - if ($node->rebuild) { + if (!empty($node->rebuild)) { $output .= t('Nightly development snapshot from CVS branch: @tag', array('@tag' => $node->tag)) .'
'; } else { @@ -836,7 +843,7 @@ function project_release_view($node, $te } } - if ($node->file_path) { + if (!empty($node->file_path)) { $output .= ''. t('Download: !file', array('!file' => theme('project_release_download_link', $node->file_path))) .'
'; $output .= ''. t('Size: !size', array('!size' => format_size(filesize(file_create_path($node->file_path))))) .'
'; $output .= ''. t('md5_file hash: !file_hash', array('!file_hash' => $node->file_hash)) .'
'; @@ -844,7 +851,7 @@ function project_release_view($node, $te if ($node->created) { $output .= ''. t('First released: !created', array('!created' => format_date($node->created))) .'
'; } - if ($node->file_date && ($node->file_date != $node->created)) { + if (!empty($node->file_date) && ($node->file_date != $node->created)) { $output .= ''. t('Last updated: !changed', array('!changed' => format_date($node->file_date))) .'
'; } $node->content['release_info'] = array( @@ -857,14 +864,16 @@ function project_release_view($node, $te $rows = array(); $result = db_query('SELECT * FROM {project_release_package_errors} WHERE nid = %d', $node->nid); $error = db_fetch_object($result); - $rows = unserialize($error->messages); - if (!empty($rows)) { - $node->content['release_errors'] = array( - '#value' => theme('item_list', $rows, t('Packaging error messages')), - '#weight' => -1, - '#prefix' => '
', - '#suffix' => '
', - ); + if (!empty($error)) { + $rows = unserialize($error->messages); + if (!empty($rows)) { + $node->content['release_errors'] = array( + '#value' => theme('item_list', $rows, t('Packaging error messages')), + '#weight' => -1, + '#prefix' => '
', + '#suffix' => '
', + ); + } } } @@ -875,19 +884,25 @@ function project_release_view($node, $te * Display a list of releases for a given project * @ingroup project_release_api */ -function project_release_project_releases() { - $node = node_load(arg(1)); - - // Breadcrumb navigation - $breadcrumb[] = l($node->title, 'node/'. $node->nid); - project_project_set_breadcrumb($node, $breadcrumb); - - $output = project_release_list($node); - - drupal_set_title(t('Releases for %project', array('%project' => $node->title))); - return $output; -} - + // @TODO: I believe we can remove this function since this is now + // provided by the project_release_by_project default view. + // However, we probably need to make sure the breadcrumb is + // properly set in that view. +//function project_release_project_releases($node) { +// // Breadcrumb navigation +// $breadcrumb[] = l($node->title, 'node/'. $node->nid); +// project_project_set_breadcrumb($node, $breadcrumb); +// +// $output = project_release_list($node); +// +// drupal_set_title(t('Releases for %project', array('%project' => $node->title))); +// return $output; +//} + +// @TODO: This function is used by project_issue, so we need to keep it here, even though +// we're now creating the list of releases at node/XXX/release using the views module. +// however, it might be nice if we could replace this function with views as well just to +// use views's query builder. Maybe that's a bad idea in terms of performance, however. /** * Get an array of release nodes * @ingroup project_release_api @@ -925,13 +940,15 @@ function project_release_get_releases($p $args = array($project->nid); if (!project_check_admin_access($project)) { if (!empty($rids)) { - $where = "AND (n.status = 1 OR n.nid IN (". implode(',', array_fill(0, count($rids), '%d')) ."))"; + $where = "AND (n.status = %d OR n.nid IN (". db_placeholders($rids) ."))"; + $args[] = 1; foreach ($rids as $rid) { $args[] = $rid; } } else { - $where = 'AND (n.status = 1)'; + $where = 'AND (n.status = %d)'; + $args[] = 1; } if ($filter_by == 'files') { $where .= " AND (r.file_path <> '')"; @@ -960,18 +977,20 @@ function project_release_get_releases($p * Returns a listing of project release nodes * @ingroup project_release_callback */ -function project_release_list($project, $main = 0) { - if ($releases = project_release_get_releases($project, 1, 'date', 'files')) { - $output = ''; - foreach ($releases as $release) { - $output .= node_view($release); - } - } - else { - $output = t('There are no published releases for this project.'); - } - return $output; -} + // @TODO: I believe we can remove this function since this is now + // provided by the project_release_by_project default view. +//function project_release_list($project, $main = 0) { +// if ($releases = project_release_get_releases($project, 1, 'date', 'files')) { +// $output = ''; +// foreach ($releases as $release) { +// $output .= node_view($release); +// } +// } +// else { +// $output = t('There are no published releases for this project.'); +// } +// return $output; +//} /** * Returns a listing of all active project release compatibility terms @@ -1025,32 +1044,32 @@ function project_release_version_filter_ ); $register = ''; if (variable_get('user_register', 1)) { - $register = ' or '. l(t('register'), 'user/register', array(), $destination) .' '; + $register = ' or '. l(t('register'), 'user/register', array('query' => $destination)) .' '; } - $form['version_login'] = array('#value' => l(t('Login'), 'user/login', array(), $destination) . $register . t('to modify the filter.')); + $form['version_login'] = array('#value' => l(t('Login'), 'user/login', array('query' => $destination)) . $register . t('to modify the filter.')); } $form['#redirect'] = FALSE; } return isset($form) ? $form : ''; } -function project_release_version_filter_form_submit($form_id, $form_values) { - if (isset($form_values['version_tid'])) { - $_SESSION['project_version'] = $form_values['version_tid']; +function project_release_version_filter_form_submit($form, &$form_state) { + if (isset($form_state['values']['version_tid'])) { + $_SESSION['project_version'] = $form_state['values']['version_tid']; } } -function project_release_version_filter_form_validate($form_id, $form_values, $form) { +function project_release_version_filter_form_validate($form, &$form_state) { global $user; - if (!$user->uid && $form_values['version_tid'] != variable_get('project_release_overview', -1)) { - $vocab = taxonomy_get_vocabulary(_project_release_get_api_vid()); + if (!$user->uid && $form_state['values']['version_tid'] != variable_get('project_release_overview', -1)) { + $vocab = taxonomy_vocabulary_load(_project_release_get_api_vid()); form_set_error('version_tid', t('You must login or register to modify the @vocab filter.', array('@vocab' => $vocab->name))); } } function theme_project_release_version_filter_form($form) { if (project_release_get_api_taxonomy()) { - $vocab = taxonomy_get_vocabulary(_project_release_get_api_vid()); + $vocab = taxonomy_vocabulary_load(_project_release_get_api_vid()); $label = check_plain($vocab->name); } else { @@ -1069,7 +1088,7 @@ function theme_project_release_version_f * Implementation of hook_form_alter(). * @ingroup project_release_fapi */ -function project_release_form_alter($form_id, &$form) { +function project_release_form_alter(&$form, &$form_state, $form_id) { if ($form_id == 'project_project_node_form') { return project_release_alter_project_form($form); } @@ -1090,14 +1109,13 @@ function project_release_alter_project_f /** * Releases subtab for the project edit tab. */ -function project_release_project_edit_releases() { - $node = node_load(arg(1)); +function project_release_project_edit_releases($node) { project_project_set_breadcrumb($node); drupal_set_title(check_plain($node->title)); return drupal_get_form('project_release_project_edit_form', $node); } -function project_release_project_edit_form($node) { +function project_release_project_edit_form($form_state, $node) { // Get all the data about major versions for this project. $data = _project_release_get_version_major_data($node); @@ -1110,7 +1128,7 @@ function project_release_project_edit_fo '#value' => t('Supported versions'), ); - $vocab = taxonomy_get_vocabulary(_project_release_get_api_vid()); + $vocab = taxonomy_vocabulary_load(_project_release_get_api_vid()); $form['help'] = array( '#type' => 'markup', '#value' => t('For each term in the %api_vocabulary_name vocabulary, the following tables allow you to define which major versions are supported. If there are releases from more than one major version number, you can select which major version should be recommended for new users to download. You can also control if the development snapshot releases should be displayed on the front page of the project. Finally, for each term in the %api_vocabulary_name vocabulary, the current recommended release is shown. If no official releases have been made, the development snapshot from the corresponding branch will be listed. Otherwise, the most recent official release will be listed.', array('%api_vocabulary_name' => $vocab->name)), @@ -1160,13 +1178,9 @@ function _project_release_get_version_ma $data['node'] = $node; $params = array(); $params[] = $node->nid; - $placeholders = array(); $active_tids = project_release_compatibility_list(); - foreach ($active_tids as $tid => $api_term) { - $placeholders[] = '%d'; - $params[] = $tid; - } - $tid_where = 'prsv.tid IN ('. implode(',', $placeholders) .')'; + $params = $params + array_keys($active_tids); + $tid_where = 'prsv.tid IN ('. db_placeholders($active_tids) .')'; $result = db_query("SELECT prsv.*, td.name AS term_name FROM {project_release_supported_versions} prsv INNER JOIN {term_data} td ON prsv.tid = td.tid WHERE prsv.nid = %d AND $tid_where ORDER BY td.weight, td.name", $params); while ($obj = db_fetch_object($result)) { $tid = $obj->tid; @@ -1186,7 +1200,8 @@ function _project_release_get_version_ma } function _project_release_edit_version_major_form($data) { - drupal_add_js(drupal_get_path('module', 'project_release') .'/project_release.js'); +// Since this form is used relatively infrequently, don't allow the js to be aggregated. + drupal_add_js(drupal_get_path('module', 'project_release') .'/project_release.js', 'module', 'header', FALSE, TRUE, FALSE); $form = array(); $node = $data['node']; @@ -1236,7 +1251,7 @@ function _project_release_edit_version_m '#default_value' => $recommended_version, '#attributes' => array('class'=>'recommended'), ); - $recommended_major = db_result(db_query("SELECT major FROM {project_release_supported_versions} WHERE nid = %d AND tid = %d AND recommended = 1", $node->nid, $api_tid)); + $recommended_major = db_result(db_query("SELECT major FROM {project_release_supported_versions} WHERE nid = %d AND tid = %d AND recommended = %d", $node->nid, $api_tid, 1)); if ($recommended_major !== FALSE) { $current_recommended = $form['api'][$api_tid]['major'][$recommended_major]['version_name']['#value']; } @@ -1310,12 +1325,12 @@ function theme_project_release_project_e * @ingroup project_release_fapi * @see project_release_project_edit_releases */ -function project_release_project_edit_form_validate($form_id, $form_values, $form) { - if (!empty($form_values['version_format'])) { - _project_release_validate_format_string($form_values, 'version_format'); +function project_release_project_edit_form_validate($form, &$form_state) { + if (!empty($form_state['values']['version_format'])) { + _project_release_validate_format_string($form_state['values'], 'version_format'); } - if (isset($form_values['api'])) { - foreach ($form_values['api'] as $tid => $api_info) { + if (isset($form_state['values']['api'])) { + foreach ($form_state['values']['api'] as $tid => $api_info) { $supported = FALSE; // First, we just iterate through to see if *any* majors are supported. foreach ($api_info['major'] as $major => $flags) { @@ -1329,15 +1344,15 @@ function project_release_project_edit_fo foreach ($api_info['major'] as $major => $flags) { if (empty($flags['supported']) && !empty($flags['snapshot'])) { $element = 'api]['. $tid .'][major]['. $major .'][snapshot'; - form_set_error($element, t('You can not show a snapshot release for a major version that is not supported for %api_term_name.', array('%api_term_name' => $form['api'][$tid]['#api_term_name']))); + form_set_error($element, t('You can not show a snapshot release for a major version that is not supported for %api_term_name.', array('%api_term_name' => $form_state['values']['api'][$tid]['#api_term_name']))); } } $recommended = $api_info['recommended']; if ($recommended < 0) { - form_set_error("api][$tid][recommended", t('You must select a recommended major version for %api_term_name.', array('%api_term_name' => $form['api'][$tid]['#api_term_name']))); + form_set_error("api][$tid][recommended", t('You must select a recommended major version for %api_term_name.', array('%api_term_name' => $form_state['values']['api'][$tid]['#api_term_name']))); } elseif (empty($api_info['major'][$recommended]['supported'])) { - form_set_error("api][$tid][recommended", t('You can not recommend a major version that is not supported for %api_term_name.', array('%api_term_name' => $form['api'][$tid]['#api_term_name']))); + form_set_error("api][$tid][recommended", t('You can not recommend a major version that is not supported for %api_term_name.', array('%api_term_name' => $form_state['values']['api'][$tid]['#api_term_name']))); } } } @@ -1349,12 +1364,12 @@ function project_release_project_edit_fo * @ingroup project_release_fapi * @see project_release_project_edit_releases */ -function project_release_project_edit_form_submit($form_id, $form_values) { - $nid = $form_values['nid']; - db_query("UPDATE {project_release_projects} SET releases = %d, version_format = '%s' WHERE nid = %d", $form_values['releases'], $form_values['version_format'], $nid); +function project_release_project_edit_form_submit($form, &$form_state) { + $nid = $form_state['values']['nid']; + db_query("UPDATE {project_release_projects} SET releases = %d, version_format = '%s' WHERE nid = %d", $form_state['values']['releases'], $form_state['values']['version_format'], $nid); - if (!empty($form_values['api'])) { - foreach ($form_values['api'] as $tid => $values) { + if (!empty($form_state['values']['api'])) { + foreach ($form_state['values']['api'] as $tid => $values) { if (isset($values['recommended'])) { $recommended_major = $values['recommended']; } @@ -1376,9 +1391,9 @@ function project_release_project_edit_fo } } } - db_query("UPDATE {node} SET changed = %d WHERE nid = %d", time(), $form_values['nid']); + db_query("UPDATE {node} SET changed = %d WHERE nid = %d", time(), $form_state['values']['nid']); - $cid = 'table:'. $form_values['nid'] .':'; + $cid = 'table:'. $form_state['values']['nid'] .':'; cache_clear_all($cid, 'cache_project_release', TRUE); drupal_set_message(t('Release settings have been saved.')); @@ -1446,7 +1461,7 @@ function project_release_alter_release_f } // If there are no children elements, we should unset the entire // thing so we don't end up with an empty fieldset. - if (!element_children($form['taxonomy'])) { + if (isset($form['taxonomy']) && !element_children($form['taxonomy'])) { unset($form['taxonomy']); } } @@ -1483,13 +1498,15 @@ function project_release_project_nodeapi switch ($op) { case 'load': $project = db_fetch_object(db_query('SELECT * FROM {project_release_projects} WHERE nid = %d', $node->nid)); - $fields = array('releases', 'version_format'); - foreach ($fields as $field) { - $node->$field = $project->$field; - } - $wants_snapshots = db_result(db_query('SELECT tid FROM {project_release_supported_versions} WHERE nid = %d AND snapshot = 1 LIMIT 1', $node->nid)); - if (isset($wants_snapshots)) { - $node->project_release_show_snapshots = TRUE; + if (!empty($project)) { + $fields = array('releases', 'version_format'); + foreach ($fields as $field) { + $node->$field = $project->$field; + } + $wants_snapshots = db_result(db_query('SELECT tid FROM {project_release_supported_versions} WHERE nid = %d AND snapshot = %d LIMIT %d', $node->nid, 1, 1)); + if (isset($wants_snapshots)) { + $node->project_release_show_snapshots = TRUE; + } } break; @@ -1569,15 +1586,17 @@ function project_release_get_current_rec $join = ' INNER JOIN {term_node} tn ON n.nid = tn.nid AND tn.tid = %d'; $params[] = $api_tid; - $where = 'WHERE (r.pid = %d) AND (n.status = 1)'; + $where = 'WHERE (r.pid = %d) AND (n.status = %d)'; $params[] = $project_nid; + $params[] = 1; if (isset($recommended_major)) { $where .= ' AND (r.version_major = %d)'; $params[] = $recommended_major; } else { - $join .= ' INNER JOIN {project_release_supported_versions} prsv ON prsv.nid = r.pid AND prsv.tid = tn.tid AND prsv.major = r.version_major AND prsv.recommended = 1 '; + $join .= ' INNER JOIN {project_release_supported_versions} prsv ON prsv.nid = r.pid AND prsv.tid = tn.tid AND prsv.major = r.version_major AND prsv.recommended = %d '; + $params[] = 1; } // We always want the dev snapshots to show up last. @@ -1588,10 +1607,11 @@ function project_release_get_current_rec $orderby[] = 'r.file_date DESC'; $order_by = 'ORDER BY '. implode(', ', $orderby); + $params[] = 1; $result = db_query(db_rewrite_sql( "SELECT n.nid, n.title, n.created, r.* FROM {node} n ". "INNER JOIN {project_release_nodes} r ON r.nid = n.nid $join ". - "$where $order_by LIMIT 1"), $params); + "$where $order_by LIMIT %d"), $params); $release = db_fetch_object($result); $current_major[$project_nid][$api_tid][$major] = $release; @@ -1602,7 +1622,7 @@ function project_release_get_current_rec * Theme the appropriate release download table for a project node. */ function theme_project_release_project_download_table($node) { - if (!$node->releases) { + if (empty($node->releases)) { return; } $output = '

'. t('Releases') .'

'; @@ -1615,6 +1635,8 @@ function theme_project_release_project_d /** * Implemenation of hook_project_page_link_alter(). + * + * Note: This is *not* an implementation of hook_link_alter(). */ function project_release_project_page_link_alter($node, &$all_links) { $all_links['project_release'] = array( @@ -1686,14 +1708,16 @@ function project_release_table($project, return $cached->data; } - $select = $join = $where = $order_by = ''; + $selects = $join = $where = $order_by = ''; + $args = array(); $tids = project_release_compatibility_list(); if ($tids) { unset($tids[-1]); // get rid of that one. if (!empty($tids)) { $join = ' INNER JOIN {term_node} tn ON n.nid = tn.nid AND tn.tid in (' - . implode(',', array_keys($tids)) .') ' + . db_placeholders($tids) .') ' .' INNER JOIN {term_data} td ON td.tid = tn.tid '; + $args = array_keys($tids); $selects[] = 'tn.tid'; $selects[] = 'td.name as api_term_name'; $orderby[] = 'td.weight'; @@ -1707,24 +1731,31 @@ function project_release_table($project, $selects[] = 'prsv.snapshot'; $join .= ' INNER JOIN {project_release_supported_versions} prsv ON prsv.nid = r.pid AND prsv.tid = tn.tid AND prsv.major = r.version_major '; if ($table_type == 'recommended') { - $join .= 'AND prsv.recommended = 1 '; + $join .= 'AND prsv.recommended = %d '; + $args[] = 1; } elseif ($table_type == 'supported') { - $join .= 'AND prsv.supported = 1 '; + $join .= 'AND prsv.supported = %d '; + $args[] = 1; } } else { // TODO: someday (never?) when project_release doesn't require taxonomy. } + $args[] = $project->nid; // Account for r.pid. + $args[] = 1; // Account for n.status = 1. switch ($release_type) { case 'official': - $where = 'AND r.rebuild <> 1'; + $where = 'AND r.rebuild <> %d'; + $args[] = 1; break; case 'snapshot': // For snapshot tables, restrict to snapshot nodes from branches where // the maintainer wants the snapshot visible. - $where = 'AND r.rebuild = 1 AND prsv.snapshot = 1'; + $where = 'AND r.rebuild = %d AND prsv.snapshot = %d'; + $args[] = 1; + $args[] = 1; break; case 'all': // If we're generating the default releases table, we want the @@ -1751,8 +1782,8 @@ function project_release_table($project, $result = db_query(db_rewrite_sql( "SELECT n.nid, n.created, $select r.* FROM {node} n ". "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); + "WHERE (r.pid = %d) AND (n.status = %d) $where $order_by"), + $args); $rows = array(); // Rows for the download table. $seen = array(); // Keeps track of which versions we already saw. @@ -1825,7 +1856,7 @@ function project_release_table($project, $output = theme('table', $header, $rows, array('class' => 'releases')); } // Default cache time is 12 hours - will be cleared by the packaging script - cache_set($cid, 'cache_project_release', $output, time() + 43200); + cache_set($cid, $output, 'cache_project_release', time() + 43200); return $output; } @@ -2046,6 +2077,7 @@ function project_release_exists($version return false; } + $taxo_join = $taxo_where = ''; if (isset($version->version_api_tid)) { $taxo_join = ' INNER JOIN {term_node} t ON p.nid = t.nid'; $taxo_where = ' AND t.tid = %d'; @@ -2053,14 +2085,14 @@ function project_release_exists($version $tid = $version->version_api_tid; } - $sql = 'SELECT * FROM {project_release_nodes} p'. $taxo_join .' WHERE p.pid = %d'; + $sql = 'SELECT COUNT(*) FROM {project_release_nodes} p'. $taxo_join .' WHERE p.pid = %d'; foreach ($types as $field => $type) { $sql .= " AND p.$field = $type"; } $sql .= $taxo_where; // we put pid as the first WHERE, so stick it on the front $values = array_merge(array('pid' => $version->pid), $values); - return db_num_rows(db_query($sql, $values)); + return db_result(db_query($sql, $values)); } /** @@ -2166,16 +2198,104 @@ function project_release_pick_project_fo return $form; } -function project_release_pick_project_form_validate($form_id, $form_values) { - if (empty($form_values['pid'])) { +function project_release_pick_project_form_validate($form, &$form_state) { + if (empty($form_state['values']['pid'])) { form_set_error('pid', t('You must select a project.')); } - $node = node_load($form_values['pid']); + $node = node_load($form_state['values']['pid']); if (empty($node) || $node->type != 'project_project') { form_set_error('pid', t('Invalid project selected.')); } } -function project_release_pick_project_form_submit($form_id, $form_values) { - return 'node/add/project-release/'. $form_values['pid']; +function project_release_pick_project_form_submit($form, &$form_state) { + $form_state['redirect'] = 'node/add/project-release/'. $form_state['values']['pid']; +} + +/** + * Implementation of hook_theme(). + */ +function project_release_theme() { + return array( + 'project_release_download_link' => array( + 'arguments' => array( + 'file_path' => NULL, + 'link_text' => NULL, + 'as_array' => FALSE, + ), + ), + 'project_release_download_table_row' => array( + 'arguments' => array( + 'release' => NULL, + 'recommended' => FALSE, + 'can_edit' => FALSE, + 'print_size' => TRUE, + ), + ), + 'project_release_download_text_recommended' => array( + 'arguments' => array( + 'release' => NULL, + 'text_type' => NULL, + ), + ), + 'project_release_download_text_snapshot' => array( + 'arguments' => array( + 'release' => NULL, + 'text_type' => NULL, + ), + ), + 'project_release_download_text_supported' => array( + 'arguments' => array( + 'release' => NULL, + 'text_type' => NULL, + ), + ), + 'project_release_download_text_unsupported' => array( + 'arguments' => array( + 'release' => NULL, + 'text_type' => NULL, + ), + ), + 'project_release_form_value' => array( + 'arguments' => array( + 'element' => NULL, + ), + ), + 'project_release_project_download_table' => array( + 'arguments' => array( + 'node' => NULL, + ), + ), + 'project_release_project_edit_form' => array( + 'arguments' => array( + 'form' => NULL, + ), + ), + 'project_release_table_overview' => array( + 'arguments' => array( + 'project' => NULL, + 'table_type' => NULL, + 'release_type' => NULL, + 'title' => NULL, + 'print_size' => NULL, + ), + ), + 'project_release_version_filter_form' => array( + 'arguments' => array( + 'form' => NULL, + ), + ), + 'project_release_node_form_version_elements' => array( + 'arguments' => array( + 'form' => NULL, + ), + ), + ); +} + +function theme_project_release_node_form_version_elements($form) { + $output = '
'; + $output .= drupal_render($form); + $output .= '
'; + return $output; } Index: release/project_release.views.inc =================================================================== RCS file: release/project_release.views.inc diff -N release/project_release.views.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ release/project_release.views.inc 20 Jun 2008 23:17:53 -0000 @@ -0,0 +1,126 @@ + array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + + 'project_projects' => array( + 'type' => 'INNER', + 'left_table' => 'project_projects', + 'left_field' => 'nid', + 'field' => 'pid', + ) + ); + + // pid + $data['project_release_nodes']['pid'] = array( + 'title' => t('Pid'), + 'help' => t('The node ID of the project node a release is tied to.'), + 'field' => array( + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + // Information for accepting a nid as an argument + 'argument' => array( + 'handler' => 'views_handler_argument_node_nid', + 'name field' => 'title', + 'numeric' => TRUE, + 'validate type' => 'nid', + ), + // Information for accepting a nid as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + // Information for sorting on a nid. + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // version + $data['project_release_nodes']['version'] = array( + 'title' => t('Version string'), + 'help' => t('The full version string of a release.'), + 'field' => array( + 'group' => t('Project release'), + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // tag + $data['project_release_nodes']['tag'] = array( + 'title' => t('Tag'), + 'help' => t('The tag associated with a release.'), + 'field' => array( + 'group' => t('Project release'), + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // @TODO: file_path + // @TODO: file_date + // @TODO: file_hash + // @TODO: rebuild + // @TODO: version_major + // @TODO: version_minor + // @TODO: version_patch + // @TODO: version_extra + + + return $data; +} + + Index: release/project_release.views_default.inc =================================================================== RCS file: release/project_release.views_default.inc diff -N release/project_release.views_default.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ release/project_release.views_default.inc 20 Jun 2008 23:17:53 -0000 @@ -0,0 +1,317 @@ +name = 'project_release_by_project'; + $view->description = 'List the project release nodes associated with a particular project.'; + $view->tag = 'project,releases'; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = '0'; + $view->api_version = 2; + $view->disabled = FALSE; // Edit this to true to make a default view disabled initially + $view->display = array(); + $display = new views_display; + $display->id = 'default'; + $display->display_title = 'Defaults'; + $display->display_plugin = 'default'; + $display->position = '1'; + $display->display_options = array( + 'style_plugin' => 'default', + 'style_options' => array(), + 'row_plugin' => 'node', + 'row_options' => array( + 'teaser' => 1, + 'links' => 1, + ), + 'relationships' => array(), + 'fields' => array( + 'nid' => array( + 'id' => 'nid', + 'table' => 'node', + 'field' => 'nid', + 'label' => 'Nid', + 'relationship' => 'none', + 'link_to_node' => 0, + ), + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => 'Title', + 'relationship' => 'none', + 'link_to_node' => 0, + ), + 'version' => array( + 'id' => 'version', + 'table' => 'project_release_nodes', + 'field' => 'version', + 'label' => 'Version string', + 'relationship' => 'none', + 'link_to_node' => 1, + ), + ), + 'sorts' => array( + 'created' => array( + 'id' => 'created', + 'table' => 'node', + 'field' => 'created', + 'order' => 'DESC', + 'granularity' => 'day', + 'relationship' => 'none', + ), + 'name' => array( + 'id' => 'name', + 'table' => 'term_data', + 'field' => 'name', + 'order' => 'DESC', + 'relationship' => 'none', + ), + ), + 'arguments' => array( + 'pid' => array( + 'id' => 'pid', + 'table' => 'project_release_nodes', + 'field' => 'pid', + 'default_action' => 'not found', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => 'Releases for %1', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'node', + 'validate_fail' => 'not found', + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'project_project' => 'project_project', + 'project_release' => 0, + 'book' => 0, + 'page' => 0, + 'story' => 0, + ), + 'validate_argument_vocabulary' => array( + '3' => 0, + '5' => 0, + '2' => 0, + '1' => 0, + '4' => 0, + ), + 'validate_argument_type' => 'tid', + 'validate_argument_php' => '', + 'default_argument_user' => 0, + 'validate_argument_node_access' => 1, + 'validate_argument_nid_type' => 'nid', + 'break_phrase' => 0, + 'not' => 0, + ), + ), + 'filters' => array( + 'type' => array( + 'id' => 'type', + 'table' => 'node', + 'field' => 'type', + 'operator' => 'in', + 'value' => array( + 'project_release' => 'project_release', + ), + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Expose', + ), + ), + 'tid' => array( + 'id' => 'tid', + 'table' => 'term_node', + 'field' => 'tid', + 'operator' => 'or', + 'value' => array(), + 'group' => 0, + 'exposed' => TRUE, + 'expose' => array( + 'operator' => '', + 'identifier' => 'api', + 'label' => 'API Version', + 'optional' => 1, + 'single' => 0, + 'remember' => 1, + ), + 'type' => 'select', + 'vid' => '2', + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Hide', + ), + 'reduce_duplicates' => 0, + ), + 'status' => array( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => 1, + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + 'expose_button' => array( + 'button' => 'Expose', + ), + ), + ), + 'items_per_page' => 20, + 'offset' => 0, + 'access' => array( + 'type' => 'perm', + 'role' => array( + '3' => 0, + '1' => 0, + '2' => 0, + '6' => 0, + '5' => 0, + '4' => 0, + '7' => 0, + ), + 'perm' => 'access projects', + ), + 'use_pager' => '1', + 'pager_element' => 0, + 'empty' => 'There are no published releases for this project.', + 'empty_format' => '1', + ); + $view->display['default'] = $display; + $display = new views_display; + $display->id = 'page'; + $display->display_title = 'Releases for *project*'; + $display->display_plugin = 'page'; + $display->position = '2'; + $display->display_options = array( + 'defaults' => array( + 'access' => TRUE, + 'title' => TRUE, + 'header' => TRUE, + 'header_format' => TRUE, + 'header_empty' => TRUE, + 'footer' => TRUE, + 'footer_format' => TRUE, + 'footer_empty' => TRUE, + 'empty' => TRUE, + 'empty_format' => TRUE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'offset' => TRUE, + 'use_pager' => TRUE, + 'pager_element' => TRUE, + 'use_more' => TRUE, + 'distinct' => TRUE, + 'link_display' => TRUE, + 'style_plugin' => TRUE, + 'style_options' => TRUE, + 'row_plugin' => TRUE, + 'row_options' => TRUE, + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => TRUE, + 'arguments' => TRUE, + 'filters' => TRUE, + ), + 'relationships' => array(), + 'fields' => array(), + 'sorts' => array(), + 'arguments' => array(), + 'filters' => array(), + 'path' => 'node/%/release', + 'menu' => array( + 'type' => 'none', + 'title' => 'Test title', + 'weight' => '0', + ), + ); + $view->display['page'] = $display; + $display = new views_display; + $display->id = 'feed'; + $display->display_title = 'Feed'; + $display->display_plugin = 'feed'; + $display->position = '3'; + $display->display_options = array( + 'defaults' => array( + 'access' => TRUE, + 'title' => TRUE, + 'header' => TRUE, + 'header_format' => TRUE, + 'header_empty' => TRUE, + 'footer' => TRUE, + 'footer_format' => TRUE, + 'footer_empty' => TRUE, + 'empty' => TRUE, + 'empty_format' => TRUE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'offset' => TRUE, + 'use_pager' => TRUE, + 'pager_element' => TRUE, + 'use_more' => TRUE, + 'distinct' => TRUE, + 'link_display' => TRUE, + 'style_plugin' => FALSE, + 'style_options' => FALSE, + 'row_plugin' => FALSE, + 'row_options' => FALSE, + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => TRUE, + 'arguments' => TRUE, + 'filters' => TRUE, + ), + 'relationships' => array(), + 'fields' => array(), + 'sorts' => array(), + 'arguments' => array(), + 'filters' => array(), + 'displays' => array( + 'default' => 0, + 'page' => 0, + ), + 'style_plugin' => 'rss', + 'style_options' => array( + 'mission_description' => FALSE, + 'description' => '', + ), + 'row_plugin' => 'node_rss', + 'path' => 'node/%/release/feed', + 'row_options' => array( + 'item_length' => 'default', + ), + ); + $view->display['feed'] = $display; + $views[$view->name] = $view; + + return $views; +} \ No newline at end of file Index: usage/project_usage.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/project/usage/project_usage.install,v retrieving revision 1.4 diff -u -p -r1.4 project_usage.install --- usage/project_usage.install 11 Jun 2008 02:50:24 -0000 1.4 +++ usage/project_usage.install 20 Jun 2008 23:17:53 -0000 @@ -1,61 +1,15 @@ t('Table used to store raw usage information.'), + 'fields' => array( + 'project_uri' => array( + 'description' => t('Primary Key: The {project_projects}.uri short name of the project.'), + 'type' => 'varchar', + 'length' => 50, + 'not null' => TRUE, + 'default' => '', + ), + 'timestamp' => array( + 'description' => t('Primary Key: The Unix timestamp of when the request was made.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'site_key' => array( + 'description' => t('Primary Key: An MD5 hash that identifies the site from which the request was made.'), + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + 'api_version' => array( + 'description' => t('The {term_data}.name of the API version requested.'), + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + 'project_version' => array( + 'description' => t('The {project_release_nodes}.version of the requested project.'), + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'pid' => array( + 'description' => t('The {node}.nid of the requested project.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'nid' => array( + 'description' => t('The {node}.nid of the requested release.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'tid' => array( + 'description' => t('The {term_data}.tid of the API compatability version of the requested release.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'ip_addr' => array( + 'description' => t('IP address to prevent abuse of the usage tracking system.'), + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'primary key' => array('timestamp', 'project_uri', 'site_key'), + ); - // Since this might take a long time, if we're not in 'safe mode', increase - // the maximum execution time. - if (!ini_get('safe_mode')) { - set_time_limit(240); - } + $schema['project_usage_day'] = array( + 'description' => t('Table used to store daily usage information.'), + 'fields' => array( + 'timestamp' => array( + 'description' => t('Primary Key: The Unix timestamp of when the request was made.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'site_key' => array( + 'description' => t('Primary Key: An MD5 hash that identifies the site from which the request was made.'), + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + 'pid' => array( + 'description' => t('Primary Key: The {node}.nid of the requested project.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'nid' => array( + 'description' => t('The {node}.nid of the requested release.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'tid' => array( + 'description' => t('The {term_data}.tid of the API compatability version of the requested release.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'ip_addr' => array( + 'description' => t('IP address to prevent abuse of the usage tracking system.'), + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'primary key' => array('timestamp', 'site_key', 'pid'), + ); - // Key is table name, value is function used to round the timestamp. - $tables = array( - 'project_usage_week_project' => 'project_usage_weekly_timestamp', - 'project_usage_week_release' => 'project_usage_weekly_timestamp', - 'project_usage_raw' => 'project_usage_daily_timestamp', - 'project_usage_day' => 'project_usage_daily_timestamp', + $schema['project_usage_week_project'] = array( + 'description' => t('Table used to store weekly usage information by project and {term_data}.tid.'), + 'fields' => array( + 'nid' => array( + 'description' => t('Primary Key: The {node}.nid of the project.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'timestamp' => array( + 'description' => t('Primary Key: A Unix timestamp.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'tid' => array( + 'description' => t('Primary Key: The {term_data}.tid of the API compatability version of the release.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'count' => array( + 'description' => t('The number of requests.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('nid', 'timestamp', 'tid'), ); - foreach ($tables as $table => $rounding_function) { - $query = db_query("SELECT DISTINCT timestamp FROM {$table} ORDER BY timestamp ASC"); - while ($row = db_fetch_object($query)) { - $old = (int) $row->timestamp; - $new = (int) $rounding_function($old); - if ($old != $new) { - $ret[] = update_sql("UPDATE {$table} SET timestamp = $new WHERE timestamp = $old"); - } - } - } - return $ret; + $schema['project_usage_week_release'] = array( + 'description' => t('Table used to store weekly usage information by project and {term_data}.tid.'), + 'fields' => array( + 'nid' => array( + 'description' => t('Primary Key: The {node}.nid of the project.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'timestamp' => array( + 'description' => t('Primary Key: A Unix timestamp.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'count' => array( + 'description' => t('The number of requests.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('nid', 'timestamp'), + ); + return $schema; } /** @@ -107,12 +216,20 @@ function project_usage_update_5000() { */ function project_usage_update_5001() { $ret = array(); - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - $ret[] = update_sql("ALTER TABLE {project_usage_raw} ADD COLUMN ip_addr varchar(128) NOT NULL default '' AFTER tid"); - $ret[] = update_sql("ALTER TABLE {project_usage_day} ADD COLUMN ip_addr varchar(128) NOT NULL default '' AFTER tid"); - break; - } + // @TODO These were specified "AFTER tid". Is there any way to do the same in schemaAPI? + db_add_field($ret, 'project_usage_raw', 'ip_addr', array( + 'description' => t('IP address to prevent abuse of the usage tracking system.'), + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + )); + db_add_field($ret, 'project_usage_day', 'ip_addr', array( + 'description' => t('IP address to prevent abuse of the usage tracking system.'), + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + )); return $ret; }