| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
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
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |