[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/modules/node/ -> node.pages.inc (source)

   1  <?php
   2  // $Id: node.pages.inc,v 1.28.2.4 2009/04/27 11:35:01 goba Exp $
   3  
   4  /**
   5   * @file
   6   * Page callbacks for adding, editing, deleting, and revisions management for content.
   7   */
   8  
   9  
  10  /**
  11   * Menu callback; presents the node editing form, or redirects to delete confirmation.
  12   */
  13  function node_page_edit($node) {
  14    drupal_set_title(check_plain($node->title));
  15    return drupal_get_form($node->type .'_node_form', $node);
  16  }
  17  
  18  function node_add_page() {
  19    $item = menu_get_item();
  20    $content = system_admin_menu_block($item);
  21    return theme('node_add_list', $content);
  22  }
  23  
  24  /**
  25   * Display the list of available node types for node creation.
  26   *
  27   * @ingroup themeable
  28   */
  29  function theme_node_add_list($content) {
  30    $output = '';
  31  
  32    if ($content) {
  33      $output = '<dl class="node-type-list">';
  34      foreach ($content as $item) {
  35        $output .= '<dt>'. l($item['title'], $item['href'], $item['localized_options']) .'</dt>';      
  36        $output .= '<dd>'. filter_xss_admin($item['description']) .'</dd>';
  37      }
  38      $output .= '</dl>';
  39    }
  40    return $output;
  41  }
  42  
  43  
  44  /**
  45   * Present a node submission form or a set of links to such forms.
  46   */
  47  function node_add($type) {
  48    global $user;
  49  
  50    $types = node_get_types();
  51    $type = isset($type) ? str_replace('-', '_', $type) : NULL;
  52    // If a node type has been specified, validate its existence.
  53    if (isset($types[$type]) && node_access('create', $type)) {
  54      // Initialize settings:
  55      $node = array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => '');
  56  
  57      drupal_set_title(t('Create @name', array('@name' => $types[$type]->name)));
  58      $output = drupal_get_form($type .'_node_form', $node);
  59    }
  60  
  61    return $output;
  62  }
  63  
  64  function node_form_validate($form, &$form_state) {
  65    node_validate($form_state['values'], $form);
  66  }
  67  
  68  function node_object_prepare(&$node) {
  69    // Set up default values, if required.
  70    $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
  71    // If this is a new node, fill in the default values.
  72    if (!isset($node->nid)) {
  73      foreach (array('status', 'promote', 'sticky') as $key) {
  74        $node->$key = in_array($key, $node_options);
  75      }
  76      global $user;
  77      $node->uid = $user->uid;
  78      $node->created = time();
  79    }
  80    else {
  81      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
  82      // Remove the log message from the original node object.
  83      $node->log = NULL;
  84    }
  85    // Always use the default revision setting.
  86    $node->revision = in_array('revision', $node_options);
  87  
  88    node_invoke($node, 'prepare');
  89    node_invoke_nodeapi($node, 'prepare');
  90  }
  91  
  92  /**
  93   * Generate the node add/edit form array.
  94   */
  95  function node_form(&$form_state, $node) {
  96    global $user;
  97  
  98    if (isset($form_state['node'])) {
  99      $node = $form_state['node'] + (array)$node;
 100    }
 101    if (isset($form_state['node_preview'])) {
 102      $form['#prefix'] = $form_state['node_preview'];
 103    }
 104    $node = (object)$node;
 105    foreach (array('body', 'title', 'format') as $key) {
 106      if (!isset($node->$key)) {
 107        $node->$key = NULL;
 108      }
 109    }
 110    if (!isset($form_state['node_preview'])) {
 111      node_object_prepare($node);
 112    }
 113    else {
 114      $node->build_mode = NODE_BUILD_PREVIEW;
 115    }
 116  
 117    // Set the id of the top-level form tag
 118    $form['#id'] = 'node-form';
 119  
 120    // Basic node information.
 121    // These elements are just values so they are not even sent to the client.
 122    foreach (array('nid', 'vid', 'uid', 'created', 'type', 'language') as $key) {
 123      $form[$key] = array(
 124        '#type' => 'value',
 125        '#value' => isset($node->$key) ? $node->$key : NULL,
 126      );
 127    }
 128  
 129    // Changed must be sent to the client, for later overwrite error checking.
 130    $form['changed'] = array(
 131      '#type' => 'hidden',
 132      '#default_value' => isset($node->changed) ? $node->changed : NULL,
 133    );
 134    // Get the node-specific bits.
 135    if ($extra = node_invoke($node, 'form', $form_state)) {
 136      $form = array_merge_recursive($form, $extra);
 137    }
 138    if (!isset($form['title']['#weight'])) {
 139      $form['title']['#weight'] = -5;
 140    }
 141  
 142    $form['#node'] = $node;
 143  
 144    // Add a log field if the "Create new revision" option is checked, or if the
 145    // current user has the ability to check that option.
 146    if (!empty($node->revision) || user_access('administer nodes')) {
 147      $form['revision_information'] = array(
 148        '#type' => 'fieldset',
 149        '#title' => t('Revision information'),
 150        '#collapsible' => TRUE,
 151        // Collapsed by default when "Create new revision" is unchecked
 152        '#collapsed' => !$node->revision,
 153        '#weight' => 20,
 154      );
 155      $form['revision_information']['revision'] = array(
 156        '#access' => user_access('administer nodes'),
 157        '#type' => 'checkbox',
 158        '#title' => t('Create new revision'),
 159        '#default_value' => $node->revision,
 160      );
 161      $form['revision_information']['log'] = array(
 162        '#type' => 'textarea',
 163        '#title' => t('Log message'),
 164        '#default_value' => (isset($node->log) ? $node->log : ''),
 165        '#rows' => 2,
 166        '#description' => t('An explanation of the additions or updates being made to help other authors understand your motivations.'),
 167      );
 168    }
 169  
 170    // Node author information for administrators
 171    $form['author'] = array(
 172      '#type' => 'fieldset',
 173      '#access' => user_access('administer nodes'),
 174      '#title' => t('Authoring information'),
 175      '#collapsible' => TRUE,
 176      '#collapsed' => TRUE,
 177      '#weight' => 20,
 178    );
 179    $form['author']['name'] = array(
 180      '#type' => 'textfield',
 181      '#title' => t('Authored by'),
 182      '#maxlength' => 60,
 183      '#autocomplete_path' => 'user/autocomplete',
 184      '#default_value' => $node->name ? $node->name : '',
 185      '#weight' => -1,
 186      '#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous')))),
 187    );
 188    $form['author']['date'] = array(
 189      '#type' => 'textfield',
 190      '#title' => t('Authored on'),
 191      '#maxlength' => 25,
 192      '#description' => t('Format: %time. Leave blank to use the time of form submission.', array('%time' => !empty($node->date) ? $node->date : format_date($node->created, 'custom', 'Y-m-d H:i:s O'))),
 193    );
 194  
 195    if (isset($node->date)) {
 196      $form['author']['date']['#default_value'] = $node->date;
 197    }
 198  
 199    // Node options for administrators
 200    $form['options'] = array(
 201      '#type' => 'fieldset',
 202      '#access' => user_access('administer nodes'),
 203      '#title' => t('Publishing options'),
 204      '#collapsible' => TRUE,
 205      '#collapsed' => TRUE,
 206      '#weight' => 25,
 207    );
 208    $form['options']['status'] = array(
 209      '#type' => 'checkbox',
 210      '#title' => t('Published'),
 211      '#default_value' => $node->status,
 212    );
 213    $form['options']['promote'] = array(
 214      '#type' => 'checkbox',
 215      '#title' => t('Promoted to front page'),
 216      '#default_value' => $node->promote,
 217    );
 218    $form['options']['sticky'] = array(
 219      '#type' => 'checkbox',
 220      '#title' => t('Sticky at top of lists'),
 221      '#default_value' => $node->sticky,
 222    );
 223  
 224    // These values are used when the user has no administrator access.
 225    foreach (array('uid', 'created') as $key) {
 226      $form[$key] = array(
 227        '#type' => 'value',
 228        '#value' => $node->$key,
 229      );
 230    }
 231  
 232    // Add the buttons.
 233    $form['buttons'] = array();
 234    $form['buttons']['submit'] = array(
 235      '#type' => 'submit',
 236      '#access' => !variable_get('node_preview', 0) || (!form_get_errors() && isset($form_state['node_preview'])),
 237      '#value' => t('Save'),
 238      '#weight' => 5,
 239      '#submit' => array('node_form_submit'),
 240    );
 241    $form['buttons']['preview'] = array(
 242      '#type' => 'submit',
 243      '#value' => t('Preview'),
 244      '#weight' => 10,
 245      '#submit' => array('node_form_build_preview'),
 246    );
 247    if (!empty($node->nid) && node_access('delete', $node)) {
 248      $form['buttons']['delete'] = array(
 249        '#type' => 'submit',
 250        '#value' => t('Delete'),
 251        '#weight' => 15,
 252        '#submit' => array('node_form_delete_submit'),
 253      );
 254    }
 255    $form['#validate'][] = 'node_form_validate';
 256    $form['#theme'] = array($node->type .'_node_form', 'node_form');
 257    return $form;
 258  }
 259  
 260  /**
 261   * Return a node body field, with format and teaser.
 262   */
 263  function node_body_field(&$node, $label, $word_count) {
 264  
 265    // Check if we need to restore the teaser at the beginning of the body.
 266    $include = !isset($node->teaser) || ($node->teaser == substr($node->body, 0, strlen($node->teaser)));
 267  
 268    $form = array(
 269      '#after_build' => array('node_teaser_js', 'node_teaser_include_verify'));
 270  
 271    $form['#prefix'] = '<div class="body-field-wrapper">';
 272    $form['#suffix'] = '</div>';
 273  
 274    $form['teaser_js'] = array(
 275      '#type' => 'textarea',
 276      '#rows' => 10,
 277      '#teaser' => 'edit-body',
 278      '#teaser_checkbox' => 'edit-teaser-include',
 279      '#disabled' => TRUE,
 280    );
 281  
 282    $form['teaser_include'] = array(
 283      '#type' => 'checkbox',
 284      '#title' => t('Show summary in full view'),
 285      '#default_value' => $include,
 286      '#prefix' => '<div class="teaser-checkbox">',
 287      '#suffix' => '</div>',
 288    );
 289  
 290    $form['body'] = array(
 291      '#type' => 'textarea',
 292      '#title' => check_plain($label),
 293      '#default_value' => $include ? $node->body : ($node->teaser . $node->body),
 294      '#rows' => 20,
 295      '#required' => ($word_count > 0),
 296    );
 297  
 298    $form['format'] = filter_form($node->format);
 299  
 300    return $form;
 301  }
 302  
 303  /**
 304   * Button sumit function: handle the 'Delete' button on the node form.
 305   */
 306  function node_form_delete_submit($form, &$form_state) {
 307    $destination = '';
 308    if (isset($_REQUEST['destination'])) {
 309      $destination = drupal_get_destination();
 310      unset($_REQUEST['destination']);
 311    }
 312    $node = $form['#node'];
 313    $form_state['redirect'] = array('node/'. $node->nid .'/delete', $destination);
 314  }
 315  
 316  
 317  function node_form_build_preview($form, &$form_state) {
 318    $node = node_form_submit_build_node($form, $form_state);
 319    $form_state['node_preview'] = node_preview($node);
 320  }
 321  
 322  /**
 323   * Present a node submission form.
 324   *
 325   * @ingroup themeable
 326   */
 327  function theme_node_form($form) {
 328    $output = "\n<div class=\"node-form\">\n";
 329  
 330    // Admin form fields and submit buttons must be rendered first, because
 331    // they need to go to the bottom of the form, and so should not be part of
 332    // the catch-all call to drupal_render().
 333    $admin = '';
 334    if (isset($form['author'])) {
 335      $admin .= "    <div class=\"authored\">\n";
 336      $admin .= drupal_render($form['author']);
 337      $admin .= "    </div>\n";
 338    }
 339    if (isset($form['options'])) {
 340      $admin .= "    <div class=\"options\">\n";
 341      $admin .= drupal_render($form['options']);
 342      $admin .= "    </div>\n";
 343    }
 344    $buttons = drupal_render($form['buttons']);
 345  
 346    // Everything else gets rendered here, and is displayed before the admin form
 347    // field and the submit buttons.
 348    $output .= "  <div class=\"standard\">\n";
 349    $output .= drupal_render($form);
 350    $output .= "  </div>\n";
 351  
 352    if (!empty($admin)) {
 353      $output .= "  <div class=\"admin\">\n";
 354      $output .= $admin;
 355      $output .= "  </div>\n";
 356    }
 357    $output .= $buttons;
 358    $output .= "</div>\n";
 359  
 360    return $output;
 361  }
 362  
 363  /**
 364   * Generate a node preview.
 365   */
 366  function node_preview($node) {
 367    if (node_access('create', $node) || node_access('update', $node)) {
 368      // Load the user's name when needed.
 369      if (isset($node->name)) {
 370        // The use of isset() is mandatory in the context of user IDs, because
 371        // user ID 0 denotes the anonymous user.
 372        if ($user = user_load(array('name' => $node->name))) {
 373          $node->uid = $user->uid;
 374          $node->picture = $user->picture;
 375        }
 376        else {
 377          $node->uid = 0; // anonymous user
 378        }
 379      }
 380      else if ($node->uid) {
 381        $user = user_load(array('uid' => $node->uid));
 382        $node->name = $user->name;
 383        $node->picture = $user->picture;
 384      }
 385  
 386      $node->changed = time();
 387  
 388      // Extract a teaser, if it hasn't been set (e.g. by a module-provided
 389      // 'teaser' form item).
 390      if (!isset($node->teaser)) {
 391        $node->teaser = empty($node->body) ? '' : node_teaser($node->body, $node->format);
 392        // Chop off the teaser from the body if needed.
 393        if (!$node->teaser_include && $node->teaser == substr($node->body, 0, strlen($node->teaser))) {
 394          $node->body = substr($node->body, strlen($node->teaser));
 395        }
 396      }
 397  
 398      // Display a preview of the node.
 399      // Previewing alters $node so it needs to be cloned.
 400      if (!form_get_errors()) {
 401        $cloned_node = drupal_clone($node);
 402        $cloned_node->build_mode = NODE_BUILD_PREVIEW;
 403        $output = theme('node_preview', $cloned_node);
 404      }
 405      drupal_set_title(t('Preview'));
 406  
 407      return $output;
 408    }
 409  }
 410  
 411  /**
 412   * Display a node preview for display during node creation and editing.
 413   *
 414   * @param $node
 415   *   The node object which is being previewed.
 416   *
 417   * @ingroup themeable
 418   */
 419  function theme_node_preview($node) {
 420    $output = '<div class="preview">';
 421  
 422    $preview_trimmed_version = FALSE;
 423    // Do we need to preview trimmed version of post as well as full version?
 424    if (isset($node->teaser) && isset($node->body)) {
 425      $teaser = trim($node->teaser);
 426      $body = trim(str_replace('<!--break-->', '', $node->body));
 427  
 428      // Preview trimmed version if teaser and body will appear different;
 429      // also (edge case) if both teaser and body have been specified by the user
 430      // and are actually the same.
 431      if ($teaser != $body || ($body && strpos($node->body, '<!--break-->') === 0)) {
 432        $preview_trimmed_version = TRUE;
 433      }
 434    }
 435  
 436    if ($preview_trimmed_version) {
 437      drupal_set_message(t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication.<span class="no-js"> You can insert the delimiter "&lt;!--break--&gt;" (without the quotes) to fine-tune where your post gets split.</span>'));
 438      $output .= '<h3>'. t('Preview trimmed version') .'</h3>';
 439      $output .= node_view(drupal_clone($node), 1, FALSE, 0);
 440      $output .= '<h3>'. t('Preview full version') .'</h3>';
 441      $output .= node_view($node, 0, FALSE, 0);
 442    }
 443    else {
 444      $output .= node_view($node, 0, FALSE, 0);
 445    }
 446    $output .= "</div>\n";
 447  
 448    return $output;
 449  }
 450  
 451  function node_form_submit($form, &$form_state) {
 452    global $user;
 453  
 454    $node = node_form_submit_build_node($form, $form_state);
 455    $insert = empty($node->nid);
 456    node_save($node);
 457    $node_link = l(t('view'), 'node/'. $node->nid);
 458    $watchdog_args = array('@type' => $node->type, '%title' => $node->title);
 459    $t_args = array('@type' => node_get_types('name', $node), '%title' => $node->title);
 460  
 461    if ($insert) {
 462      watchdog('content', '@type: added %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
 463      drupal_set_message(t('@type %title has been created.', $t_args));
 464    }
 465    else {
 466      watchdog('content', '@type: updated %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
 467      drupal_set_message(t('@type %title has been updated.', $t_args));
 468    }
 469    if ($node->nid) {
 470      unset($form_state['rebuild']);
 471      $form_state['nid'] = $node->nid;
 472      $form_state['redirect'] = 'node/'. $node->nid;
 473    }
 474    else {
 475      // In the unlikely case something went wrong on save, the node will be
 476      // rebuilt and node form redisplayed the same way as in preview.
 477      drupal_set_message(t('The post could not be saved.'), 'error');
 478    }
 479  }
 480  
 481  /**
 482   * Build a node by processing submitted form values and prepare for a form rebuild.
 483   */
 484  function node_form_submit_build_node($form, &$form_state) {
 485    // Unset any button-level handlers, execute all the form-level submit
 486    // functions to process the form values into an updated node.
 487    unset($form_state['submit_handlers']);
 488    form_execute_handlers('submit', $form, $form_state);
 489    $node = node_submit($form_state['values']);
 490    $form_state['node'] = (array)$node;
 491    $form_state['rebuild'] = TRUE;
 492    return $node;
 493  }
 494  
 495  /**
 496   * Menu callback -- ask for confirmation of node deletion
 497   */
 498  function node_delete_confirm(&$form_state, $node) {
 499    $form['nid'] = array(
 500      '#type' => 'value',
 501      '#value' => $node->nid,
 502    );
 503  
 504    return confirm_form($form,
 505      t('Are you sure you want to delete %title?', array('%title' => $node->title)),
 506      isset($_GET['destination']) ? $_GET['destination'] : 'node/'. $node->nid,
 507      t('This action cannot be undone.'),
 508      t('Delete'),
 509      t('Cancel')
 510    );
 511  }
 512  
 513  /**
 514   * Execute node deletion
 515   */
 516  function node_delete_confirm_submit($form, &$form_state) {
 517    if ($form_state['values']['confirm']) {
 518      node_delete($form_state['values']['nid']);
 519    }
 520  
 521    $form_state['redirect'] = '<front>';
 522  }
 523  
 524  /**
 525   * Generate an overview table of older revisions of a node.
 526   */
 527  function node_revision_overview($node) {
 528    drupal_set_title(t('Revisions for %title', array('%title' => $node->title)));
 529  
 530    $header = array(t('Revision'), array('data' => t('Operations'), 'colspan' => 2));
 531  
 532    $revisions = node_revision_list($node);
 533  
 534    $rows = array();
 535    $revert_permission = FALSE;
 536    if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {
 537      $revert_permission = TRUE;
 538    }
 539    $delete_permission = FALSE;
 540    if ((user_access('delete revisions') || user_access('administer nodes')) && node_access('delete', $node)) {
 541      $delete_permission = TRUE;
 542    }
 543    foreach ($revisions as $revision) {
 544      $row = array();
 545      $operations = array();
 546  
 547      if ($revision->current_vid > 0) {
 548        $row[] = array('data' => t('!date by !username', array('!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid"), '!username' => theme('username', $revision)))
 549                                 . (($revision->log != '') ? '<p class="revision-log">'. filter_xss($revision->log) .'</p>' : ''),
 550                       'class' => 'revision-current');
 551        $operations[] = array('data' => theme('placeholder', t('current revision')), 'class' => 'revision-current', 'colspan' => 2);
 552      }
 553      else {
 554        $row[] = t('!date by !username', array('!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid/revisions/$revision->vid/view"), '!username' => theme('username', $revision)))
 555                 . (($revision->log != '') ? '<p class="revision-log">'. filter_xss($revision->log) .'</p>' : '');
 556        if ($revert_permission) {
 557          $operations[] = l(t('revert'), "node/$node->nid/revisions/$revision->vid/revert");
 558        }
 559        if ($delete_permission) {
 560          $operations[] = l(t('delete'), "node/$node->nid/revisions/$revision->vid/delete");
 561        }
 562      }
 563      $rows[] = array_merge($row, $operations);
 564    }
 565  
 566    return theme('table', $header, $rows);
 567  }
 568  
 569  /**
 570   * Ask for confirmation of the reversion to prevent against CSRF attacks.
 571   */
 572  function node_revision_revert_confirm($form_state, $node_revision) {
 573    $form['#node_revision'] = $node_revision;
 574    return confirm_form($form, t('Are you sure you want to revert to the revision from %revision-date?', array('%revision-date' => format_date($node_revision->revision_timestamp))), 'node/'. $node_revision->nid .'/revisions', '', t('Revert'), t('Cancel'));
 575  }
 576  
 577  function node_revision_revert_confirm_submit($form, &$form_state) {
 578    $node_revision = $form['#node_revision'];
 579    $node_revision->revision = 1;
 580    $node_revision->log = t('Copy of the revision from %date.', array('%date' => format_date($node_revision->revision_timestamp)));
 581    if (module_exists('taxonomy')) {
 582      $node_revision->taxonomy = array_keys($node_revision->taxonomy);
 583    }
 584  
 585    node_save($node_revision);
 586  
 587    watchdog('content', '@type: reverted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->title, '%revision' => $node_revision->vid));
 588    drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title, '%revision-date' => format_date($node_revision->revision_timestamp))));
 589    $form_state['redirect'] = 'node/'. $node_revision->nid .'/revisions';
 590  }
 591  
 592  function node_revision_delete_confirm($form_state, $node_revision) {
 593    $form['#node_revision'] = $node_revision;
 594    return confirm_form($form, t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($node_revision->revision_timestamp))), 'node/'. $node_revision->nid .'/revisions', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
 595  }
 596  
 597  function node_revision_delete_confirm_submit($form, &$form_state) {
 598    $node_revision = $form['#node_revision'];
 599    db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $node_revision->nid, $node_revision->vid);
 600    node_invoke_nodeapi($node_revision, 'delete revision');
 601    watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->title, '%revision' => $node_revision->vid));
 602    drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title)));
 603    $form_state['redirect'] = 'node/'. $node_revision->nid;
 604    if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node_revision->nid)) > 1) {
 605      $form_state['redirect'] .= '/revisions';
 606    }
 607  }


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