[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/project_issue/includes/ -> issue_node_form.inc (source)

   1  <?php
   2  // $Id: issue_node_form.inc,v 1.5 2009/10/08 23:36:16 dww Exp $
   3  
   4  /**
   5   * @file
   6   * Code required for the issue node form.
   7   */
   8  
   9  /**
  10   * Redirect node/add/project_issue/* to node/add/project-issue/*.
  11   */
  12  function project_issue_add_redirect_page($project = NULL, $category = NULL) {
  13    $path = 'node/add/project-issue';
  14    if (!empty($project)) {
  15      $path .= "/$project";
  16    }
  17    if (!empty($category)) {
  18      $path .= "/$category";
  19    }
  20    drupal_goto($path);
  21  }
  22  
  23  function project_issue_pick_project_page() {
  24    drupal_set_title(t('Submit @name', array('@name' => node_get_types('name', 'project_issue'))));
  25    return drupal_get_form('project_issue_pick_project_form');
  26  }
  27  
  28  /**
  29   * Form builder for a simple form to select a project when creating a new
  30   * issue (as the first "page", but this is not really a multi-page form).
  31   */
  32  function project_issue_pick_project_form(&$form_state) {
  33    $form = array();
  34  
  35    // Fetch a list of all projects (nid => title, grouped by project type
  36    // categories if any), and also get an array of project shortnames.
  37    $short_names = array();
  38    $projects = project_projects_select_options($short_names);
  39    if (empty($projects)) {
  40      drupal_set_message(t('You do not have access to any projects.'), 'error');
  41      // No reason to return a project selector form with no elements, so just
  42      // return an empty array for the form.
  43      return array();
  44    }
  45  
  46    // See if there's only one project the user has access to, and if so,
  47    // redirect directly to the issue form for that project.
  48    if (count($short_names) == 1) {
  49      drupal_goto('node/add/project-issue/' . key($short_names));
  50    }
  51  
  52    // Otherwise, return a form to select which project to submit an issue for.
  53    $form['pid'] = array(
  54      '#type' => 'select',
  55      '#title' => t('Project'),
  56      '#options' => array(t('<none>')) + $projects,
  57      '#required' => TRUE,
  58    );
  59    $form['submit'] = array(
  60      '#type' => 'submit',
  61      '#value' => t('Next'),
  62    );
  63    return $form;
  64  }
  65  
  66  function project_issue_pick_project_form_validate($form, &$form_state) {
  67    if (empty($form_state['values']['pid'])) {
  68      form_set_error('pid', t('You must select a project.'));
  69    }
  70    $node = node_load($form_state['values']['pid']);
  71    if (empty($node) || $node->type != 'project_project') {
  72      form_set_error('pid', t('Invalid project selected.'));
  73    }
  74  }
  75  
  76  function project_issue_pick_project_form_submit($form, &$form_state) {
  77    $project = node_load($form_state['values']['pid']);
  78    $form_state['redirect'] = 'node/add/project-issue/'. $project->project['uri'];
  79  }
  80  
  81  /**
  82   * Private helper to implement hook_form().
  83   *
  84   * Create the project issue node form.
  85   *
  86   * @param $node
  87   *   The project issue node object.
  88   * @param $include_metadata_fields
  89   *   If set, metadata fields (eg. status, assigned, title) will
  90   *   be included in the form regardless of whether $node->nid is set.
  91   *   Otherwise, metadata fields will only be included in the form
  92   *   if $node->nid is empty.
  93   */
  94  function _project_issue_form($node, $form_state, $include_metadata_fields = FALSE) {
  95    global $user;
  96  
  97    $defaults = array(
  98      'rid',
  99      'component',
 100      'category',
 101      'priority',
 102      'assigned',
 103      'sid',
 104    );
 105  
 106    // Set some defaults for new forms.
 107    if (!isset($node->nid)) {
 108      foreach ($defaults as $default) {
 109        $node->project_issue[$default] = 0;
 110      }
 111    }
 112  
 113    // In the case of an issue preview, get our defaults from the submitted form.
 114    // TODO: do we want to #tree our form so we don't need this hack?
 115    if (isset($form_state['node'])) {
 116      foreach ($defaults as $default) {
 117        if (isset($form_state['node'][$default])) {
 118          $node->project_issue[$default] = $form_state['node'][$default];
 119        }
 120      }
 121    }
 122  
 123    // If this function is being called as a result of CCK building the form
 124    // in content_admin_field_overview_form(), just return an empty array, since
 125    // CCK only grabs the top level fields and this form has none of those anyway.
 126    if (!empty($node->cck_dummy_node_form)) {
 127      return array();
 128    }
 129  
 130    if (arg(0) == 'node' && arg(1) == 'add') {
 131      $breadcrumb = array();
 132      $breadcrumb[] = l(t('Home'), NULL);
 133      $breadcrumb[] = l(t('Create content'), 'node/add');
 134      drupal_set_breadcrumb($breadcrumb);
 135    }
 136  
 137    $default_state = variable_get('project_issue_default_state', 1);
 138  
 139    // Fetch a list of all projects to test for access.
 140    $uris = NULL;
 141    $projects = array(t('<none>')) + project_projects_select_options($uris);
 142    if (count($projects) == 1) {
 143      drupal_set_message(t('You do not have access to any projects.'), 'error');
 144      drupal_goto('node/add/project-issue');
 145      return;
 146    }
 147  
 148    // Figure out what project we should use for the issue metadata.
 149    if (!empty($form_state['values']['project_info']['pid'])) {
 150      // The project has been selected in the form itself (e.g. it's been
 151      // changed and we're previewing, etc.)
 152      $pid = $form_state['values']['project_info']['pid'];
 153    }
 154    elseif (!empty($node->project_issue['pid'])) {
 155      // The issue node already knows what project it belongs to.
 156      $pid = $node->project_issue['pid'];
 157    }
 158    else {
 159      // Fallback and try to learn the project from the URL -- evil.
 160      $pid = arg(3);
 161      if (!empty($pid)) {
 162        if (is_numeric($pid)) {
 163          $node->project_issue['pid'] = db_result(db_query(db_rewrite_sql('SELECT p.nid FROM {project_projects} p WHERE p.nid = %d', 'p'), $pid));
 164        }
 165        else {
 166          $node->project_issue['pid'] = db_result(db_query(db_rewrite_sql("SELECT p.nid FROM {project_projects} p WHERE p.uri = '%s'", 'p'), $pid));
 167        }
 168      }
 169      $pid = $node->project_issue['pid'];
 170    }
 171  
 172    if (empty($pid)) {
 173      drupal_set_message(t('Invalid project selected.'), 'error');
 174      drupal_goto('node/add/project-issue');
 175    }
 176  
 177    // If this issue has already been created and is just being
 178    // edited, we want to prevent any metadata changes.  However, allow
 179    // the $include_metadata_fields parameter to override this check.
 180    if ($include_metadata_fields) {
 181      $allow_metadata_changes = TRUE;
 182    }
 183    else {
 184      $allow_metadata_changes = empty($node->nid);
 185    }
 186  
 187    // Load the project and initialize some support arrays.
 188    $project = node_load($pid);
 189    if ($project->type != 'project_project') {
 190      drupal_set_message(t('Invalid project selected.'), 'error');
 191      // Not sure the best place to go here...
 192      drupal_goto('node/add/project-issue');
 193    }
 194    if ($allow_metadata_changes) {
 195      if (module_exists('project_release') && isset($node->project_issue['rid']) &&
 196          $releases = project_release_get_releases($project, 0, 'version', 'all', array($node->project_issue['rid']))) {
 197        $releases = array(t('<none>')) + $releases;
 198      }
 199      // Remove releases marked as invalid release nodes for user selection.
 200      foreach (variable_get('project_issue_invalid_releases', array()) as $rid) {
 201        unset($releases[$rid]);
 202      }
 203      // Setup components and default component.
 204      if (!empty($node->project_issue['component'])) {
 205        $default_component = $node->project_issue['component'];
 206      }
 207      else {
 208        $default_component = $project->project_issue['default_component'];
 209      }
 210      $components = empty($default_component) ? array(t('<none>')) : array();
 211      if ($project->project_issue['components']) {
 212        foreach ($project->project_issue['components'] as $component) {
 213          $component = check_plain($component);
 214          $components[$component] = $component;
 215        }
 216      }
 217      $categories = array_merge(array(t('<none>')), project_issue_category(0, 0));
 218      $priorities = project_issue_priority();
 219      $states = project_issue_state(0, TRUE, !empty($node->nid) && ($node->uid == $user->uid), $node->project_issue['sid']);
 220      $assigned = project_issue_assigned_choices($node);
 221    }
 222  
 223    // Display the site-wide and/or per-project help text.
 224    $site_help = trim(variable_get('project_issue_site_help', ''));
 225    if (!empty($site_help)) {
 226      $form['project_help']['site'] = array(
 227        '#prefix' => '<div class="messages status site">',
 228        '#value' => check_markup($site_help),
 229        '#suffix' => '</div>',
 230      );
 231    }
 232    $project_help = trim($project->project_issue['help']);
 233    if (!empty($project_help)) {
 234      $form['project_help']['project'] = array(
 235        '#prefix' => '<div class="messages status project">',
 236        '#value' => check_markup($project_help),
 237        '#suffix' => '</div>',
 238      );
 239    }
 240  
 241    if ($allow_metadata_changes) {
 242      $form['project_info'] = array(
 243        '#type' => 'fieldset',
 244        '#title' => t('Project information'),
 245        '#prefix' => '<div class="inline-options">',
 246        '#suffix' => '</div>',
 247      );
 248      $form['project_info']['project_display'] = array(
 249        '#type' => 'item',
 250        '#title' => t('Project'),
 251        '#value' => check_plain($project->title),
 252      );
 253      $form['project_info']['pid'] = array(
 254        '#type' => 'value',
 255        '#value' => $node->project_issue['pid'],
 256      );
 257      if ($releases) {
 258        $form['project_info']['rid'] = array(
 259          '#type' => 'select',
 260          '#title' => t('Version'),
 261          '#default_value' => $node->project_issue['rid'],
 262          '#options' => $releases,
 263          '#required' => TRUE,
 264        );
 265      }
 266      $form['project_info']['component'] = array(
 267        '#type' => 'select',
 268        '#title' => t('Component'),
 269        '#default_value' => $default_component,
 270        '#options' => $components,
 271        '#required' => TRUE,
 272      );
 273      $form['issue_info'] = array(
 274        '#type' => 'fieldset',
 275        '#title' => t('Issue information'),
 276        '#prefix' => '<div class="inline-options">',
 277        '#suffix' => '</div>',
 278      );
 279      $form['issue_info']['category'] = array(
 280        '#type' => 'select',
 281        '#title' => t('Category'),
 282        '#default_value' => $node->project_issue['category'] ? $node->project_issue['category'] : arg(4),
 283        '#options' => $categories,
 284        '#required' => TRUE,
 285      );
 286      $form['issue_info']['priority'] = array(
 287        '#type' => 'select',
 288        '#title' => t('Priority'),
 289        '#default_value' => $node->project_issue['priority'] ? $node->project_issue['priority'] : 2,
 290        '#options' => $priorities,
 291      );
 292      $form['issue_info']['assigned'] = array(
 293        '#type' => 'select',
 294        '#title' => t('Assigned'),
 295        '#default_value' => $node->project_issue['assigned'],
 296        '#options' => $assigned,
 297      );
 298      if (count($states) > 1) {
 299        $form['issue_info']['sid'] = array(
 300          '#type' => 'select',
 301          '#title' => t('Status'),
 302          '#default_value' => $node->project_issue['sid'] ? $node->project_issue['sid'] : $default_state,
 303          '#options' => $states,
 304        );
 305      }
 306      else {
 307        $form['issue_info']['sid'] = array(
 308          '#type' => 'value',
 309          '#value' => $default_state,
 310        );
 311        $form['issue_info']['status'] = array(
 312          '#type' => 'item',
 313          '#title' => t('Status'),
 314          '#value' => check_plain(project_issue_state($default_state)),
 315        );
 316      }
 317    }
 318    else {
 319      // If we're not allowing issue metadata changes, add all of these values
 320      // into the form so they show up in the $node->project_issue array during
 321      // validation and submit, so we're consistent with where they live.
 322      $form['project_issue'] = array('#tree' => TRUE);
 323      $form['project_issue']['pid'] = array(
 324        '#type' => 'value',
 325        '#value' => $node->project_issue['pid'],
 326      );
 327      if (isset($node->project_issue['rid'])) {
 328        $form['project_issue']['rid'] = array(
 329          '#type' => 'value',
 330          '#value' => $node->project_issue['rid'],
 331        );
 332      }
 333      $form['project_issue']['component'] = array(
 334        '#type' => 'value',
 335        '#value' => $node->project_issue['component'],
 336      );
 337      $form['project_issue']['category'] = array(
 338        '#type' => 'value',
 339        '#value' => $node->project_issue['category'],
 340      );
 341      $form['project_issue']['priority'] = array(
 342        '#type' => 'value',
 343        '#value' => $node->project_issue['priority'],
 344      );
 345      $form['project_issue']['assigned'] = array(
 346        '#type' => 'value',
 347        '#value' => $node->project_issue['assigned'],
 348      );
 349      $form['project_issue']['sid'] = array(
 350        '#type' => 'value',
 351        '#value' => $node->project_issue['sid'],
 352      );
 353    }
 354  
 355    $form['issue_details'] = array(
 356      '#type' => 'fieldset',
 357      '#title' => t('Issue details'),
 358      '#prefix' => '</div><div class="standard">',
 359    );
 360  
 361    if ($allow_metadata_changes) {
 362      $form['issue_details']['title'] = array(
 363        '#type' => 'textfield',
 364        '#title' => t('Title'),
 365        '#default_value' => $node->title,
 366        '#size' => 60,
 367        '#maxlength' => 128,
 368        '#required' => TRUE,
 369      );
 370    }
 371    else {
 372      $form['issue_details']['title'] = array(
 373        '#type' => 'value',
 374        '#value' => $node->title,
 375      );
 376    }
 377  
 378    $form['issue_details']['body'] = array(
 379      '#type' => 'textarea',
 380      '#title' => t('Description'),
 381      '#default_value' => $node->body,
 382      '#rows' => 10,
 383      '#required' => TRUE,
 384    );
 385    $form['issue_details']['format'] = filter_form($node->format);
 386  
 387    $directory = file_create_path(variable_get('project_directory_issues', 'issues'));
 388    if (!file_check_directory($directory, 0)) {
 389      $msg = t('File attachments are disabled. The issue directory has not been properly configured.');
 390      if (user_access('administer site configuration')) {
 391        $msg .= ' '. t('Please visit the !admin-project-issue-settings page.', array('!admin-project-issue-settings' => l(t('Project issue settings'), 'admin/project/project-issue-settings')));
 392      }
 393      else {
 394        $msg .= ' '. t('Please contact the site administrator.');
 395      }
 396      drupal_set_message($msg, 'error');
 397    }
 398    return $form;
 399  }
 400  
 401  /**
 402   * Private helper to implement hook_validate().
 403   *
 404   * Ensures that the issue node form has valid values for all required fields.
 405   * We use hook_validate() here instead of a #validate handler or even defining
 406   * project_issue_node_form_validate() since if we did, node_form_validate()
 407   * itself would not be invoked, which would lead to all kinds of problems,
 408   * including hook_nodeapi('validate') never being invoked.
 409   *
 410   * @param $node
 411   *   An object of form values from the project_issue node form, not a fully
 412   *   loaded issue node object.  Therefore, the fields are not in the usual
 413   *   $node->project_issue array.
 414   */
 415  function _project_issue_validate($node) {
 416    // If $node->nid is set, that means that the node was being
 417    // edited and not created.  If that's the case, the user was
 418    // not presented with any of the metadata fields, so there's no
 419    // need to validate them here.
 420    if (empty($node->nid)) {
 421      if (empty($node->pid)) {
 422        form_set_error('pid', t('You have to specify a valid project.'));
 423      }
 424      elseif ($project = node_load($node->pid)) {
 425        if (module_exists('project_release') &&
 426            $releases = project_release_get_releases($project, 0)) {
 427          if (empty($node->rid)) {
 428            form_set_error('rid', t('You have to specify a valid version.'));
 429          }
 430        }
 431        if (isset($node->component) && !in_array($node->component, $project->project_issue['components'])) {
 432          $node->component = 0;
 433        }
 434        if (empty($node->component)) {
 435          form_set_error('component', t('You have to specify a valid component.'));
 436        }
 437        if (empty($node->category)) {
 438          form_set_error('category', t('You have to specify a valid category.'));
 439        }
 440      }
 441    }
 442  }
 443  
 444  /**
 445   * Private helper to implement hook_insert().
 446   *
 447   * @param $node
 448   *   Object containing form values from the project_issue node form.  This is
 449   *   NOT a fully loaded $node object, so the issue-related values are directly
 450   *   in $node, not in the $node->project_issue array.
 451   */
 452  function _project_issue_insert($node) {
 453    // Permanently store the original issue states in a serialized array. This
 454    // is a bit yucky, but we need them for proper handling of states workflow.
 455    // The current states need to be stored in {project_issues} as well for
 456    // query efficiency in issue queue searches, and it seems too messy to add a
 457    // bunch of new columns to the {project_issues} table for the original
 458    // states.
 459    $original_issue_data = new stdClass();
 460    $fields = array(
 461      'pid' => 0,
 462      'rid' => 0,
 463      'component' => '',
 464      'category' => '',
 465      'priority' => 0,
 466      'assigned' => 0,
 467      'sid' => 0,
 468      'title' => '',
 469    );
 470    foreach ($fields as $field => $default) {
 471      // Some of the incoming data may not have the correct default.
 472      if (empty($node->$field)) {
 473        $node->$field = $default;
 474      }
 475      $original_issue_data->$field = $node->$field;
 476    }
 477  
 478    db_query("INSERT INTO {project_issues} (nid, pid, category, component, priority, rid, assigned, sid, original_issue_data, last_comment_id, db_lock) VALUES (%d, %d, '%s', '%s', %d, %d, %d, %d, '%s', %d, %d)", $node->nid, $node->pid, $node->category, $node->component, $node->priority, $node->rid, $node->assigned, $node->sid, serialize($original_issue_data), 0, 0);
 479  
 480    // Invalidate the "Issue cockpit" block cache for this project, since the
 481    // new issue will have altered the summary totals.
 482    cache_clear_all('project_issue_cockpit_block:'. $node->pid, 'cache');
 483  }
 484  


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