[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/project/release/includes/ -> release_node_form.inc (source)

   1  <?php
   2  // $Id: release_node_form.inc,v 1.11 2010/01/30 02:33:40 dww Exp $
   3  
   4  /**
   5   * @file
   6   * Code required for the release node form.
   7   */
   8  
   9  /**
  10   * Private helper to implement hook_form().
  11   *
  12   * Create the project release node form.
  13   */
  14  function _project_release_form(&$release, &$form_state) {
  15    if (arg(1) == 'add') {
  16      // Initialize variables and $release object properties to prevent notices.
  17      $is_edit = FALSE;
  18      $admin = NULL;
  19      $pid = (integer) arg(3);
  20      $project = node_load($pid);
  21      if (!isset($project) || $project->type != 'project_project') {
  22        drupal_set_message(t('Node %nid is not a valid project.', array('%nid' => $pid)), 'error');
  23        drupal_goto('node/add/project-release');
  24      }
  25      // Make sure this user should have permissions to add releases for
  26      // the requested project
  27      if (!project_check_admin_access($project)) {
  28        drupal_access_denied();
  29        module_invoke_all('exit');
  30        exit;
  31      }
  32      project_project_set_breadcrumb($project, TRUE);
  33      $format = project_release_get_version_format($project);
  34      $release->project_release['pid'] = $pid;
  35    }
  36    else {
  37      global $user;
  38      $admin = user_access('administer projects');
  39      $is_edit = TRUE;
  40      $project = node_load($release->project_release['pid']);
  41      $breadcrumb[] = l($project->title, 'node/'. $project->nid);
  42      $breadcrumb[] = l(t('Releases'), 'node/'. $project->nid . '/release');
  43      project_project_set_breadcrumb($project, $breadcrumb);
  44      $format = project_release_get_version_format($project);
  45    }
  46    $form['project'] = array(
  47      '#type' => 'value',
  48      '#value' => $project,
  49    );
  50  
  51    $modify = $admin || !$is_edit;
  52  
  53    $form['#attributes'] = array("enctype" => "multipart/form-data");
  54  
  55    if ($is_edit) {
  56      $form['rel_id'] = array(
  57        '#type' => 'fieldset',
  58        '#title' => t('Release identification'),
  59        '#weight' => -4,
  60        '#collapsible' => TRUE,
  61        '#theme' => 'project_release_node_form_version_elements',
  62      );
  63    }
  64    _project_release_form_add_text_element($form['rel_id']['title'], t('Title'), $release->title, $is_edit, $admin, TRUE, 40, 128);
  65    if (!empty($release->project_release['version'])) {
  66      _project_release_form_add_text_element($form['rel_id']['version'], t('Version string'), $release->project_release['version'], $is_edit, $admin, TRUE, 20, 255);
  67    }
  68    // The version string belongs in $node->project_release[], so we set
  69    // #parents to ensure the form value is placed there during validate,
  70    // preview, and submit.
  71    $form['rel_id']['version']['#parents'] = array('project_release', 'version');
  72  
  73    $form['project_release'] = array(
  74      '#type' => 'fieldset',
  75      '#tree' => TRUE,
  76      '#title' => t('Version number elements'),
  77      '#collapsible' => TRUE,
  78      '#theme' => 'project_release_node_form_version_elements',
  79    );
  80  
  81    if (!empty($release->project_release['pid'])) {
  82      $pid = $release->project_release['pid'];
  83    }
  84    elseif (!empty($form_state['values']['project_release']['pid'])) {
  85      $pid = $form_state['values']['project_release']['pid'];
  86    }
  87    // else?
  88    $form['project_release']['pid'] = array(
  89      '#type' => 'value',
  90      '#value' => $pid,
  91    );
  92  
  93    $form['validate_version'] = array('#type' => 'value', '#value' => 1);
  94    _project_release_form_add_version_element($form, $release, $modify, $format, 'major', t('Major'));
  95    _project_release_form_add_version_element($form, $release, $modify, $format, 'minor', t('Minor'));
  96    _project_release_form_add_version_element($form, $release, $modify, $format, 'patch', t('Patch-level'));
  97    _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);
  98  
  99    // A boolean to indicate if this release should be regularly rebuilt
 100    // (e.g. from a revision control branch) or not (e.g. an official release
 101    // from a tag).  There's no UI for this field, since it's only used if a
 102    // revision-control integration module is enabled.
 103    $form['project_release']['rebuild'] = array(
 104      '#type' => 'value',
 105      '#value' => !empty($release->project_release['rebuild']),
 106    );
 107  
 108    $form['project_release_files'] = array(
 109      '#type' => 'fieldset',
 110      '#tree' => TRUE,
 111      '#title' => t('File information'),
 112      '#collapsible' => TRUE,
 113    );
 114  
 115    if (!empty($release->project_release['files'])) {
 116      $files = $release->project_release['files'];
 117      foreach ($files as $fid => $file) {
 118        // In the case of previews, we only have the fid of the file,
 119        // so check for that and load the file object if necessary.
 120        if (is_numeric($file)) {
 121          $file = project_release_load_file($file);
 122        }
 123        $form['project_release_files'][$fid]['file_info'] = array(
 124          '#value' => theme('project_release_download_file', $file, FALSE),
 125        );
 126        if ($admin) {
 127          $form['project_release_files'][$fid]['delete'] = array(
 128            '#type' => 'checkbox',
 129            '#title' => t('Delete @filename', array('@filename' => $file->filename)),
 130            '#default_value' => isset($release->project_release_files[$fid]['delete']) ? $release->project_release_files[$fid]['delete'] : 0,
 131            // TODO: we'll need to rip this out when multiple files lands.
 132            '#description' => (isset($files) ? t('In order to add a new file, you must first delete %filename.', array('%filename' => $file->filename)) : ''),
 133          );
 134        }
 135        // Store the fid here in the proper $node->project_release[] array
 136        // so it can be used to generate file previews.
 137        $form['project_release']['files'][$fid] = array(
 138          '#type' => 'value',
 139          '#value' => $fid,
 140        );
 141      }
 142    }
 143  
 144    // TODO: we'll need to rip out the conditional when multiple files lands.
 145    if (!isset($files)) {
 146      // In case of previews, get any uploaded file info.
 147      if (isset($form_state['project_release']['new_file'])) {
 148        $new_file = $form_state['project_release']['new_file'];
 149      }
 150      elseif (!empty($release->project_release_files['temp'])) {
 151        $new_file = db_fetch_object(db_query("SELECT * FROM {files} WHERE fid = %d", $release->project_release_files['temp']));
 152      }
 153      $form['project_release_files']['file'] = array(
 154        '#title' => t('File'),
 155        '#type' => 'file',
 156        '#description' => isset($new_file) ? t('A file named %filename has already been uploaded. If you upload another file %filename will be replaced.', array('%filename' => $new_file->filename)) : t('Choose a file that will be associated with this release.'),
 157      );
 158      // Account for already uploaded files being previewed.
 159      if (isset($new_file)) {
 160        $form['project_release_files']['temp'] = array(
 161          '#type' => 'value',
 162          '#value' => $new_file->fid,
 163        );
 164      }
 165    }
 166  
 167    $form['body_field'] = node_body_field($release, t('Release notes'), !$admin);
 168    // Add a description to the body field.
 169    $form['body_field']['body']['#description'] = t('Enter a description of this release, such as a list of the major changes or updates.');
 170  
 171    $tag = isset($release->project_release['tag']) ? $release->project_release['tag'] : '';
 172    _project_release_form_add_text_element($form['tag']['tag'], t('Tag'), $tag, $is_edit, $admin, TRUE, 40, 255);
 173    $form['tag']['tag']['#parents'] = array('project_release', 'tag');
 174  
 175    // Add a custom validation function.
 176    $form['#validate'][] = 'project_release_node_form_validate';
 177    return $form;
 178  }
 179  
 180  /**
 181   * Modifies the given $form array to add the appropriate form element
 182   * for the requested version field. Since the 20+ lines of code in
 183   * here have to be duplicated 6 times in project_release_form(), this
 184   * function exists so we can reuse the code.
 185   * @see project_release_form
 186   * @ingroup project_release_internal
 187   *
 188   * @param $form Form array to modify
 189   * @param $release Relase node the form is for
 190   * @param $modify Boolean indicating if we should allow modifications
 191   * @param $format Version format string for this project
 192   * @param $name Name of this version element
 193   * @param $title Translatable title of the form element
 194   * @param $description Translatable description of the form element.
 195   * @param $size Size of the form element
 196   * @param $required Boolean for if the form element should be required
 197   */
 198  function _project_release_form_add_version_element(&$form, $release, $modify, $format, $name, $title, $description = '', $size = 10, $required = FALSE) {
 199    $var_name = 'version_'. $name;
 200    $regexp = "@.*[!#%]$name.*@";
 201    if (preg_match($regexp, $format)) {
 202      $form['project_release'][$var_name] = array(
 203        '#type' => 'textfield',
 204        '#title' => $title,
 205        '#default_value' => isset($release->project_release[$var_name]) ? $release->project_release[$var_name] : '',
 206        '#size' => $size,
 207        '#maxlength' => $size + 10,
 208        '#attributes' => array('style' => 'width:auto'),
 209      );
 210      if ($required) {
 211        // TODO: handle this more flexibly for sites not using CVS
 212        // perhaps if the format variable is UPPERCASE it's required,
 213        // and lowercase is optional or something crazy?
 214        $form[$var_name]['#required'] = TRUE;
 215      }
 216      if ($description) {
 217        $form['project_release'][$var_name]['#description'] = $description;
 218      }
 219      if (!$modify) {
 220        $form['project_release'][$var_name]['#attributes'] = array('disabled' => 'disabled');
 221        $form['project_release'][$var_name]['#value'] = $release->project_release[$var_name];
 222      }
 223    }
 224    else {
 225      $form['project_release'][$var_name] = array(
 226        '#type' => 'value',
 227        '#value' => isset($release->project_release[$var_name]) ? $release->project_release[$var_name] : '',
 228      );
 229    }
 230  }
 231  
 232  /**
 233   * Modifies the given $form array to add the appropriate form element
 234   * for the desired text field. Since the 16+ lines of code in here
 235   * have to be duplicated 5 times in project_release_form(), this
 236   * function exists so we can reuse the code.
 237   * @see project_release_form
 238   * @ingroup project_release_internal
 239   *
 240   * @param $form
 241   *   Reference to form element to add.
 242   * @param $title
 243   *   Translatable title of the form element.
 244   * @param $value
 245   *   The value to use in the form.
 246   * @param $is_edit
 247   *   Boolean indicating if we're editing or creating.
 248   * @param $admin
 249   *   Boolean for if the edit is by a project administrator.
 250   * @param $required
 251   *   Boolean for if the field should be required.
 252   * @param $size
 253   *   Value to use for the '#size' property.
 254   * @param $maxlength
 255   *   Value to use for the '#maxlength' property.
 256   */
 257  function _project_release_form_add_text_element(&$form, $title, $value, $is_edit, $admin, $required = TRUE, $size = 40, $maxlength = 50) {
 258    if ($is_edit && !empty($value)) {
 259      $form = array(
 260        '#type' => 'textfield',
 261        '#title' => $title,
 262        '#default_value' => $value,
 263        '#required' => $required,
 264        '#size' => $size,
 265        '#maxlength' => $maxlength,
 266      );
 267      if(!$admin) {
 268        $form['#attributes']['disabled'] = 'disabled';
 269        $form['#value'] = $value;
 270      }
 271    }
 272    else {
 273      $form = array(
 274        '#type' => 'value',
 275        '#value' => $value,
 276      );
 277    }
 278  }
 279  
 280  /**
 281   * Private callback to validate a release node form.
 282   *
 283   * @see project_release_node_form_validate()
 284   */
 285  function _project_release_node_form_validate(&$form, &$form_state) {
 286    global $user;
 287    $project_release = $form_state['values']['project_release'];
 288    if (!empty($form_state['values']['validate_version'])) {
 289      if (!isset($project_release['version_major']) && !isset($project_release['version_minor']) &&
 290          !isset($project_release['version_patch']) &&
 291          (!($project_release['version_extra']) || $project_release['version_extra'] === '')) {
 292        form_set_error('project_release][version_major', t('You must fill in some version information.'));
 293        // TODO: find a better form value to mark as the error?
 294      }
 295      foreach (array('version_major' => t('Major version number'), 'version_minor' => t('Minor version number')) as $field => $name) {
 296        $val = $project_release[$field];
 297        if (isset($val) && $val !== '' && !is_numeric($val)) {
 298          form_set_error("project_release][$field", t('%name must be a number.', array('%name' => $name)));
 299        }
 300      }
 301      $val = $project_release['version_patch'];
 302      if (isset($val) && $val !== '' && !is_numeric($val) && $val != 'x') {
 303        form_set_error('project_release][version_patch', t("Patch-level version number must be numeric or the letter 'x'."));
 304      }
 305    }
 306  
 307    $validators = array(
 308      'project_release_validate_file_extension' => array(),
 309    );
 310  
 311    // For some reason, with the $form['project_release_files'] element
 312    // #tree'd, the uploaded file shows up in 'project_release_files'
 313    // and not it's sub-element, so we use that here.
 314    if ($file = file_save_upload('project_release_files', $validators, file_directory_path() . '/project')) {
 315      // We need the file object, so pass that into $form_state here.
 316      $form_state['project_release']['new_file'] = $file;
 317    }
 318  
 319    if (project_release_get_api_taxonomy()) {
 320      $vid = _project_release_get_api_vid();
 321      if (isset($form_state['values']['taxonomy'])) {
 322        $tid = $form_state['values']['taxonomy'][$vid];
 323      }
 324      elseif (isset($form_state['values'][$vid])) {
 325        $tid = $form_state['values'][$vid];
 326      }
 327      if (isset($tid) && is_numeric($tid)) {
 328        $form_state['values']['project_release']['version_api_tid'] = $tid;
 329        $project_release['version_api_tid'] = $tid;
 330      }
 331    }
 332  
 333    // With cvs.module installed, this validation is already handled.
 334    // We only want to do it here if we're *not* doing the N-page form...
 335    if (!empty($form_state['values']['validate_version']) && !isset($form_state['values']['nid'])) {
 336      $version = (object) $project_release;
 337      if (project_release_exists($version)) {
 338        // TODO: is there a better form element to mark with this error?
 339        form_set_error('project_release][version_patch', t('This version already exists for this project.'));
 340      }
 341    }
 342  
 343    // TODO: it'd be nice to automagically reset the version string and
 344    // title based on changes to the version elements on an edit, but we
 345    // have to be careful not to break the fancy N-page form when
 346    // cvs_form_alter() is involved...
 347    $project = isset($form_state['values']['project']) ? $form_state['values']['project'] : new stdClass;
 348  
 349    if (isset($project->project['uri'])) {
 350      $project_name = $project->project['uri'];
 351    }
 352    elseif (isset($project_release['pid'])) {
 353      $project_name = project_get_uri_from_nid($form_state['values']['project_release']['pid']);
 354    }
 355  
 356    if (isset($form_state['values']['title'])) {
 357      // TODO: Magic re-setting to "%project_name %version" ??
 358    }
 359    elseif (isset($project_release['version']) && $project_release['version'] !== '') {
 360      form_set_value($form['title'], $project_name .' '. $project_release['version'], $form_state);
 361    }
 362    elseif (!empty($project)) {
 363      $version = project_release_get_version((object) $project_release, $project);
 364      form_set_value(array('#parents' => array('project_release', 'version')), $version, $form_state);
 365      $title = !empty($project_name) ? $project_name : $project->title;
 366      form_set_value($form['title'], "$title $version", $form_state);
 367    }
 368  }
 369  
 370  function project_release_validate_file_extension($file) {
 371    // Make sure that the extension on the file is one of the allowed
 372    // extensions for release files. Most of this validation code was
 373    // modified from the code in file_check_upload().
 374    $extensions = variable_get('project_release_file_extensions', PROJECT_RELEASE_FILE_EXTENSIONS);
 375    $regex = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';
 376    if (!preg_match($regex, $file->filename)) {
 377      return array(t('It is only possible to attach files with the following extensions: %files-allowed.', array('%files-allowed' => $extensions)));
 378    }
 379    return array();
 380  }
 381  
 382  function project_release_node_submit(&$form, $form_state) {
 383    // Get rid of the file upload item, not needed.
 384    unset($form_state['values']['project_release_files']['file']);
 385    // Look for newly uploaded files.
 386    if (isset($form_state['project_release']['new_file'])) {
 387      $new_file = $form_state['project_release']['new_file'];
 388    }
 389    elseif (!empty($form_state['values']['project_release_files']['temp'])) {
 390      $temp = $form_state['values']['project_release_files']['temp'];
 391      // Have to ensure the temp file hasn't been wiped from the files table.
 392      if ($temp_file = db_fetch_object(db_query("SELECT * FROM {files} WHERE fid = %d", $temp))) {
 393        $new_file = $temp_file;
 394      }
 395      unset($form_state['values']['project_release_files']['temp']);
 396    }
 397    $existing_files = !empty($form_state['values']['project_release_files']) ? $form_state['values']['project_release_files'] : NULL;
 398  
 399    if (isset($existing_files)) {
 400      foreach ($existing_files as $fid => $values) {
 401        if ($values['delete']) {
 402          $file = db_fetch_object(db_query("SELECT * FROM {files} WHERE fid = %d", $fid));
 403          project_release_file_delete($file);
 404        }
 405      }
 406    }
 407    // Add new files.
 408    if (isset($new_file)) {
 409      $status_updated = file_set_status($new_file, FILE_STATUS_PERMANENT);
 410      if ($status_updated) {
 411        $new_file->nid = $form_state['nid'];
 412        $filepath = file_create_path($new_file->filepath);
 413        $new_file->filehash = md5_file($filepath);
 414        drupal_write_record('project_release_file', $new_file);
 415      }
 416    }
 417  }
 418  
 419  /**
 420   * Helper method to take data out of a $node object and store it into
 421   * the DB as necessary. Sadly, db_query() doesn't let us store NULL in
 422   * the DB, since those get cast to 0. Therefore, we have to do some
 423   * manual effort to dynamically create the appropriate SQL depending
 424   * on which version fields are set in the release node.
 425   * @see project_release_insert
 426   * @see project_release_update
 427   * @see db_query
 428   * @ingroup project_release_internal
 429   *
 430   * @param $node
 431   *   Object containing form values from the project_release node form.  Even
 432   *   though this is NOT a fully loaded $node object, the release-related
 433   *   values are in the $node->project_release array due to manual #tree and
 434   *   #parents hacking in project_release_form().
 435   * @param $is_new Is this a new release node, or are we updating?
 436   */
 437  function project_release_db_save($node, $is_new) {
 438    // If the patch field is set to a non-numeric value, we just want to
 439    // keep it as a NULL in the DB, instead of casting it to a 0.
 440    if (isset($node->project_release['version_patch']) && !is_numeric($node->project_release['version_patch'])) {
 441      unset($node->project_release['version_patch']);
 442    }
 443  
 444    $types = array('pid' => "%d", 'version' => "'%s'", 'tag' => "'%s'",
 445      'rebuild' => "%d",
 446    );
 447    $values = array(
 448      'pid' => $node->project_release['pid'],
 449      'version' => $node->project_release['version'],
 450      'tag' => $node->project_release['tag'],
 451      'rebuild' => $node->project_release['rebuild'],
 452    );
 453    $fields = array('version_major', 'version_minor', 'version_patch', 'version_api_tid');
 454    foreach ($fields as $field) {
 455      if (isset($node->project_release[$field]) && is_numeric($node->project_release[$field])) {
 456        $types[$field] = "%d";
 457        $values[$field] = $node->project_release[$field];
 458      }
 459    }
 460    if (module_exists('taxonomy')) {
 461      // version_api_tid might not be where we think it is, so if we don't have
 462      // a real value by now, look in $node->taxonomy
 463      if (empty($types['version_api_tid'])) {
 464        $vid = _project_release_get_api_vid();
 465        if (isset($node->taxonomy[$vid])) {
 466          if (is_array($node->taxonomy[$vid])) {
 467            $api_tid = reset($node->taxonomy[$vid]);
 468          }
 469          else {
 470            $api_tid = (int)$node->taxonomy[$vid];
 471          }
 472          $types['version_api_tid'] = '%d';
 473          $values['version_api_tid'] = $api_tid;
 474        }
 475      }
 476  
 477      if (($type_vid = _project_release_get_release_type_vid()) && ($security_tid = variable_get('project_release_security_update_tid', 0))) {
 478        $types['security_update'] = '%d';
 479        $values['security_update'] = !empty($node->taxonomy[$type_vid][$security_tid]);
 480      }
 481    }
 482  
 483    $version_extra_weight_map = project_release_get_version_extra_weight_map();
 484    if (!empty($node->project_release['version_extra'])) {
 485      $types['version_extra'] = "'%s'";
 486      $values['version_extra'] = $node->project_release['version_extra'];
 487      // Since we have a version_extra defined, see what the weight should be,
 488      // based on our current mapping of version_extra prefixes to weights.
 489      foreach ($version_extra_weight_map as $prefix => $weight) {
 490        // If the $prefix exists inside version_extra, we have a match. We use
 491        // === 0 to tell the difference between the prefix being at position 0
 492        // (start of the string) vs. strpos() returning FALSE (not found).
 493        if (strpos($node->project_release['version_extra'], $prefix) === 0) {
 494          $types['version_extra_weight'] = "%d";
 495          $values['version_extra_weight'] = $weight;
 496          break;
 497        }
 498      }
 499      // If version_extra contains any digits, save them as version_extra_delta.
 500      // This is used to ensure that alpha10 is considered "newer" than alpha9.
 501      $match = array();
 502      if (preg_match('/(\d+)/', $node->project_release['version_extra'], $match)) {
 503        $types['version_extra_delta'] = "%d";
 504        $values['version_extra_delta'] = $match[1];
 505      }
 506    }
 507    // If there's no version_extra, but our mapping defines a weight for 'NULL',
 508    // specify save that weight into the version_extra_weight column.
 509    elseif (!empty($version_extra_weight_map['NULL'])) {
 510      $types['version_extra_weight'] = "%d";
 511      $values['version_extra_weight'] = $version_extra_weight_map['NULL'];
 512    }
 513  
 514    if ($is_new) {
 515      $types['nid'] = "%d";
 516      $sql = 'INSERT INTO {project_release_nodes} ('. implode(', ', array_keys($types)) .') VALUES ('. implode(', ', $types) .')';
 517    }
 518    else {
 519     $arr = array();
 520     foreach ($types as $key => $value) {
 521       $arr[] = $key .' = '. $value;
 522     }
 523     $sql = 'UPDATE {project_release_nodes} SET '. implode(',', $arr) .' WHERE nid = %d';
 524    }
 525    $values['nid'] = $node->nid;
 526    db_query($sql, $values);
 527  }
 528  
 529  /**
 530   * Redirect node/add/project_release/* to node/add/project-release/*.
 531   */
 532  function project_release_add_redirect_page() {
 533    $arg = arg(3);
 534    drupal_goto('node/add/project-release/' . (empty($arg) ? '' : $arg));
 535  }
 536  
 537  /**
 538   * Form builder for a simple form to select a project when creating a new
 539   * release (as the first "page", but this is not really a multi-page form).
 540   */
 541  function project_release_pick_project_form() {
 542    $form = array();
 543  
 544    drupal_set_title(t('Submit @name', array('@name' => node_get_types('name', 'project_release'))));
 545  
 546    // Fetch a list of all projects.
 547    $uris = NULL;
 548    $projects = array(0 => t('- Select a project -')) + project_projects_select_options($uris);
 549    if (count($projects) == 1) {
 550      drupal_set_message(t('You do not have access to any projects.'), 'error');
 551    }
 552  
 553    $form['pid'] = array(
 554      '#type' => 'select',
 555      '#title' => t('Project'),
 556      '#options' => $projects,
 557      '#required' => TRUE,
 558    );
 559    $form['submit'] = array(
 560      '#type' => 'submit',
 561      '#value' => t('Next'),
 562    );
 563    return $form;
 564  }
 565  
 566  function project_release_pick_project_form_validate($form, &$form_state) {
 567    if (empty($form_state['values']['pid'])) {
 568      form_set_error('pid', t('You must select a project.'));
 569    }
 570    $node = node_load($form_state['values']['pid']);
 571    if (empty($node) || $node->type != 'project_project') {
 572      form_set_error('pid', t('Invalid project selected.'));
 573    }
 574  }
 575  
 576  function project_release_pick_project_form_submit($form, &$form_state) {
 577    $form_state['redirect'] = 'node/add/project-release/'. $form_state['values']['pid'];
 578  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7