| 1 |
<?php |
<?php |
| 2 |
// $Id: node.module,v 1.640 2006/04/23 05:22:05 drumm Exp $ |
// $Id: node.module,v 1.641.2.29 2007/01/01 22:16:11 killes Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* @file |
* @file |
| 43 |
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>'); |
| 44 |
} |
} |
| 45 |
|
|
| 46 |
if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'revisions') { |
if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'revisions' && !arg(3)) { |
| 47 |
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.'); |
| 48 |
} |
} |
| 49 |
|
|
| 160 |
return $body; |
return $body; |
| 161 |
} |
} |
| 162 |
|
|
| 163 |
|
// If a valid delimiter has been specified, use it to chop off the teaser. |
| 164 |
|
if ($delimiter !== FALSE) { |
| 165 |
|
return substr($body, 0, $delimiter); |
| 166 |
|
} |
| 167 |
|
|
| 168 |
// 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 |
| 169 |
// 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 |
| 170 |
// parse errors. |
// parse errors. |
| 175 |
} |
} |
| 176 |
} |
} |
| 177 |
|
|
|
// If a valid delimiter has been specified, use it to chop of the teaser. |
|
|
if ($delimiter !== FALSE) { |
|
|
return substr($body, 0, $delimiter); |
|
|
} |
|
|
|
|
| 178 |
// If we have a short body, the entire body is the teaser. |
// If we have a short body, the entire body is the teaser. |
| 179 |
if (strlen($body) < $size) { |
if (strlen($body) < $size) { |
| 180 |
return $body; |
return $body; |
| 181 |
} |
} |
| 182 |
|
|
| 183 |
// In some cases, no delimiter has been specified (e.g. when posting using |
// The teaser may not be longer than maximum length specified. Initial slice. |
| 184 |
// the Blogger API). In this case, we try to split at paragraph boundaries. |
$teaser = truncate_utf8($body, $size); |
| 185 |
// When even the first paragraph is too long, we try to split at the end of |
$position = 0; |
| 186 |
// the next sentence. |
// Cache the reverse of the teaser. |
| 187 |
$breakpoints = array('</p>' => 4, '<br />' => 0, '<br>' => 0, "\n" => 0, '. ' => 1, '! ' => 1, '? ' => 1, '。' => 3, '؟ ' => 1); |
$reversed = strrev($teaser); |
| 188 |
foreach ($breakpoints as $point => $charnum) { |
|
| 189 |
if ($length = strpos($body, $point, $size)) { |
// In some cases, no delimiter has been specified. In this case, we try to |
| 190 |
return substr($body, 0, $length + $charnum); |
// split at paragraph boundaries. |
| 191 |
|
$breakpoints = array('</p>' => 0, '<br />' => 6, '<br>' => 4, "\n" => 1); |
| 192 |
|
// We use strpos on the reversed needle and haystack for speed. |
| 193 |
|
foreach ($breakpoints as $point => $offset) { |
| 194 |
|
$length = strpos($reversed, strrev($point)); |
| 195 |
|
if ($length !== FALSE) { |
| 196 |
|
$position = - $length - $offset; |
| 197 |
|
return ($position == 0) ? $teaser : substr($teaser, 0, $position); |
| 198 |
} |
} |
| 199 |
} |
} |
| 200 |
|
|
| 201 |
// If all else fails, we simply truncate the string. |
// When even the first paragraph is too long, we try to split at the end of |
| 202 |
return truncate_utf8($body, $size); |
// the last full sentence. |
| 203 |
|
$breakpoints = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1); |
| 204 |
|
$min_length = strlen($reversed); |
| 205 |
|
foreach ($breakpoints as $point => $offset) { |
| 206 |
|
$length = strpos($reversed, strrev($point)); |
| 207 |
|
if ($length !== FALSE) { |
| 208 |
|
$min_length = min($length, $min_length); |
| 209 |
|
$position = 0 - $length - $offset; |
| 210 |
|
} |
| 211 |
|
} |
| 212 |
|
return ($position == 0) ? $teaser : substr($teaser, 0, $position); |
| 213 |
} |
} |
| 214 |
|
|
| 215 |
function _node_names($op = '', $node = NULL) { |
function _node_names($op = '', $node = NULL) { |
| 273 |
/** |
/** |
| 274 |
* Return the list of available node types. |
* Return the list of available node types. |
| 275 |
* |
* |
|
* @param $node |
|
|
* Either a node object, a node array, or a string containing the node type. |
|
| 276 |
* @return |
* @return |
| 277 |
* An array consisting ('#type' => name) pairs. |
* An array consisting ('#type' => name) pairs. |
| 278 |
*/ |
*/ |
| 360 |
$nodes = array(); |
$nodes = array(); |
| 361 |
} |
} |
| 362 |
|
|
| 363 |
|
$cachable = ($revision == NULL); |
| 364 |
$arguments = array(); |
$arguments = array(); |
| 365 |
if (is_numeric($param)) { |
if (is_numeric($param)) { |
|
$cachable = $revision == NULL; |
|
| 366 |
if ($cachable && isset($nodes[$param])) { |
if ($cachable && isset($nodes[$param])) { |
| 367 |
return $nodes[$param]; |
return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param]; |
| 368 |
} |
} |
| 369 |
$cond = 'n.nid = %d'; |
$cond = 'n.nid = %d'; |
| 370 |
$arguments[] = $param; |
$arguments[] = $param; |
| 379 |
} |
} |
| 380 |
|
|
| 381 |
// Retrieve the node. |
// Retrieve the node. |
| 382 |
|
// No db_rewrite_sql is applied so as to get complete indexing for search. |
| 383 |
if ($revision) { |
if ($revision) { |
| 384 |
array_unshift($arguments, $revision); |
array_unshift($arguments, $revision); |
| 385 |
$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.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('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)); |
| 386 |
} |
} |
| 387 |
else { |
else { |
| 388 |
$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.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('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)); |
| 389 |
} |
} |
| 390 |
|
|
| 391 |
if ($node->nid) { |
if ($node->nid) { |
| 402 |
$node->$key = $value; |
$node->$key = $value; |
| 403 |
} |
} |
| 404 |
} |
} |
| 405 |
} |
if ($cachable) { |
| 406 |
|
$nodes[$node->nid] = is_object($node) ? drupal_clone($node) : $node; |
| 407 |
if ($cachable) { |
} |
|
$nodes[$param] = $node; |
|
| 408 |
} |
} |
| 409 |
|
|
| 410 |
return $node; |
return $node; |
| 675 |
$ranking = array(); |
$ranking = array(); |
| 676 |
$arguments2 = array(); |
$arguments2 = array(); |
| 677 |
$join2 = ''; |
$join2 = ''; |
| 678 |
|
$total = 0; |
| 679 |
// Used to avoid joining on node_comment_statistics twice |
// Used to avoid joining on node_comment_statistics twice |
| 680 |
$stats_join = false; |
$stats_join = false; |
| 681 |
if ($weight = (int)variable_get('node_rank_relevance', 5)) { |
if ($weight = (int)variable_get('node_rank_relevance', 5)) { |
| 682 |
// Average relevance values hover around 0.15 |
// Average relevance values hover around 0.15 |
| 683 |
$ranking[] = '%d * i.relevance'; |
$ranking[] = '%d * i.relevance'; |
| 684 |
$arguments2[] = $weight; |
$arguments2[] = $weight; |
| 685 |
|
$total += $weight; |
| 686 |
} |
} |
| 687 |
if ($weight = (int)variable_get('node_rank_recent', 5)) { |
if ($weight = (int)variable_get('node_rank_recent', 5)) { |
| 688 |
// 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 |
| 691 |
$arguments2[] = (int)variable_get('node_cron_last', 0); |
$arguments2[] = (int)variable_get('node_cron_last', 0); |
| 692 |
$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'; |
| 693 |
$stats_join = true; |
$stats_join = true; |
| 694 |
|
$total += $weight; |
| 695 |
} |
} |
| 696 |
if (module_exist('comment') && $weight = (int)variable_get('node_rank_comments', 5)) { |
if (module_exist('comment') && $weight = (int)variable_get('node_rank_comments', 5)) { |
| 697 |
// 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. |
| 702 |
if (!$stats_join) { |
if (!$stats_join) { |
| 703 |
$join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid'; |
$join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid'; |
| 704 |
} |
} |
| 705 |
|
$total += $weight; |
| 706 |
} |
} |
| 707 |
if (module_exist('statistics') && variable_get('statistics_count_content_views', 0) && |
if (module_exist('statistics') && variable_get('statistics_count_content_views', 0) && |
| 708 |
$weight = (int)variable_get('node_rank_views', 5)) { |
$weight = (int)variable_get('node_rank_views', 5)) { |
| 712 |
$arguments2[] = $weight; |
$arguments2[] = $weight; |
| 713 |
$arguments2[] = $scale; |
$arguments2[] = $scale; |
| 714 |
$join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid'; |
$join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid'; |
| 715 |
|
$total += $weight; |
| 716 |
} |
} |
| 717 |
$select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') . ' AS score'; |
$select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') . ' AS score'; |
| 718 |
|
|
| 747 |
'date' => $node->changed, |
'date' => $node->changed, |
| 748 |
'node' => $node, |
'node' => $node, |
| 749 |
'extra' => $extra, |
'extra' => $extra, |
| 750 |
|
'score' => $item->score / $total, |
| 751 |
'snippet' => search_excerpt($keys, $node->body)); |
'snippet' => search_excerpt($keys, $node->body)); |
| 752 |
} |
} |
| 753 |
return $results; |
return $results; |
| 826 |
$links = array(); |
$links = array(); |
| 827 |
|
|
| 828 |
if ($type == 'node') { |
if ($type == 'node') { |
|
if (array_key_exists('links', $node)) { |
|
|
$links = $node->links; |
|
|
} |
|
|
|
|
| 829 |
if ($main == 1 && $node->teaser && $node->readmore) { |
if ($main == 1 && $node->teaser && $node->readmore) { |
| 830 |
$links[] = l(t('read more'), "node/$node->nid", array('title' => t('Read the rest of this posting.'), 'class' => 'read-more')); |
$links[] = l(t('read more'), "node/$node->nid", array('title' => t('Read the rest of this posting.'), 'class' => 'read-more')); |
| 831 |
} |
} |
| 864 |
$items[] = array('path' => 'node', 'title' => t('content'), |
$items[] = array('path' => 'node', 'title' => t('content'), |
| 865 |
'callback' => 'node_page', |
'callback' => 'node_page', |
| 866 |
'access' => user_access('access content'), |
'access' => user_access('access content'), |
| 867 |
'type' => MENU_SUGGESTED_ITEM); |
'type' => MENU_MODIFIABLE_BY_ADMIN); |
| 868 |
$items[] = array('path' => 'node/add', 'title' => t('create content'), |
$items[] = array('path' => 'node/add', 'title' => t('create content'), |
| 869 |
'callback' => 'node_page', |
'callback' => 'node_page', |
| 870 |
'access' => user_access('access content'), |
'access' => user_access('access content'), |
| 901 |
'access' => $revisions_access, |
'access' => $revisions_access, |
| 902 |
'weight' => 2, |
'weight' => 2, |
| 903 |
'type' => MENU_LOCAL_TASK); |
'type' => MENU_LOCAL_TASK); |
| 904 |
|
$items[] = array('path' => 'node/'. arg(1) .'/revisions/' . arg(3) . '/delete', |
| 905 |
|
'title' => t('revisions'), |
| 906 |
|
'callback' => 'node_revisions', |
| 907 |
|
'access' => $revisions_access, |
| 908 |
|
'weight' => 2, |
| 909 |
|
'type' => MENU_CALLBACK); |
| 910 |
|
$items[] = array('path' => 'node/'. arg(1) .'/revisions/' . arg(3) . '/revert', |
| 911 |
|
'title' => t('revisions'), |
| 912 |
|
'callback' => 'node_revisions', |
| 913 |
|
'access' => $revisions_access, |
| 914 |
|
'weight' => 2, |
| 915 |
|
'type' => MENU_CALLBACK); |
| 916 |
} |
} |
| 917 |
} |
} |
| 918 |
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))) { |
| 936 |
function node_operations() { |
function node_operations() { |
| 937 |
$operations = array( |
$operations = array( |
| 938 |
'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, moderate = 0 WHERE nid = %d'), |
| 939 |
'promote' => array(t('Promote the selected posts'), 'UPDATE {node} SET status = 1, promote = 1 WHERE nid = %d'), |
'promote' => array(t('Promote the selected posts'), 'UPDATE {node} SET status = 1, promote = 1, moderate = 0 WHERE nid = %d'), |
| 940 |
'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'), |
| 941 |
'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'), |
| 942 |
'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'), |
| 1123 |
db_query($operation, $nid); |
db_query($operation, $nid); |
| 1124 |
} |
} |
| 1125 |
} |
} |
| 1126 |
|
cache_clear_all(); |
| 1127 |
drupal_set_message(t('The update has been performed.')); |
drupal_set_message(t('The update has been performed.')); |
| 1128 |
} |
} |
| 1129 |
} |
} |
| 1337 |
$node = node_load($nid, $revision); |
$node = node_load($nid, $revision); |
| 1338 |
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)) { |
| 1339 |
if ($node->vid) { |
if ($node->vid) { |
| 1340 |
$node->revision = 1; |
$form = array(); |
| 1341 |
$node->log = t('Copy of the revision from %date.', array('%date' => theme('placeholder', format_date($node->revision_timestamp)))); |
$form['nid'] = array('#type' => 'value', '#value' => $node->nid); |
| 1342 |
$node->taxonomy = array_keys($node->taxonomy); |
$form['vid'] = array('#type' => 'value', '#value' => $node->vid); |
| 1343 |
|
return confirm_form('node_revision_revert_confirm', $form, |
| 1344 |
node_save($node); |
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)))), |
| 1345 |
|
"node/$nid/revisions", ' ', t('Revert'), t('Cancel')); |
|
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)))); |
|
| 1346 |
} |
} |
| 1347 |
else { |
else { |
| 1348 |
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'); |
| 1352 |
drupal_access_denied(); |
drupal_access_denied(); |
| 1353 |
} |
} |
| 1354 |
|
|
| 1355 |
|
function node_revision_revert_confirm_submit($form_id, $form_values) { |
| 1356 |
|
$nid = $form_values['nid']; |
| 1357 |
|
$revision = $form_values['vid']; |
| 1358 |
|
$node = node_load($nid, $revision); |
| 1359 |
|
$node->revision = 1; |
| 1360 |
|
$node->log = t('Copy of the revision from %date.', array('%date' => theme('placeholder', format_date($node->revision_timestamp)))); |
| 1361 |
|
if (module_exist('taxonomy')) { |
| 1362 |
|
$node->taxonomy = array_keys($node->taxonomy); |
| 1363 |
|
} |
| 1364 |
|
|
| 1365 |
|
node_save($node); |
| 1366 |
|
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))))); |
| 1367 |
|
watchdog('content', t('%type: reverted %title revision %revision.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision)))); |
| 1368 |
|
return 'node/'. $nid .'/revisions'; |
| 1369 |
|
} |
| 1370 |
|
|
| 1371 |
/** |
/** |
| 1372 |
* 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 |
| 1373 |
* revision is deleted. |
* revision is deleted. |
| 1379 |
// Don't delete the current revision |
// Don't delete the current revision |
| 1380 |
if ($revision != $node->vid) { |
if ($revision != $node->vid) { |
| 1381 |
$node = node_load($nid, $revision); |
$node = node_load($nid, $revision); |
| 1382 |
|
$form = array(); |
| 1383 |
db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $nid, $revision); |
$form['nid'] = array('#type' => 'value', '#value' => $nid); |
| 1384 |
node_invoke_nodeapi($node, 'delete revision'); |
$form['vid'] = array('#type' => 'value', '#value' => $revision); |
| 1385 |
drupal_set_message(t('Deleted %title revision %revision.', array('%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision)))); |
return confirm_form('node_revision_delete_confirm', $form, |
| 1386 |
watchdog('content', t('%type: deleted %title revision %revision.', array('%type' => theme('placeholder', t($node->type)), '%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision)))); |
t('Are you sure you want to delete %title revision %revision?', array('%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $revision))), |
| 1387 |
|
"node/$nid/revisions", '', t('Delete'), t('Cancel')); |
| 1388 |
} |
} |
|
|
|
| 1389 |
else { |
else { |
| 1390 |
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.')); |
| 1391 |
} |
} |
| 1397 |
} |
} |
| 1398 |
} |
} |
| 1399 |
} |
} |
|
|
|
| 1400 |
drupal_access_denied(); |
drupal_access_denied(); |
| 1401 |
} |
} |
| 1402 |
|
|
| 1403 |
|
function node_revision_delete_confirm_submit($form_id, $form_values) { |
| 1404 |
|
$node = node_load($form_values['nid'], $form_values['vid']); |
| 1405 |
|
db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $node->nid, $node->vid); |
| 1406 |
|
node_invoke_nodeapi($node, 'delete revision'); |
| 1407 |
|
drupal_set_message(t('Deleted %title revision %revision.', array('%title' => theme('placeholder', $node->title), '%revision' => theme('placeholder', $node->vid)))); |
| 1408 |
|
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)))); |
| 1409 |
|
|
| 1410 |
|
if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) > 1) { |
| 1411 |
|
return "node/$node->nid/revisions"; |
| 1412 |
|
} |
| 1413 |
|
return "node/$node->nid"; |
| 1414 |
|
} |
| 1415 |
|
|
| 1416 |
/** |
/** |
| 1417 |
* Return a list of all the existing revision numbers. |
* Return a list of all the existing revision numbers. |
| 1418 |
*/ |
*/ |
| 1460 |
global $base_url, $locale; |
global $base_url, $locale; |
| 1461 |
|
|
| 1462 |
if (!$nodes) { |
if (!$nodes) { |
| 1463 |
$nodes = db_query_range(db_rewrite_sql('SELECT n.nid FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, variable_get('feed_default_items', 10)); |
$nodes = db_query_range(db_rewrite_sql('SELECT n.nid, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, variable_get('feed_default_items', 10)); |
| 1464 |
} |
} |
| 1465 |
|
|
| 1466 |
$item_length = variable_get('feed_item_length', 'teaser'); |
$item_length = variable_get('feed_item_length', 'teaser'); |
| 1486 |
node_invoke_nodeapi($item, 'view', $teaser, FALSE); |
node_invoke_nodeapi($item, 'view', $teaser, FALSE); |
| 1487 |
} |
} |
| 1488 |
|
|
| 1489 |
|
// Allow modules to add additional item fields |
| 1490 |
|
$extra = node_invoke_nodeapi($item, 'rss item'); |
| 1491 |
|
$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')))); |
| 1492 |
|
foreach ($extra as $element) { |
| 1493 |
|
if ($element['namespace']) { |
| 1494 |
|
$namespaces = array_merge($namespaces, $element['namespace']); |
| 1495 |
|
} |
| 1496 |
|
} |
| 1497 |
|
|
| 1498 |
// Prepare the item description |
// Prepare the item description |
| 1499 |
switch ($item_length) { |
switch ($item_length) { |
| 1500 |
case 'fulltext': |
case 'fulltext': |
| 1511 |
break; |
break; |
| 1512 |
} |
} |
| 1513 |
|
|
|
// 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']); |
|
|
} |
|
|
} |
|
| 1514 |
$items .= format_rss_item($item->title, $link, $item_text, $extra); |
$items .= format_rss_item($item->title, $link, $item_text, $extra); |
| 1515 |
} |
} |
| 1516 |
|
|
| 1528 |
$output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']); |
$output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']); |
| 1529 |
$output .= "</rss>\n"; |
$output .= "</rss>\n"; |
| 1530 |
|
|
| 1531 |
drupal_set_header('Content-Type: text/xml; charset=utf-8'); |
drupal_set_header('Content-Type: application/rss+xml; charset=utf-8'); |
| 1532 |
print $output; |
print $output; |
| 1533 |
} |
} |
| 1534 |
|
|
| 1590 |
} |
} |
| 1591 |
|
|
| 1592 |
if (isset($node->nid) && (node_last_changed($node->nid) > $node->changed)) { |
if (isset($node->nid) && (node_last_changed($node->nid) > $node->changed)) { |
| 1593 |
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.')); |
| 1594 |
} |
} |
| 1595 |
|
|
| 1596 |
if (user_access('administer nodes')) { |
if (user_access('administer nodes')) { |
| 1654 |
* Basic node information. |
* Basic node information. |
| 1655 |
* 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. |
| 1656 |
*/ |
*/ |
| 1657 |
foreach (array('nid', 'vid', 'uid', 'created', 'changed', 'type') as $key) { |
foreach (array('nid', 'vid', 'uid', 'created', 'type') as $key) { |
| 1658 |
$form[$key] = array('#type' => 'value', '#value' => $node->$key); |
$form[$key] = array('#type' => 'value', '#value' => $node->$key); |
| 1659 |
} |
} |
| 1660 |
|
|
| 1661 |
|
// Changed must be sent to the client, for later overwrite error checking. |
| 1662 |
|
$form['changed'] = array('#type' => 'hidden', '#default_value' => $node->changed); |
| 1663 |
|
|
| 1664 |
// Get the node-specific bits. |
// Get the node-specific bits. |
| 1665 |
$form = array_merge_recursive($form, node_invoke($node, 'form')); |
$form = array_merge_recursive($form, node_invoke($node, 'form')); |
| 1666 |
if (!isset($form['title']['#weight'])) { |
if (!isset($form['title']['#weight'])) { |
| 1719 |
return $form; |
return $form; |
| 1720 |
} |
} |
| 1721 |
|
|
| 1722 |
function node_form_add_preview($form, $edit) { |
function node_form_add_preview($form) { |
| 1723 |
|
global $form_values; |
| 1724 |
|
|
| 1725 |
$op = isset($_POST['op']) ? $_POST['op'] : ''; |
$op = isset($_POST['op']) ? $_POST['op'] : ''; |
| 1726 |
if ($op == t('Preview')) { |
if ($op == t('Preview')) { |
| 1727 |
drupal_validate_form($form['form_id']['#value'], $form); |
drupal_validate_form($form['form_id']['#value'], $form); |
| 1728 |
if (!form_get_errors()) { |
if (!form_get_errors()) { |
| 1729 |
$form['node_preview'] = array('#value' => node_preview((object)$edit), '#weight' => -100); |
// Because the node preview may display a form, we must render it |
| 1730 |
|
// outside the node submission form tags using the #prefix property |
| 1731 |
|
// (i.e. to prevent illegally nested forms). |
| 1732 |
|
// If the node form already has a #prefix, we must preserve it. |
| 1733 |
|
// In this case, we put the preview before the #prefix so we keep |
| 1734 |
|
// the #prefix as "close" to the rest of the form as possible, |
| 1735 |
|
// for example, to keep a <div> only around the form, not the |
| 1736 |
|
// preview. We pass the global $form_values here to preserve |
| 1737 |
|
// changes made during form validation. |
| 1738 |
|
$preview = node_preview((object)$form_values); |
| 1739 |
|
$form['#prefix'] = isset($form['#prefix']) ? $preview . $form['#prefix'] : $preview; |
| 1740 |
} |
} |
| 1741 |
} |
} |
| 1742 |
if (variable_get('node_preview', 0) && (form_get_errors() || $op != t('Preview'))) { |
if (variable_get('node_preview', 0) && (form_get_errors() || $op != t('Preview'))) { |
| 1746 |
} |
} |
| 1747 |
|
|
| 1748 |
function theme_node_form($form) { |
function theme_node_form($form) { |
| 1749 |
$output = '<div class="node-form">'; |
$output = "\n<div class=\"node-form\">\n"; |
|
if (isset($form['node_preview'])) { |
|
|
$output .= form_render($form['node_preview']); |
|
|
} |
|
| 1750 |
|
|
| 1751 |
$output .= ' <div class="standard">'; |
// Admin form fields and submit buttons must be rendered first, because |
| 1752 |
|
// they need to go to the bottom of the form, and so should not be part of |
| 1753 |
|
// the catch-all call to form_render(). |
| 1754 |
|
$admin = ''; |
| 1755 |
|
if (isset($form['author'])) { |
| 1756 |
|
$admin .= " <div class=\"authored\">\n"; |
| 1757 |
|
$admin .= form_render($form['author']); |
| 1758 |
|
$admin .= " </div>\n"; |
| 1759 |
|
} |
| 1760 |
|
if (isset($form['options'])) { |
| 1761 |
|
$admin .= " <div class=\"options\">\n"; |
| 1762 |
|
$admin .= form_render($form['options']); |
| 1763 |
|
$admin .= " </div>\n"; |
| 1764 |
|
} |
| 1765 |
|
$buttons = form_render($form['preview']); |
| 1766 |
|
$buttons .= form_render($form['submit']); |
| 1767 |
|
$buttons .= isset($form['delete']) ? form_render($form['delete']) : ''; |
| 1768 |
|
|
| 1769 |
|
// Everything else gets rendered here, and is displayed before the admin form |
| 1770 |
|
// field and the submit buttons. |
| 1771 |
|
$output .= " <div class=\"standard\">\n"; |
| 1772 |
$output .= form_render($form); |
$output .= form_render($form); |
| 1773 |
$output .= ' </div>'; |
$output .= " </div>\n"; |
| 1774 |
$output .= ' <div class="admin">'; |
|
| 1775 |
$output .= ' <div class="authored">'; |
if (!empty($admin)) { |
| 1776 |
$output .= form_render($form['author']); |
$output .= " <div class=\"admin\">\n"; |
| 1777 |
$output .= ' </div>'; |
$output .= $admin; |
| 1778 |
$output .= ' <div class="options">'; |
$output .= " </div>\n"; |
| 1779 |
$output .= form_render($form['options']); |
} |
| 1780 |
$output .= ' </div>'; |
$output .= $buttons; |
| 1781 |
$output .= ' </div>'; |
$output .= "</div>\n"; |
| 1782 |
$output .= '</div>'; |
|
| 1783 |
return $output; |
return $output; |
| 1784 |
} |
} |
| 1785 |
|
|
| 1800 |
else { |
else { |
| 1801 |
// 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. |
| 1802 |
foreach (node_get_types() as $type => $name) { |
foreach (node_get_types() as $type => $name) { |
| 1803 |
if (module_invoke(node_get_base($type), 'access', 'create', $type)) { |
if (node_access('create', $type)) { |
| 1804 |
$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>'; |
| 1805 |
$out .= '<dd>'. implode("\n", module_invoke_all('help', 'node/add#'. $type)) .'</dd>'; |
$out .= '<dd>'. implode("\n", module_invoke_all('help', 'node/add#'. $type)) .'</dd>'; |
| 1806 |
$item[$name] = $out; |
$item[$name] = $out; |
| 1808 |
} |
} |
| 1809 |
|
|
| 1810 |
if (isset($item)) { |
if (isset($item)) { |
| 1811 |
uasort($item, 'strnatcasecmp'); |
uksort($item, 'strnatcasecmp'); |
| 1812 |
$output = t('Choose the appropriate item from the list:') .'<dl>'. implode('', $item) .'</dl>'; |
$output = t('Choose the appropriate item from the list:') .'<dl>'. implode('', $item) .'</dl>'; |
| 1813 |
} |
} |
| 1814 |
else { |
else { |
| 1899 |
if ($node->nid) { |
if ($node->nid) { |
| 1900 |
// Check whether the current user has the proper access rights to |
// Check whether the current user has the proper access rights to |
| 1901 |
// perform this operation: |
// perform this operation: |
| 1902 |
if (node_access('update', $node)) { |
$original_node = node_load($node->nid); //check access rights using the unmodified node |
| 1903 |
|
if (node_access('update', $original_node)) { |
| 1904 |
node_save($node); |
node_save($node); |
| 1905 |
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)); |
| 1906 |
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)))); |
| 2012 |
} |
} |
| 2013 |
break; |
break; |
| 2014 |
case 'revert': |
case 'revert': |
| 2015 |
node_revision_revert(arg(1), arg(3)); |
return node_revision_revert(arg(1), arg(3)); |
| 2016 |
break; |
break; |
| 2017 |
case 'delete': |
case 'delete': |
| 2018 |
node_revision_delete(arg(1), arg(3)); |
return node_revision_delete(arg(1), arg(3)); |
| 2019 |
break; |
break; |
| 2020 |
} |
} |
| 2021 |
} |
} |
| 2041 |
$output .= theme('pager', NULL, variable_get('default_nodes_main', 10)); |
$output .= theme('pager', NULL, variable_get('default_nodes_main', 10)); |
| 2042 |
} |
} |
| 2043 |
else { |
else { |
| 2044 |
$output = t(" |
$output = t(' |
| 2045 |
<p>Welcome to your new <a href=\"%drupal\">Drupal</a>-powered website. This message will guide you through your first steps with Drupal, and will disappear once you have posted your first piece of content.</p> |
<h1 class="title">Welcome to your new Drupal website!</h1> |
| 2046 |
<p>The first thing you will need to do is <a href=\"%register\">create the first account</a>. This account will have full administration rights and will allow you to configure your website. Once logged in, you can visit the <a href=\"%admin\">administration section</a> and <a href=\"%config\">set up your site's configuration</a>.</p> |
<p>Please follow these steps to set up and start using your website:</p> |
| 2047 |
<p>Drupal comes with various modules, each of which contains a specific piece of functionality. You should visit the <a href=\"%modules\">module list</a> and enable those modules which suit your website's needs.</p> |
<ol> |
| 2048 |
<p><a href=\"%themes\">Themes</a> handle the presentation of your website. You can use one of the existing themes, modify them or create your own from scratch.</p> |
<li> |
| 2049 |
<p>We suggest you look around the administration section and explore the various options Drupal offers you. For more information, you can refer to the <a href=\"%handbook\">Drupal handbooks online</a>.</p>", array('%drupal' => 'http://drupal.org/', '%register' => url('user/register'), '%admin' => url('admin'), '%config' => url('admin/settings'), '%modules' => url('admin/modules'), '%themes' => url('admin/themes'), '%handbook' => 'http://drupal.org/handbooks')); |
<strong>Create your administrator account</strong> |
| 2050 |
|
To begin, <a href="%register">create the first account</a>. This account will have full administration rights and will allow you to configure your website. |
| 2051 |
|
</li> |
| 2052 |
|
<li> |
| 2053 |
|
<strong>Configure your website</strong> |
| 2054 |
|
Once logged in, visit the <a href="%admin">administration section</a>, where you can <a href="%config">customize and configure</a> all aspects of your website. |
| 2055 |
|
</li> |
| 2056 |
|
<li> |
| 2057 |
|
<strong>Enable additional functionality</strong> |
| 2058 |
|
Next, visit the <a href="%modules">module list</a> and enable features which suit your specific needs. You can find additional modules in the <a href="%download_modules">Drupal modules download section</a>. |
| 2059 |
|
</li> |
| 2060 |
|
<li> |
| 2061 |
|
<strong>Customize your website design</strong> |
| 2062 |
|
To change the "look and feel" of your website, visit the <a href="%themes">themes section</a>. You may choose from one of the included themes or download additional themes from the <a href="%download_themes">Drupal themes download section</a>. |
| 2063 |
|
</li> |
| 2064 |
|
<li> |
| 2065 |
|
<strong>Start posting content</strong> |
| 2066 |
|
Finally, you can <a href="%content">create content</a> for your website. This message will disappear once you have published your first post. |
| 2067 |
|
</li> |
| 2068 |
|
</ol> |
| 2069 |
|
<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>', |
| 2070 |
|
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') |
| 2071 |
|
); |
| 2072 |
|
$output = '<div id="first-time">'. $output .'</div>'; |
| 2073 |
} |
} |
| 2074 |
|
|
| 2075 |
return $output; |
return $output; |
| 2162 |
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}')))); |
| 2163 |
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}')))); |
| 2164 |
|
|
| 2165 |
$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); |
$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); |
| 2166 |
|
|
| 2167 |
while ($node = db_fetch_object($result)) { |
while ($node = db_fetch_object($result)) { |
| 2168 |
$last_change = $node->last_change; |
$last_change = $node->last_change; |