/[drupal]/drupal/modules/node.module
ViewVC logotype

Diff of /drupal/modules/node.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.641.2.32, Mon Jan 29 21:39:28 2007 UTC revision 1.657, Wed Jul 12 14:30:01 2006 UTC
# Line 1  Line 1 
1  <?php  <?php
2  // $Id: node.module,v 1.641.2.31 2007/01/04 20:50:02 killes Exp $  // $Id: node.module,v 1.656 2006/07/10 19:27:52 dries Exp $
3    
4  /**  /**
5   * @file   * @file
# Line 34  function node_help($section) { Line 34  function node_help($section) {
34        return $output;        return $output;
35      case 'admin/modules#description':      case 'admin/modules#description':
36        return t('Allows content to be submitted to the site and displayed on pages.');        return t('Allows content to be submitted to the site and displayed on pages.');
     case 'admin/node/configure':  
     case 'admin/node/configure/settings':  
       return t('<p>Settings for the core of Drupal. Almost everything is a node so these settings will affect most of the site.</p>');  
37      case 'admin/node':      case 'admin/node':
38        return t('<p>Below is a list of all of the posts on your site. Other forms of content are listed elsewhere (e.g. <a href="%comments">comments</a>).</p><p>Clicking a title views the post, while clicking an author\'s name views their user information.</p>', array('%comments' => url('admin/comment')));        return t('<p>Below is a list of all of the posts on your site. Other forms of content are listed elsewhere (e.g. <a href="%comments">comments</a>).</p><p>Clicking a title views the post, while clicking an author\'s name views their user information.</p>', array('%comments' => url('admin/comment')));
39      case 'admin/node/search':      case 'admin/node/search':
40        return t('<p>Enter a simple pattern to search for a post. This can include the wildcard character *.<br />For example, a search for "br*" might return "bread bakers", "our daily bread" and "brenda".</p>');        return t('<p>Enter a simple pattern to search for a post. This can include the wildcard character *.<br />For example, a search for "br*" might return "bread bakers", "our daily bread" and "brenda".</p>');
41    }    }
42    
43    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'revisions' && !arg(3)) {    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'revisions') {
44      return t('The revisions let you track differences between multiple versions of a post.');      return t('The revisions let you track differences between multiple versions of a post.');
45    }    }
46    
# Line 63  function node_cron() { Line 60  function node_cron() {
60   * Gather a listing of links to nodes.   * Gather a listing of links to nodes.
61   *   *
62   * @param $result   * @param $result
63   *   A DB result object from a query to fetch node objects.  If your query joins the <code>node_comment_statistics</code> table so that the <code>comment_count</code> field is available, a title attribute will be added to show the number of comments.   *   A DB result object from a query to fetch node objects. If your query joins the <code>node_comment_statistics</code> table so that the <code>comment_count</code> field is available, a title attribute will be added to show the number of comments.
64   * @param $title   * @param $title
65   *   A heading for the resulting list.   *   A heading for the resulting list.
66   *   *
# Line 160  function node_teaser($body, $format = NU Line 157  function node_teaser($body, $format = NU
157      return $body;      return $body;
158    }    }
159    
   // If a valid delimiter has been specified, use it to chop off the teaser.  
   if ($delimiter !== FALSE) {  
     return substr($body, 0, $delimiter);  
   }  
   
160    // We check for the presence of the PHP evaluator filter in the current    // We check for the presence of the PHP evaluator filter in the current
161    // format. If the body contains PHP code, we do not split it up to prevent    // format. If the body contains PHP code, we do not split it up to prevent
162    // parse errors.    // parse errors.
# Line 175  function node_teaser($body, $format = NU Line 167  function node_teaser($body, $format = NU
167      }      }
168    }    }
169    
170      // If a valid delimiter has been specified, use it to chop of the teaser.
171      if ($delimiter !== FALSE) {
172        return substr($body, 0, $delimiter);
173      }
174    
175    // If we have a short body, the entire body is the teaser.    // If we have a short body, the entire body is the teaser.
176    if (strlen($body) < $size) {    if (strlen($body) < $size) {
177      return $body;      return $body;
178    }    }
179    
180    // The teaser may not be longer than maximum length specified. Initial slice.    // In some cases, no delimiter has been specified (e.g. when posting using
181    $teaser = truncate_utf8($body, $size);    // the Blogger API). In this case, we try to split at paragraph boundaries.
   $position = 0;  
   // Cache the reverse of the teaser.  
   $reversed = strrev($teaser);  
   
   // In some cases, no delimiter has been specified. In this case, we try to  
   // split at paragraph boundaries.  
   $breakpoints = array('</p>' => 0, '<br />' => 6, '<br>' => 4, "\n" => 1);  
   // We use strpos on the reversed needle and haystack for speed.  
   foreach ($breakpoints as $point => $offset) {  
     $length = strpos($reversed, strrev($point));  
     if ($length !== FALSE) {  
       $position = - $length - $offset;  
       return ($position == 0) ? $teaser : substr($teaser, 0, $position);  
     }  
   }  
   
182    // When even the first paragraph is too long, we try to split at the end of    // When even the first paragraph is too long, we try to split at the end of
183    // the last full sentence.    // the next sentence.
184    $breakpoints = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1);    $breakpoints = array('</p>' => 4, '<br />' => 0, '<br>' => 0, "\n" => 0, '. ' => 1, '! ' => 1, '? ' => 1, '。' => 3, '؟ ' => 1);
185    $min_length = strlen($reversed);    foreach ($breakpoints as $point => $charnum) {
186    foreach ($breakpoints as $point => $offset) {      if ($length = strpos($body, $point, $size)) {
187      $length = strpos($reversed, strrev($point));        return substr($body, 0, $length + $charnum);
     if ($length !== FALSE) {  
       $min_length = min($length, $min_length);  
       $position = 0 - $length - $offset;  
188      }      }
189    }    }
190    return ($position == 0) ? $teaser : substr($teaser, 0, $position);  
191      // If all else fails, we simply truncate the string.
192      return truncate_utf8($body, $size);
193  }  }
194    
195  function _node_names($op = '', $node = NULL) {  function _node_names($op = '', $node = NULL) {
# Line 273  function node_get_name($node) { Line 253  function node_get_name($node) {
253  /**  /**
254   * Return the list of available node types.   * Return the list of available node types.
255   *   *
256     * @param $node
257     *   Either a node object, a node array, or a string containing the node type.
258   * @return   * @return
259   *   An array consisting ('#type' => name) pairs.   *   An array consisting ('#type' => name) pairs.
260   */   */
# Line 360  function node_load($param = array(), $re Line 342  function node_load($param = array(), $re
342      $nodes = array();      $nodes = array();
343    }    }
344    
   $cachable = ($revision == NULL);  
345    $arguments = array();    $arguments = array();
346    if (is_numeric($param)) {    if (is_numeric($param)) {
347        $cachable = $revision == NULL;
348      if ($cachable && isset($nodes[$param])) {      if ($cachable && isset($nodes[$param])) {
349        return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param];        return $nodes[$param];
350      }      }
351      $cond = 'n.nid = %d';      $cond = 'n.nid = %d';
352      $arguments[] = $param;      $arguments[] = $param;
# Line 379  function node_load($param = array(), $re Line 361  function node_load($param = array(), $re
361    }    }
362    
363    // Retrieve the node.    // Retrieve the node.
   // No db_rewrite_sql is applied so as to get complete indexing for search.  
364    if ($revision) {    if ($revision) {
365      array_unshift($arguments, $revision);      array_unshift($arguments, $revision);
366      $node = db_fetch_object(db_query('SELECT n.nid, r.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.nid = n.nid AND r.vid = %d WHERE '. $cond, $arguments));      $node = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, r.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.nid = n.nid AND r.vid = %d WHERE '. $cond), $arguments));
367    }    }
368    else {    else {
369      $node = db_fetch_object(db_query('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond, $arguments));      $node = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond), $arguments));
370    }    }
371    
372    if ($node->nid) {    if ($node->nid) {
# Line 402  function node_load($param = array(), $re Line 383  function node_load($param = array(), $re
383          $node->$key = $value;          $node->$key = $value;
384        }        }
385      }      }
386      if ($cachable) {    }
387        $nodes[$node->nid] = is_object($node) ? drupal_clone($node) : $node;  
388      }    if ($cachable) {
389        $nodes[$param] = $node;
390    }    }
391    
392    return $node;    return $node;
# Line 416  function node_load($param = array(), $re Line 398  function node_load($param = array(), $re
398  function node_save(&$node) {  function node_save(&$node) {
399    global $user;    global $user;
400    
401    $node->is_new = false;    $node->is_new = FALSE;
402    
403    // Apply filters to some default node fields:    // Apply filters to some default node fields:
404    if (empty($node->nid)) {    if (empty($node->nid)) {
405      // Insert a new node.      // Insert a new node.
406      $node->is_new = true;      $node->is_new = TRUE;
407    
408      $node->nid = db_next_id('{node}_nid');      $node->nid = db_next_id('{node}_nid');
409      $node->vid = db_next_id('{node_revisions}_vid');;      $node->vid = db_next_id('{node_revisions}_vid');;
# Line 460  function node_save(&$node) { Line 442  function node_save(&$node) {
442                      'title' => $node->title, 'type' => $node->type, 'uid' => $node->uid,                      'title' => $node->title, 'type' => $node->type, 'uid' => $node->uid,
443                      'status' => $node->status, 'created' => $node->created,                      'status' => $node->status, 'created' => $node->created,
444                      'changed' => $node->changed, 'comment' => $node->comment,                      'changed' => $node->changed, 'comment' => $node->comment,
445                      'promote' => $node->promote, 'moderate' => $node->moderate,                      'promote' => $node->promote, 'sticky' => $node->sticky);
                     'sticky' => $node->sticky);  
446    $node_table_types = array('nid' => '%d', 'vid' => '%d',    $node_table_types = array('nid' => '%d', 'vid' => '%d',
447                      'title' => "'%s'", 'type' => "'%s'", 'uid' => '%d',                      'title' => "'%s'", 'type' => "'%s'", 'uid' => '%d',
448                      'status' => '%d', 'created' => '%d',                      'status' => '%d', 'created' => '%d',
449                      'changed' => '%d', 'comment' => '%d',                      'changed' => '%d', 'comment' => '%d',
450                      'promote' => '%d', 'moderate' => '%d',                      'promote' => '%d', 'sticky' => '%d');
                     'sticky' => '%d');  
451    
452    //Generate the node table query and the    //Generate the node table query and the
453    //the node_revisions table query    //the node_revisions table query
# Line 535  function node_view($node, $teaser = FALS Line 515  function node_view($node, $teaser = FALS
515    // TODO: this strips legitimate uses of '<!--break-->' also.    // TODO: this strips legitimate uses of '<!--break-->' also.
516    $node->body = str_replace('<!--break-->', '', $node->body);    $node->body = str_replace('<!--break-->', '', $node->body);
517    
518    if ($node->log != '' && !$teaser && $node->moderate) {    if ($node->log != '' && !$teaser) {
519      $node->body .= '<div class="log"><div class="title">'. t('Log') .':</div>'. filter_xss($node->log) .'</div>';      $node->body .= '<div class="log"><div class="title">'. t('Log') .':</div>'. filter_xss($node->log) .'</div>';
520    }    }
521    
# Line 551  function node_view($node, $teaser = FALS Line 531  function node_view($node, $teaser = FALS
531    node_invoke_nodeapi($node, 'view', $teaser, $page);    node_invoke_nodeapi($node, 'view', $teaser, $page);
532    if ($links) {    if ($links) {
533      $node->links = module_invoke_all('link', 'node', $node, !$page);      $node->links = module_invoke_all('link', 'node', $node, !$page);
534    
535        foreach (module_implements('link_alter') AS $module) {
536          $function = $module .'_link_alter';
537          $function($node, $node->links);
538        }
539    }    }
540    // unset unused $node part so that a bad theme can not open a security hole    // unset unused $node part so that a bad theme can not open a security hole
541    if ($teaser) {    if ($teaser) {
# Line 603  function node_perm() { Line 588  function node_perm() {
588  /**  /**
589   * Implementation of hook_search().   * Implementation of hook_search().
590   */   */
591  function node_search($op = 'search', $keys = null) {  function node_search($op = 'search', $keys = NULL) {
592    switch ($op) {    switch ($op) {
593      case 'name':      case 'name':
594        return t('content');        return t('content');
# Line 625  function node_search($op = 'search', $ke Line 610  function node_search($op = 'search', $ke
610        // Output form for defining rank factor weights.        // Output form for defining rank factor weights.
611        $form['content_ranking'] = array('#type' => 'fieldset', '#title' => t('Content ranking'));        $form['content_ranking'] = array('#type' => 'fieldset', '#title' => t('Content ranking'));
612        $form['content_ranking']['#theme'] = 'node_search_admin';        $form['content_ranking']['#theme'] = 'node_search_admin';
613        $form['content_ranking']['info'] = array('#type' => 'markup', '#value' => '<em>'. t('The following numbers control which properties the content search should favor when ordering the results. Higher numbers mean more influence, zero means the property is ignored. Changing these numbers does not require the search index to be rebuilt.  Changes take effect immediately.') .'</em>');        $form['content_ranking']['info'] = array('#type' => 'markup', '#value' => '<em>'. t('The following numbers control which properties the content search should favor when ordering the results. Higher numbers mean more influence, zero means the property is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') .'</em>');
614    
615        $ranking = array('node_rank_relevance' => t('Keyword relevance'),        $ranking = array('node_rank_relevance' => t('Keyword relevance'),
616                         'node_rank_recent' => t('Recently posted'));                         'node_rank_recent' => t('Recently posted'));
# Line 675  function node_search($op = 'search', $ke Line 660  function node_search($op = 'search', $ke
660        $ranking = array();        $ranking = array();
661        $arguments2 = array();        $arguments2 = array();
662        $join2 = '';        $join2 = '';
       $total = 0;  
663        // Used to avoid joining on node_comment_statistics twice        // Used to avoid joining on node_comment_statistics twice
664        $stats_join = false;        $stats_join = FALSE;
665        if ($weight = (int)variable_get('node_rank_relevance', 5)) {        if ($weight = (int)variable_get('node_rank_relevance', 5)) {
666          // Average relevance values hover around 0.15          // Average relevance values hover around 0.15
667          $ranking[] = '%d * i.relevance';          $ranking[] = '%d * i.relevance';
668          $arguments2[] = $weight;          $arguments2[] = $weight;
         $total += $weight;  
669        }        }
670        if ($weight = (int)variable_get('node_rank_recent', 5)) {        if ($weight = (int)variable_get('node_rank_recent', 5)) {
671          // Exponential decay with half-life of 6 months, starting at last indexed node          // Exponential decay with half-life of 6 months, starting at last indexed node
# Line 690  function node_search($op = 'search', $ke Line 673  function node_search($op = 'search', $ke
673          $arguments2[] = $weight;          $arguments2[] = $weight;
674          $arguments2[] = (int)variable_get('node_cron_last', 0);          $arguments2[] = (int)variable_get('node_cron_last', 0);
675          $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';          $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
676          $stats_join = true;          $stats_join = TRUE;
         $total += $weight;  
677        }        }
678        if (module_exist('comment') && $weight = (int)variable_get('node_rank_comments', 5)) {        if (module_exist('comment') && $weight = (int)variable_get('node_rank_comments', 5)) {
679          // Inverse law that maps the highest reply count on the site to 1 and 0 to 0.          // Inverse law that maps the highest reply count on the site to 1 and 0 to 0.
# Line 702  function node_search($op = 'search', $ke Line 684  function node_search($op = 'search', $ke
684          if (!$stats_join) {          if (!$stats_join) {
685            $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';            $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
686          }          }
         $total += $weight;  
687        }        }
688        if (module_exist('statistics') && variable_get('statistics_count_content_views', 0) &&        if (module_exist('statistics') && variable_get('statistics_count_content_views', 0) &&
689            $weight = (int)variable_get('node_rank_views', 5)) {            $weight = (int)variable_get('node_rank_views', 5)) {
# Line 712  function node_search($op = 'search', $ke Line 693  function node_search($op = 'search', $ke
693          $arguments2[] = $weight;          $arguments2[] = $weight;
694          $arguments2[] = $scale;          $arguments2[] = $scale;
695          $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';          $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
         $total += $weight;  
696        }        }
697        $select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') . ' AS score';        $select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') . ' AS score';
698    
# Line 726  function node_search($op = 'search', $ke Line 706  function node_search($op = 'search', $ke
706    
707          // Get node output (filtered and with module-specific fields).          // Get node output (filtered and with module-specific fields).
708          if (node_hook($node, 'view')) {          if (node_hook($node, 'view')) {
709            node_invoke($node, 'view', false, false);            node_invoke($node, 'view', FALSE, FALSE);
710          }          }
711          else {          else {
712            $node = node_prepare($node, false);            $node = node_prepare($node, FALSE);
713          }          }
714          // Allow modules to change $node->body before viewing.          // Allow modules to change $node->body before viewing.
715          node_invoke_nodeapi($node, 'view', false, false);          node_invoke_nodeapi($node, 'view', FALSE, FALSE);
716    
717          // Fetch comments for snippet          // Fetch comments for snippet
718          $node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');          $node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
# Line 747  function node_search($op = 'search', $ke Line 727  function node_search($op = 'search', $ke
727                             'date' => $node->changed,                             'date' => $node->changed,
728                             'node' => $node,                             'node' => $node,
729                             'extra' => $extra,                             'extra' => $extra,
                            'score' => $item->score / $total,  
730                             'snippet' => search_excerpt($keys, $node->body));                             'snippet' => search_excerpt($keys, $node->body));
731        }        }
732        return $results;        return $results;
# Line 797  function node_configure() { Line 776  function node_configure() {
776      '#options' => array(0 => t('Unlimited'), 200 => t('200 characters'), 400 => t('400 characters'), 600 => t('600 characters'),      '#options' => array(0 => t('Unlimited'), 200 => t('200 characters'), 400 => t('400 characters'), 600 => t('600 characters'),
777        800 => t('800 characters'), 1000 => t('1000 characters'), 1200 => t('1200 characters'), 1400 => t('1400 characters'),        800 => t('800 characters'), 1000 => t('1000 characters'), 1200 => t('1200 characters'), 1400 => t('1400 characters'),
778        1600 => t('1600 characters'), 1800 => t('1800 characters'), 2000 => t('2000 characters')),        1600 => t('1600 characters'), 1800 => t('1800 characters'), 2000 => t('2000 characters')),
779      '#description' => t("The maximum number of characters used in the trimmed version of a post.  Drupal will use this setting to determine at which offset long posts should be trimmed.  The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc.  To disable teasers, set to 'Unlimited'. Note that this setting will only affect new or updated content and will not affect existing teasers.")      '#description' => t("The maximum number of characters used in the trimmed version of a post. Drupal will use this setting to determine at which offset long posts should be trimmed. The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc. To disable teasers, set to 'Unlimited'. Note that this setting will only affect new or updated content and will not affect existing teasers.")
780    );    );
781    
782    $form['node_preview'] = array(    $form['node_preview'] = array(
# Line 826  function node_link($type, $node = 0, $ma Line 805  function node_link($type, $node = 0, $ma
805    $links = array();    $links = array();
806    
807    if ($type == 'node') {    if ($type == 'node') {
808        if (array_key_exists('links', $node)) {
809          $links = $node->links;
810        }
811    
812      if ($main == 1 && $node->teaser && $node->readmore) {      if ($main == 1 && $node->teaser && $node->readmore) {
813        $links[] = l(t('read more'), "node/$node->nid", array('title' => t('Read the rest of this posting.'), 'class' => 'read-more'));        $links['node_read_more'] = array(
814            'title' => t('read more'),
815            'href' => "node/$node->nid",
816            'attributes' => array('title' => t('Read the rest of this posting.'))
817          );
818      }      }
819    }    }
820    
# Line 901  function node_menu($may_cache) { Line 888  function node_menu($may_cache) {
888            'access' => $revisions_access,            'access' => $revisions_access,
889            'weight' => 2,            'weight' => 2,
890            'type' => MENU_LOCAL_TASK);            'type' => MENU_LOCAL_TASK);
         $items[] = array('path' => 'node/'. arg(1) .'/revisions/' . arg(3) . '/delete',  
           'title' => t('revisions'),  
           'callback' => 'node_revisions',  
           'access' => $revisions_access,  
           'weight' => 2,  
           'type' => MENU_CALLBACK);  
         $items[] = array('path' => 'node/'. arg(1) .'/revisions/' . arg(3) . '/revert',  
           'title' => t('revisions'),  
           'callback' => 'node_revisions',  
           'access' => $revisions_access,  
           'weight' => 2,  
           'type' => MENU_CALLBACK);  
891        }        }
892      }      }
893      else if (arg(0) == 'admin' && arg(1) == 'settings' && arg(2) == 'content-types' && is_string(arg(3))) {      else if (arg(0) == 'admin' && arg(1) == 'settings' && arg(2) == 'content-types' && is_string(arg(3))) {
# Line 935  function node_last_changed($nid) { Line 910  function node_last_changed($nid) {
910   */   */
911  function node_operations() {  function node_operations() {
912    $operations = array(    $operations = array(
913      'approve' =>   array(t('Approve the selected posts'), 'UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d'),      'approve' =>   array(t('Approve the selected posts'), 'UPDATE {node} SET status = 1 WHERE nid = %d'),
914      'promote' =>   array(t('Promote the selected posts'), 'UPDATE {node} SET status = 1, promote = 1, moderate = 0 WHERE nid = %d'),      'promote' =>   array(t('Promote the selected posts'), 'UPDATE {node} SET status = 1, promote = 1 WHERE nid = %d'),
915      'sticky' =>    array(t('Make the selected posts sticky'), 'UPDATE {node} SET status = 1, sticky = 1 WHERE nid = %d'),      'sticky' =>    array(t('Make the selected posts sticky'), 'UPDATE {node} SET status = 1, sticky = 1 WHERE nid = %d'),
916      'demote' =>    array(t('Demote the selected posts'), 'UPDATE {node} SET promote = 0 WHERE nid = %d'),      'demote' =>    array(t('Demote the selected posts'), 'UPDATE {node} SET promote = 0 WHERE nid = %d'),
917      'unpublish' => array(t('Unpublish the selected posts'), 'UPDATE {node} SET status = 0 WHERE nid = %d'),      'unpublish' => array(t('Unpublish the selected posts'), 'UPDATE {node} SET status = 0 WHERE nid = %d'),
# Line 952  function node_filters() { Line 927  function node_filters() {
927    // Regular filters    // Regular filters
928    $filters['status'] = array('title' => t('status'),    $filters['status'] = array('title' => t('status'),
929      'options' => array('status-1'   => t('published'),     'status-0' => t('not published'),      'options' => array('status-1'   => t('published'),     'status-0' => t('not published'),
                        'moderate-1' => t('in moderation'), 'moderate-0' => t('not in moderation'),  
930                         'promote-1'  => t('promoted'),      'promote-0' => t('not promoted'),                         'promote-1'  => t('promoted'),      'promote-0' => t('not promoted'),
931                         'sticky-1'   => t('sticky'),        'sticky-0' => t('not sticky')));                         'sticky-1'   => t('sticky'),        'sticky-0' => t('not sticky')));
932    $filters['type'] = array('title' => t('type'), 'options' => node_get_types());    $filters['type'] = array('title' => t('type'), 'options' => node_get_types());
# Line 1123  function node_admin_nodes_submit($form_i Line 1097  function node_admin_nodes_submit($form_i
1097          db_query($operation, $nid);          db_query($operation, $nid);
1098        }        }
1099      }      }
     cache_clear_all();  
1100      drupal_set_message(t('The update has been performed.'));      drupal_set_message(t('The update has been performed.'));
1101    }    }
1102  }  }
# Line 1224  function node_multiple_delete_confirm() Line 1197  function node_multiple_delete_confirm()
1197    $edit = $_POST['edit'];    $edit = $_POST['edit'];
1198    
1199    $form['nodes'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);    $form['nodes'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
1200    // array_filter returns only elements with true values    // array_filter returns only elements with TRUE values
1201    foreach (array_filter($edit['nodes']) as $nid => $value) {    foreach (array_filter($edit['nodes']) as $nid => $value) {
1202      $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid));      $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid));
1203      $form['nodes'][$nid] = array('#type' => 'hidden', '#value' => $nid, '#prefix' => '<li>', '#suffix' => check_plain($title) ."</li>\n");      $form['nodes'][$nid] = array('#type' => 'hidden', '#value' => $nid, '#prefix' => '<li>', '#suffix' => check_plain($title) ."</li>\n");
# Line 1337  function node_revision_revert($nid, $rev Line 1310  function node_revision_revert($nid, $rev
1310    $node = node_load($nid, $revision);    $node = node_load($nid, $revision);
1311    if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {    if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {
1312      if ($node->vid) {      if ($node->vid) {
1313        $form = array();        $node->revision = 1;
1314        $form['nid'] = array('#type' => 'value', '#value' => $node->nid);        $node->log = t('Copy of the revision from %date.', array('%date' => theme('placeholder', format_date($node->revision_timestamp))));
1315        $form['vid'] = array('#type' => 'value', '#value' => $node->vid);        $node->taxonomy = array_keys($node->taxonomy);
1316        return confirm_form('node_revision_revert_confirm', $form,  
1317                       t('Are you sure you want to revert %title to the revision from %revision-date?', array('%title' => theme('placeholder', $node->title), '%revision-date' => theme('placeholder', format_date($node->revision_timestamp)))),        node_save($node);
1318                       "node/$nid/revisions", ' ', t('Revert'), t('Cancel'));  
1319          drupal_set_message(t('%title has been reverted back to the revision from %revision-date', array('%revision-date' => theme('placeholder', format_date($node->revision_timestamp)), '%title' => theme('placeholder', check_plain($node->title)))));
1320          watchdog('content', t('%type: reverted %title revision %revision.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision))));
1321      }      }
1322      else {      else {
1323        drupal_set_message(t('You tried to revert to an invalid revision.'), 'error');        drupal_set_message(t('You tried to revert to an invalid revision.'), 'error');
# Line 1352  function node_revision_revert($nid, $rev Line 1327  function node_revision_revert($nid, $rev
1327    drupal_access_denied();    drupal_access_denied();
1328  }  }
1329    
 function node_revision_revert_confirm_submit($form_id, $form_values) {  
   $nid = $form_values['nid'];  
   $revision = $form_values['vid'];  
   $node = node_load($nid, $revision);  
   $node->revision = 1;  
   $node->log = t('Copy of the revision from %date.', array('%date' => theme('placeholder', format_date($node->revision_timestamp))));  
   if (module_exist('taxonomy')) {  
     $node->taxonomy = array_keys($node->taxonomy);  
   }  
   
   node_save($node);  
   drupal_set_message(t('%title has been reverted back to the revision from %revision-date', array('%revision-date' => theme('placeholder', format_date($node->revision_timestamp)), '%title' => theme('placeholder', check_plain($node->title)))));  
   watchdog('content', t('%type: reverted %title revision %revision.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision))));  
   return 'node/'. $nid .'/revisions';  
 }  
   
1330  /**  /**
1331   * Delete the revision with specified revision number. A "delete revision" nodeapi event is invoked when a   * Delete the revision with specified revision number. A "delete revision" nodeapi event is invoked when a
1332   * revision is deleted.   * revision is deleted.
# Line 1379  function node_revision_delete($nid, $rev Line 1338  function node_revision_delete($nid, $rev
1338        // Don't delete the current revision        // Don't delete the current revision
1339        if ($revision != $node->vid) {        if ($revision != $node->vid) {
1340          $node = node_load($nid, $revision);          $node = node_load($nid, $revision);
1341          $form = array();  
1342          $form['nid'] = array('#type' => 'value', '#value' => $nid);          db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $nid, $revision);
1343          $form['vid'] = array('#type' => 'value', '#value' => $revision);          node_invoke_nodeapi($node, 'delete revision');
1344          return confirm_form('node_revision_delete_confirm', $form,          drupal_set_message(t('Deleted %title revision %revision.', array('%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision))));
1345                       t('Are you sure you want to delete %title revision %revision?', array('%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision))),          watchdog('content', t('%type: deleted %title revision %revision.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision))));
                      "node/$nid/revisions", '', t('Delete'), t('Cancel'));  
1346        }        }
1347    
1348        else {        else {
1349          drupal_set_message(t('Deletion failed. You tried to delete the current revision.'));          drupal_set_message(t('Deletion failed. You tried to delete the current revision.'));
1350        }        }
# Line 1397  function node_revision_delete($nid, $rev Line 1356  function node_revision_delete($nid, $rev
1356        }        }
1357      }      }
1358    }    }
   drupal_access_denied();  
 }  
1359    
1360  function node_revision_delete_confirm_submit($form_id, $form_values) {    drupal_access_denied();
   $node = node_load($form_values['nid'], $form_values['vid']);  
   db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $node->nid, $node->vid);  
   node_invoke_nodeapi($node, 'delete revision');  
   drupal_set_message(t('Deleted %title revision %revision.', array('%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $node->vid))));  
   watchdog('content', t('%type: deleted %title revision %revision.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $node->revision))));  
   
   if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) > 1) {  
     return "node/$node->nid/revisions";  
   }  
   return "node/$node->nid";  
1361  }  }
1362    
1363  /**  /**
# Line 1486  function node_feed($nodes = 0, $channel Line 1433  function node_feed($nodes = 0, $channel
1433        node_invoke_nodeapi($item, 'view', $teaser, FALSE);        node_invoke_nodeapi($item, 'view', $teaser, FALSE);
1434      }      }
1435    
     // Allow modules to add additional item fields  
     $extra = node_invoke_nodeapi($item, 'rss item');  
     $extra = array_merge($extra, array(array('key' => 'pubDate', 'value' =>  date('r', $item->created)), array('key' => 'dc:creator', 'value' => $item->name), array('key' => 'guid', 'value' => $item->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false'))));  
     foreach ($extra as $element) {  
       if ($element['namespace']) {  
         $namespaces = array_merge($namespaces, $element['namespace']);  
       }  
     }  
   
1436      // Prepare the item description      // Prepare the item description
1437      switch ($item_length) {      switch ($item_length) {
1438        case 'fulltext':        case 'fulltext':
# Line 1511  function node_feed($nodes = 0, $channel Line 1449  function node_feed($nodes = 0, $channel
1449          break;          break;
1450      }      }
1451    
1452        // Allow modules to add additional item fields
1453        $extra = node_invoke_nodeapi($item, 'rss item');
1454        $extra = array_merge($extra, array(array('key' => 'pubDate', 'value' =>  date('r', $item->created)), array('key' => 'dc:creator', 'value' => $item->name), array('key' => 'guid', 'value' => $item->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'FALSE'))));
1455        foreach ($extra as $element) {
1456          if ($element['namespace']) {
1457            $namespaces = array_merge($namespaces, $element['namespace']);
1458          }
1459        }
1460      $items .= format_rss_item($item->title, $link, $item_text, $extra);      $items .= format_rss_item($item->title, $link, $item_text, $extra);
1461    }    }
1462    
# Line 1561  function node_submit($node) { Line 1507  function node_submit($node) {
1507    }    }
1508    // Force defaults in case people modify the form:    // Force defaults in case people modify the form:
1509    $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));    $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
1510    foreach (array('status', 'moderate', 'promote', 'sticky', 'revision') as $key) {    foreach (array('status', 'promote', 'sticky', 'revision') as $key) {
1511      if (!$access || !isset($node->$key)) {      if (!$access || !isset($node->$key)) {
1512        $node->$key = in_array($key, $node_options);        $node->$key = in_array($key, $node_options);
1513      }      }
# Line 1590  function node_validate($node, $form = ar Line 1536  function node_validate($node, $form = ar
1536    }    }
1537    
1538    if (isset($node->nid) && (node_last_changed($node->nid) > $node->changed)) {    if (isset($node->nid) && (node_last_changed($node->nid) > $node->changed)) {
1539      form_set_error('changed', t('This content has been modified by another user, changes cannot be saved.'));      form_set_error('changed', t('This content has been modified by another user; changes cannot be saved.'));
1540    }    }
1541    
1542    if (user_access('administer nodes')) {    if (user_access('administer nodes')) {
1543      // Validate the "authored by" field.      // Validate the "authored by" field.
1544      if (!empty($node->name) && !($account = user_load(array('name' => $node->name)))) {      if (!empty($node->name) && !($account = user_load(array('name' => $node->name)))) {
1545        // The use of empty() is mandatory in the context of usernames        // The use of empty() is mandatory in the context of usernames
1546        // as the empty string denotes the anonymous user.  In case we        // as the empty string denotes the anonymous user. In case we
1547        // are dealing with an anonymous user we set the user ID to 0.        // are dealing with an anonymous user we set the user ID to 0.
1548        form_set_error('name', t('The username %name does not exist.', array ('%name' => theme('placeholder', $node->name))));        form_set_error('name', t('The username %name does not exist.', array ('%name' => theme('placeholder', $node->name))));
1549      }      }
# Line 1654  function node_form_array($node) { Line 1600  function node_form_array($node) {
1600     * Basic node information.     * Basic node information.
1601     * These elements are just values so they are not even sent to the client.     * These elements are just values so they are not even sent to the client.
1602     */     */
1603    foreach (array('nid', 'vid', 'uid', 'created', 'type') as $key) {    foreach (array('nid', 'vid', 'uid', 'created', 'changed', 'type') as $key) {
1604      $form[$key] = array('#type' => 'value', '#value' => $node->$key);      $form[$key] = array('#type' => 'value', '#value' => $node->$key);
1605    }    }
1606    
   // Changed must be sent to the client, for later overwrite error checking.  
   $form['changed'] = array('#type' => 'hidden', '#default_value' => $node->changed);  
   
1607    // Get the node-specific bits.    // Get the node-specific bits.
1608    $form = array_merge_recursive($form, node_invoke($node, 'form'));    $form = array_merge_recursive($form, node_invoke($node, 'form'));
1609    if (!isset($form['title']['#weight'])) {    if (!isset($form['title']['#weight'])) {
# Line 1670  function node_form_array($node) { Line 1613  function node_form_array($node) {
1613    $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));    $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
1614    // If this is a new node, fill in the default values.    // If this is a new node, fill in the default values.
1615    if (!isset($node->nid)) {    if (!isset($node->nid)) {
1616      foreach (array('status', 'moderate', 'promote', 'sticky', 'revision') as $key) {      foreach (array('status', 'promote', 'sticky', 'revision') as $key) {
1617        $node->$key = in_array($key, $node_options);        $node->$key = in_array($key, $node_options);
1618      }      }
1619      global $user;      global $user;
# Line 1695  function node_form_array($node) { Line 1638  function node_form_array($node) {
1638      // Node options for administrators      // Node options for administrators
1639      $form['options'] = array('#type' => 'fieldset', '#title' => t('Publishing options'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => 25);      $form['options'] = array('#type' => 'fieldset', '#title' => t('Publishing options'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => 25);
1640      $form['options']['status']   = array('#type' => 'checkbox', '#title' => t('Published'), '#default_value' => $node->status);      $form['options']['status']   = array('#type' => 'checkbox', '#title' => t('Published'), '#default_value' => $node->status);
     $form['options']['moderate'] = array('#type' => 'checkbox', '#title' => t('In moderation queue'), '#default_value' => $node->moderate);  
1641      $form['options']['promote']  = array('#type' => 'checkbox', '#title' => t('Promoted to front page'), '#default_value' => $node->promote);      $form['options']['promote']  = array('#type' => 'checkbox', '#title' => t('Promoted to front page'), '#default_value' => $node->promote);
1642      $form['options']['sticky']   = array('#type' => 'checkbox', '#title' => t('Sticky at top of lists'), '#default_value' => $node->sticky);      $form['options']['sticky']   = array('#type' => 'checkbox', '#title' => t('Sticky at top of lists'), '#default_value' => $node->sticky);
1643      $form['options']['revision'] = array('#type' => 'checkbox', '#title' => t('Create new revision'), '#default_value' => $node->revision);      $form['options']['revision'] = array('#type' => 'checkbox', '#title' => t('Create new revision'), '#default_value' => $node->revision);
# Line 1724  function node_form_add_preview($form) { Line 1666  function node_form_add_preview($form) {
1666    
1667    $op = isset($_POST['op']) ? $_POST['op'] : '';    $op = isset($_POST['op']) ? $_POST['op'] : '';
1668    if ($op == t('Preview')) {    if ($op == t('Preview')) {
     // Invoke full validation for the form, to protect against cross site  
     // request forgeries (CSRF) and setting arbitrary values for fields such as  
     // the input format. Preview the node only when form validation does not  
     // set any errors.  
1669      drupal_validate_form($form['form_id']['#value'], $form);      drupal_validate_form($form['form_id']['#value'], $form);
1670      if (!form_get_errors()) {      if (!form_get_errors()) {
1671        // Because the node preview may display a form, we must render it        // We pass the global $form_values here to preserve changes made during form validation
1672        // outside the node submission form tags using the #prefix property        $form['node_preview'] = array('#value' => node_preview((object)$form_values), '#weight' => -100);
       // (i.e. to prevent illegally nested forms).  
       // If the node form already has a #prefix, we must preserve it.  
       // In this case, we put the preview before the #prefix so we keep  
       // the #prefix as "close" to the rest of the form as possible,  
       // for example, to keep a <div> only around the form, not the  
       // preview. We pass the global $form_values here to preserve  
       // changes made during form validation.  
       $preview = node_preview((object)$form_values);  
       $form['#prefix'] = isset($form['#prefix']) ? $preview . $form['#prefix'] : $preview;  
1673      }      }
1674    }    }
1675    if (variable_get('node_preview', 0) && (form_get_errors() || $op != t('Preview'))) {    if (variable_get('node_preview', 0) && (form_get_errors() || $op != t('Preview'))) {
# Line 1751  function node_form_add_preview($form) { Line 1680  function node_form_add_preview($form) {
1680    
1681  function theme_node_form($form) {  function theme_node_form($form) {
1682    $output = "\n<div class=\"node-form\">\n";    $output = "\n<div class=\"node-form\">\n";
1683      if (isset($form['node_preview'])) {
1684        $output .= form_render($form['node_preview']);
1685      }
1686    
1687    // Admin form fields and submit buttons must be rendered first, because    // Admin form fields and submit buttons must be rendered first, because
1688    // they need to go to the bottom of the form, and so should not be part of    // they need to go to the bottom of the form, and so should not be part of
# Line 1804  function node_add($type) { Line 1736  function node_add($type) {
1736    else {    else {
1737      // If no (valid) node type has been provided, display a node type overview.      // If no (valid) node type has been provided, display a node type overview.
1738      foreach (node_get_types() as $type => $name) {      foreach (node_get_types() as $type => $name) {
1739        if (node_access('create', $type)) {        if (module_invoke(node_get_base($type), 'access', 'create', $type)) {
1740          $out = '<dt>'. l($name, "node/add/$type", array('title' => t('Add a new %s.', array('%s' => $name)))) .'</dt>';          $out = '<dt>'. l($name, "node/add/$type", array('title' => t('Add a new %s.', array('%s' => $name)))) .'</dt>';
1741          $out .= '<dd>'. implode("\n", module_invoke_all('help', 'node/add#'. $type)) .'</dd>';          $out .= '<dd>'. implode("\n", module_invoke_all('help', 'node/add#'. $type)) .'</dd>';
1742          $item[$name] = $out;          $item[$name] = $out;
# Line 1834  function node_preview($node) { Line 1766  function node_preview($node) {
1766        // user ID 0 denotes the anonymous user.        // user ID 0 denotes the anonymous user.
1767        if ($user = user_load(array('name' => $node->name))) {        if ($user = user_load(array('name' => $node->name))) {
1768          $node->uid = $user->uid;          $node->uid = $user->uid;
         $node->picture = $user->picture;  
1769        }        }
1770        else {        else {
1771          $node->uid = 0; // anonymous user          $node->uid = 0; // anonymous user
# Line 1843  function node_preview($node) { Line 1774  function node_preview($node) {
1774      else if ($node->uid) {      else if ($node->uid) {
1775        $user = user_load(array('uid' => $node->uid));        $user = user_load(array('uid' => $node->uid));
1776        $node->name = $user->name;        $node->name = $user->name;
       $node->picture = $user->picture;  
1777      }      }
1778    
1779      // Set the timestamps when needed:      // Set the timestamps when needed:
# Line 1905  function node_form_submit($form_id, $edi Line 1835  function node_form_submit($form_id, $edi
1835    if ($node->nid) {    if ($node->nid) {
1836      // Check whether the current user has the proper access rights to      // Check whether the current user has the proper access rights to
1837      // perform this operation:      // perform this operation:
1838      $original_node = node_load($node->nid); //check access rights using the unmodified node      if (node_access('update', $node)) {
     if (node_access('update', $original_node)) {  
1839        node_save($node);        node_save($node);
1840        watchdog('content', t('%type: updated %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));        watchdog('content', t('%type: updated %title.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title))), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
1841        drupal_set_message(t('The %post was updated.', array ('%post' => node_get_name($node))));        drupal_set_message(t('The %post was updated.', array ('%post' => node_get_name($node))));
# Line 2018  function node_revisions() { Line 1947  function node_revisions() {
1947          }          }
1948          break;          break;
1949        case 'revert':        case 'revert':
1950          return node_revision_revert(arg(1), arg(3));          node_revision_revert(arg(1), arg(3));
1951          break;          break;
1952        case 'delete':        case 'delete':
1953          return node_revision_delete(arg(1), arg(3));          node_revision_delete(arg(1), arg(3));
1954          break;          break;
1955      }      }
1956    }    }
# Line 2072  function node_page_default() { Line 2001  function node_page_default() {
2001            Finally, you can <a href="%content">create content</a> for your website. This message will disappear once you have published your first post.            Finally, you can <a href="%content">create content</a> for your website. This message will disappear once you have published your first post.
2002          </li>          </li>
2003        </ol>        </ol>
2004        <p>For more information, please refer to the <a href="%help">Help section</a>, or the <a href="%handbook">online Drupal handbooks</a>. You may also post at the <a href="%forum">Drupal forum</a>, or view the wide range of <a href="%support">other support options</a> available.</p>',        <p>For more information, please refer to the <a href="%help">help section</a>, or the <a href="%handbook">online Drupal handbooks</a>. You may also post at the <a href="%forum">Drupal forum</a>, or view the wide range of <a href="%support">other support options</a> available.</p>',
2005        array('%drupal' => 'http://drupal.org/', '%register' => url('user/register'), '%admin' => url('admin'), '%config' => url('admin/settings'), '%modules' => url('admin/modules'), '%download_modules' => 'http://drupal.org/project/modules', '%themes' => url('admin/themes'), '%download_themes' => 'http://drupal.org/project/themes', '%content' => url('node/add'), '%help' => url('admin/help'), '%handbook' => 'http://drupal.org/handbooks', '%forum' => 'http://drupal.org/forum', '%support' => 'http://drupal.org/support')        array('%drupal' => 'http://drupal.org/', '%register' => url('user/register'), '%admin' => url('admin'), '%config' => url('admin/settings'), '%modules' => url('admin/modules'), '%download_modules' => 'http://drupal.org/project/modules', '%themes' => url('admin/themes'), '%download_themes' => 'http://drupal.org/project/themes', '%content' => url('node/add'), '%help' => url('admin/help'), '%handbook' => 'http://drupal.org/handbooks', '%forum' => 'http://drupal.org/forum', '%support' => 'http://drupal.org/support')
2006      );      );
2007      $output = '<div id="first-time">'. $output .'</div>';      $output = '<div id="first-time">'. $output .'</div>';
# Line 2168  function node_update_index() { Line 2097  function node_update_index() {
2097    variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node_comment_statistics}'))));    variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node_comment_statistics}'))));
2098    variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node_counter}'))));    variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node_counter}'))));
2099    
2100    $result = db_query_range('SELECT GREATEST(IF(c.last_comment_timestamp IS NULL, 0, c.last_comment_timestamp), n.changed) as last_change, n.nid FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND ((GREATEST(n.changed, c.last_comment_timestamp) = %d AND n.nid > %d) OR (n.changed > %d OR c.last_comment_timestamp > %d)) ORDER BY GREATEST(n.changed, c.last_comment_timestamp) ASC, n.nid ASC', $last, $last_nid, $last, $last, $last, 0, $limit);    $result = db_query_range('SELECT GREATEST(c.last_comment_timestamp, n.changed) as last_change, n.nid FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND ((GREATEST(n.changed, c.last_comment_timestamp) = %d AND n.nid > %d) OR (n.changed > %d OR c.last_comment_timestamp > %d)) ORDER BY GREATEST(n.changed, c.last_comment_timestamp) ASC, n.nid ASC', $last, $last_nid, $last, $last, $last, 0, $limit);
2101    
2102    while ($node = db_fetch_object($result)) {    while ($node = db_fetch_object($result)) {
2103      $last_change = $node->last_change;      $last_change = $node->last_change;
# Line 2177  function node_update_index() { Line 2106  function node_update_index() {
2106    
2107      // Get node output (filtered and with module-specific fields).      // Get node output (filtered and with module-specific fields).
2108      if (node_hook($node, 'view')) {      if (node_hook($node, 'view')) {
2109        node_invoke($node, 'view', false, false);        node_invoke($node, 'view', FALSE, FALSE);
2110      }      }
2111      else {      else {
2112        $node = node_prepare($node, false);        $node = node_prepare($node, FALSE);
2113      }      }
2114      // Allow modules to change $node->body before viewing.      // Allow modules to change $node->body before viewing.
2115      node_invoke_nodeapi($node, 'view', false, false);      node_invoke_nodeapi($node, 'view', FALSE, FALSE);
2116    
2117      $text = '<h1>'. check_plain($node->title) .'</h1>'. $node->body;      $text = '<h1>'. check_plain($node->title) .'</h1>'. $node->body;
2118    
# Line 2209  function node_form_alter($form_id, &$for Line 2138  function node_form_alter($form_id, &$for
2138        '#default_value' => variable_get('node_options_'. $form['type']['#value'], array('status', 'promote')),        '#default_value' => variable_get('node_options_'. $form['type']['#value'], array('status', 'promote')),
2139        '#options' => array(        '#options' => array(
2140          'status' => t('Published'),          'status' => t('Published'),
         'moderate' => t('In moderation queue'),  
2141          'promote' => t('Promoted to front page'),          'promote' => t('Promoted to front page'),
2142          'sticky' => t('Sticky at top of lists'),          'sticky' => t('Sticky at top of lists'),
2143          'revision' => t('Create new revision'),          'revision' => t('Create new revision'),
# Line 2219  function node_form_alter($form_id, &$for Line 2147  function node_form_alter($form_id, &$for
2147    }    }
2148    
2149    // Advanced node search form    // Advanced node search form
2150    elseif ($form_id == 'search_form' && arg(1) == 'node') {    elseif ($form_id == 'search_form' && arg(1) == 'node' && user_access('use advanced search')) {
2151      // Keyword boxes:      // Keyword boxes:
2152      $form['advanced'] = array(      $form['advanced'] = array(
2153        '#type' => 'fieldset',        '#type' => 'fieldset',

Legend:
Removed from v.1.641.2.32  
changed lines
  Added in v.1.657

  ViewVC Help
Powered by ViewVC 1.1.2