View source
<?php
define('NODE_NEW_LIMIT', time() - 30 * 24 * 60 * 60);
function node_help($section) {
switch ($section) {
case 'admin/help#node':
$output = '<p>' . t('All content in a website is stored and treated as <b>nodes</b>. Therefore nodes are any postings such as blogs, stories, polls and forums. The node module manages these content types and is one of the strengths of Drupal over other content management systems.') . '</p>';
$output .= '<p>' . t('Treating all content as nodes allows the flexibility of creating new types of content. It also allows you to painlessly apply new features or changes to all content. Comments are not stored as nodes but are always associated with a node.') . '</p>';
$output .= t('<p>Node module features</p>
<ul>
<li>The list tab provides an interface to search and sort all content on your site.</li>
<li>The configure settings tab has basic settings for content on your site.</li>
<li>The configure content types tab lists all content types for your site and lets you configure their default workflow.</li>
<li>The search tab lets you search all content on your site</li>
</ul>
');
$output .= '<p>' . t('For more information please read the configuration and customization handbook <a href="@node">Node page</a>.', array(
'@node' => 'http://drupal.org/handbook/modules/node/',
)) . '</p>';
return $output;
case 'admin/content/search':
return '<p>' . t('Enter a simple pattern to search for a post. Words are matched exactly. Phrases can be surrounded by quotes to do an exact search.') . '</p>';
case 'admin/content/types':
return '<p>' . t('Below is a list of all the content types on your site. All posts that exist on your site are instances of one of these content types.') . '</p>';
case 'admin/content/types/add':
return '<p>' . t('To create a new content type, enter the human-readable name, the machine-readable name, and all other relevant fields that are on this page. Once created, users of your site will be able to create posts that are instances of this content type.') . '</p>';
}
if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'revisions' && arg(3) == NULL) {
return '<p>' . t('The revisions let you track differences between multiple versions of a post.') . '</p>';
}
if (arg(0) == 'node' && arg(1) == 'add' && ($type = arg(2))) {
$type = node_get_types('type', str_replace('-', '_', arg(2)));
return '<p>' . filter_xss_admin($type->help) . '</p>';
}
}
function node_cron() {
db_query('DELETE FROM {history} WHERE timestamp < %d', NODE_NEW_LIMIT);
}
function node_title_list($result, $title = NULL) {
while ($node = db_fetch_object($result)) {
$items[] = l($node->title, 'node/' . $node->nid, $node->comment_count ? array(
'title' => format_plural($node->comment_count, '1 comment', '@count comments'),
) : '');
}
return theme('node_list', $items, $title);
}
function theme_node_list($items, $title = NULL) {
return theme('item_list', $items, $title);
}
function node_tag_new($nid) {
global $user;
if ($user->uid) {
if (node_last_viewed($nid)) {
db_query('UPDATE {history} SET timestamp = %d WHERE uid = %d AND nid = %d', time(), $user->uid, $nid);
}
else {
@db_query('INSERT INTO {history} (uid, nid, timestamp) VALUES (%d, %d, %d)', $user->uid, $nid, time());
}
}
}
function node_last_viewed($nid) {
global $user;
static $history;
if (!isset($history[$nid])) {
$history[$nid] = db_fetch_object(db_query("SELECT timestamp FROM {history} WHERE uid = %d AND nid = %d", $user->uid, $nid));
}
return isset($history[$nid]->timestamp) ? $history[$nid]->timestamp : 0;
}
function node_mark($nid, $timestamp) {
global $user;
static $cache;
if (!$user->uid) {
return MARK_READ;
}
if (!isset($cache[$nid])) {
$cache[$nid] = node_last_viewed($nid);
}
if ($cache[$nid] == 0 && $timestamp > NODE_NEW_LIMIT) {
return MARK_NEW;
}
elseif ($timestamp > $cache[$nid] && $timestamp > NODE_NEW_LIMIT) {
return MARK_UPDATED;
}
return MARK_READ;
}
function node_teaser($body, $format = NULL) {
$size = variable_get('teaser_length', 600);
$delimiter = strpos($body, '<!--break-->');
if ($size == 0 && $delimiter === FALSE) {
return $body;
}
if ($delimiter !== FALSE) {
return substr($body, 0, $delimiter);
}
if (isset($format)) {
$filters = filter_list_format($format);
if (isset($filters['filter/1']) && strpos($body, '<?') !== FALSE) {
return $body;
}
}
if (strlen($body) <= $size) {
return $body;
}
$teaser = truncate_utf8($body, $size);
$max_rpos = strlen($teaser);
$min_rpos = $max_rpos;
$reversed = strrev($teaser);
$break_points = array();
$break_points[] = array(
'</p>' => 0,
);
$line_breaks = array(
'<br />' => 6,
'<br>' => 4,
);
if (isset($filters['filter/2'])) {
$line_breaks["\n"] = 1;
}
$break_points[] = $line_breaks;
$break_points[] = array(
'. ' => 1,
'! ' => 1,
'? ' => 1,
'。' => 0,
'؟ ' => 1,
);
foreach ($break_points as $points) {
foreach ($points as $point => $offset) {
$rpos = strpos($reversed, strrev($point));
if ($rpos !== FALSE) {
$min_rpos = min($rpos + $offset, $min_rpos);
}
}
if ($min_rpos !== $max_rpos) {
return $min_rpos === 0 ? $teaser : substr($teaser, 0, 0 - $min_rpos);
}
}
return $teaser;
}
function node_get_types($op = 'types', $node = NULL, $reset = FALSE) {
static $_node_types, $_node_names;
if ($reset || !isset($_node_types)) {
list($_node_types, $_node_names) = _node_types_build();
}
if ($node) {
if (is_array($node)) {
$type = $node['type'];
}
elseif (is_object($node)) {
$type = $node->type;
}
elseif (is_string($node)) {
$type = $node;
}
if (!isset($_node_types[$type])) {
return FALSE;
}
}
switch ($op) {
case 'types':
return $_node_types;
case 'type':
return $_node_types[$type];
case 'module':
return $_node_types[$type]->module;
case 'names':
return $_node_names;
case 'name':
return $_node_names[$type];
}
}
function node_types_rebuild() {
_node_types_build();
$node_types = node_get_types('types', NULL, TRUE);
foreach ($node_types as $type => $info) {
if (!empty($info->is_new)) {
node_type_save($info);
}
if (!empty($info->disabled)) {
node_type_delete($info->type);
}
}
_node_types_build();
}
function node_type_save($info) {
$is_existing = FALSE;
$existing_type = !empty($info->old_type) ? $info->old_type : $info->type;
$is_existing = db_num_rows(db_query("SELECT * FROM {node_type} WHERE type = '%s'", $existing_type));
if ($is_existing) {
db_query("UPDATE {node_type} SET type = '%s', name = '%s', module = '%s', has_title = %d, title_label = '%s', has_body = %d, body_label = '%s', description = '%s', help = '%s', min_word_count = %d, custom = %d, modified = %d, locked = %d WHERE type = '%s'", $info->type, $info->name, $info->module, $info->has_title, $info->title_label, $info->has_body, $info->body_label, $info->description, $info->help, $info->min_word_count, $info->custom, $info->modified, $info->locked, $existing_type);
module_invoke_all('node_type', 'update', $info);
return SAVED_UPDATED;
}
else {
db_query("INSERT INTO {node_type} (type, name, module, has_title, title_label, has_body, body_label, description, help, min_word_count, custom, modified, locked, orig_type) VALUES ('%s', '%s', '%s', %d, '%s', %d, '%s', '%s', '%s', %d, %d, %d, %d, '%s')", $info->type, $info->name, $info->module, $info->has_title, $info->title_label, $info->has_body, $info->body_label, $info->description, $info->help, $info->min_word_count, $info->custom, $info->modified, $info->locked, $info->orig_type);
module_invoke_all('node_type', 'insert', $info);
return SAVED_NEW;
}
}
function node_type_delete($type) {
db_query("DELETE FROM {node_type} WHERE type = '%s'", $type);
$info = node_get_types('type', $type);
module_invoke_all('node_type', 'delete', $info);
}
function node_type_update_nodes($old_type, $type) {
db_query("UPDATE {node} SET type = '%s' WHERE type = '%s'", $type, $old_type);
return db_affected_rows();
}
function _node_types_build() {
$_node_types = array();
$_node_names = array();
$info_array = module_invoke_all('node_info');
foreach ($info_array as $type => $info) {
$info['type'] = $type;
$_node_types[$type] = (object) _node_type_set_defaults($info);
$_node_names[$type] = $info['name'];
}
$type_result = db_query(db_rewrite_sql('SELECT nt.type, nt.* FROM {node_type} nt ORDER BY nt.type ASC', 'nt', 'type'));
while ($type_object = db_fetch_object($type_result)) {
if ($type_object->module != 'node' && empty($info_array[$type_object->type])) {
$type_object->disabled = TRUE;
}
if (!isset($_node_types[$type_object->type]) || $type_object->modified) {
$_node_types[$type_object->type] = $type_object;
$_node_names[$type_object->type] = $type_object->name;
if ($type_object->type != $type_object->orig_type) {
unset($_node_types[$type_object->orig_type]);
unset($_node_names[$type_object->orig_type]);
}
}
}
asort($_node_names);
return array(
$_node_types,
$_node_names,
);
}
function _node_type_set_defaults($info) {
if (!isset($info['has_title'])) {
$info['has_title'] = TRUE;
}
if ($info['has_title'] && !isset($info['title_label'])) {
$info['title_label'] = t('Title');
}
if (!isset($info['has_body'])) {
$info['has_body'] = TRUE;
}
if ($info['has_body'] && !isset($info['body_label'])) {
$info['body_label'] = t('Body');
}
if (!isset($info['help'])) {
$info['help'] = '';
}
if (!isset($info['min_word_count'])) {
$info['min_word_count'] = 0;
}
if (!isset($info['custom'])) {
$info['custom'] = FALSE;
}
if (!isset($info['modified'])) {
$info['modified'] = FALSE;
}
if (!isset($info['locked'])) {
$info['locked'] = TRUE;
}
$info['orig_type'] = $info['type'];
$info['is_new'] = TRUE;
return $info;
}
function node_hook(&$node, $hook) {
$module = node_get_types('module', $node);
if ($module == 'node') {
$module = 'node_content';
}
return module_hook($module, $hook);
}
function node_invoke(&$node, $hook, $a2 = NULL, $a3 = NULL, $a4 = NULL) {
if (node_hook($node, $hook)) {
$module = node_get_types('module', $node);
if ($module == 'node') {
$module = 'node_content';
}
$function = $module . '_' . $hook;
return $function($node, $a2, $a3, $a4);
}
}
function node_invoke_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
$return = array();
foreach (module_implements('nodeapi') as $name) {
$function = $name . '_nodeapi';
$result = $function($node, $op, $a3, $a4);
if (isset($result) && is_array($result)) {
$return = array_merge($return, $result);
}
else {
if (isset($result)) {
$return[] = $result;
}
}
}
return $return;
}
function node_load($param = array(), $revision = NULL, $reset = NULL) {
static $nodes = array();
if ($reset) {
$nodes = array();
}
$cachable = $revision == NULL;
$arguments = array();
if (is_numeric($param)) {
if ($cachable && isset($nodes[$param])) {
return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param];
}
$cond = 'n.nid = %d';
$arguments[] = $param;
}
else {
foreach ($param as $key => $value) {
$cond[] = 'n.' . db_escape_table($key) . " = '%s'";
$arguments[] = $value;
}
$cond = implode(' AND ', $cond);
}
if ($revision) {
array_unshift($arguments, $revision);
$node = db_fetch_object(db_query('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));
}
else {
$node = db_fetch_object(db_query('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));
}
if ($node->nid) {
if ($extra = node_invoke($node, 'load')) {
foreach ($extra as $key => $value) {
$node->{$key} = $value;
}
}
if ($extra = node_invoke_nodeapi($node, 'load')) {
foreach ($extra as $key => $value) {
$node->{$key} = $value;
}
}
if ($cachable) {
$nodes[$node->nid] = is_object($node) ? drupal_clone($node) : $node;
}
}
return $node;
}
function node_save(&$node) {
global $user;
$node->is_new = FALSE;
if (empty($node->nid)) {
$node->is_new = TRUE;
$node->nid = db_next_id('{node}_nid');
$node->vid = db_next_id('{node_revisions}_vid');
}
else {
$node_current = node_load($node->nid);
foreach ($node as $field => $data) {
$node_current->{$field} = $data;
}
$node = $node_current;
if ($node->revision) {
$node->old_vid = $node->vid;
$node->vid = db_next_id('{node_revisions}_vid');
}
}
if (empty($node->created)) {
$node->created = time();
}
$node->changed = time();
$revisions_table_values = array(
'nid' => $node->nid,
'vid' => $node->vid,
'title' => $node->title,
'body' => $node->body,
'teaser' => $node->teaser,
'timestamp' => $node->changed,
'uid' => $user->uid,
'format' => $node->format,
);
$revisions_table_types = array(
'nid' => '%d',
'vid' => '%d',
'title' => "'%s'",
'body' => "'%s'",
'teaser' => "'%s'",
'timestamp' => '%d',
'uid' => '%d',
'format' => '%d',
);
if (!empty($node->log) || $node->is_new || $node->revision) {
$revisions_table_values['log'] = $node->log;
$revisions_table_types['log'] = "'%s'";
}
$node_table_values = array(
'nid' => $node->nid,
'vid' => $node->vid,
'title' => $node->title,
'type' => $node->type,
'uid' => $node->uid,
'status' => $node->status,
'created' => $node->created,
'changed' => $node->changed,
'comment' => $node->comment,
'promote' => $node->promote,
'sticky' => $node->sticky,
);
$node_table_types = array(
'nid' => '%d',
'vid' => '%d',
'title' => "'%s'",
'type' => "'%s'",
'uid' => '%d',
'status' => '%d',
'created' => '%d',
'changed' => '%d',
'comment' => '%d',
'promote' => '%d',
'sticky' => '%d',
);
if ($node->is_new) {
$node_query = 'INSERT INTO {node} (' . implode(', ', array_keys($node_table_types)) . ') VALUES (' . implode(', ', $node_table_types) . ')';
$revisions_query = 'INSERT INTO {node_revisions} (' . implode(', ', array_keys($revisions_table_types)) . ') VALUES (' . implode(', ', $revisions_table_types) . ')';
}
else {
$arr = array();
foreach ($node_table_types as $key => $value) {
$arr[] = $key . ' = ' . $value;
}
$node_table_values[] = $node->nid;
$node_query = 'UPDATE {node} SET ' . implode(', ', $arr) . ' WHERE nid = %d';
if ($node->revision) {
$revisions_query = 'INSERT INTO {node_revisions} (' . implode(', ', array_keys($revisions_table_types)) . ') VALUES (' . implode(', ', $revisions_table_types) . ')';
}
else {
$arr = array();
foreach ($revisions_table_types as $key => $value) {
$arr[] = $key . ' = ' . $value;
}
$revisions_table_values[] = $node->vid;
$revisions_query = 'UPDATE {node_revisions} SET ' . implode(', ', $arr) . ' WHERE vid = %d';
}
}
db_query($node_query, $node_table_values);
db_query($revisions_query, $revisions_table_values);
if ($node->is_new) {
node_invoke($node, 'insert');
node_invoke_nodeapi($node, 'insert');
}
else {
node_invoke($node, 'update');
node_invoke_nodeapi($node, 'update');
}
node_access_acquire_grants($node);
cache_clear_all();
}
function node_view($node, $teaser = FALSE, $page = FALSE, $links = TRUE) {
$node = (object) $node;
$node = node_build_content($node, $teaser, $page);
if ($links) {
$node->links = module_invoke_all('link', 'node', $node, $teaser);
foreach (module_implements('link_alter') as $module) {
$function = $module . '_link_alter';
$function($node, $node->links);
}
}
$content = drupal_render($node->content);
if ($teaser) {
$node->teaser = $content;
unset($node->body);
}
else {
$node->body = $content;
unset($node->teaser);
}
node_invoke_nodeapi($node, 'alter', $teaser, $page);
return theme('node', $node, $teaser, $page);
}
function node_prepare($node, $teaser = FALSE) {
$node->readmore = strlen($node->teaser) < strlen($node->body);
if ($teaser == FALSE) {
$node->body = check_markup($node->body, $node->format, FALSE);
}
else {
$node->teaser = check_markup($node->teaser, $node->format, FALSE);
}
$node->content['body'] = array(
'#value' => $teaser ? $node->teaser : $node->body,
'#weight' => 0,
);
return $node;
}
function node_build_content($node, $teaser = FALSE, $page = FALSE) {
$node->body = str_replace('<!--break-->', '', $node->body);
if (node_hook($node, 'view')) {
$node = node_invoke($node, 'view', $teaser, $page);
}
else {
$node = node_prepare($node, $teaser);
}
node_invoke_nodeapi($node, 'view', $teaser, $page);
return $node;
}
function node_show($node, $cid) {
$output = node_view($node, FALSE, TRUE);
if (function_exists('comment_render') && $node->comment) {
$output .= comment_render($node, $cid);
}
node_tag_new($node->nid);
return $output;
}
function node_perm() {
$perms = array(
'administer content types',
'administer nodes',
'access content',
'view revisions',
'revert revisions',
);
foreach (node_get_types() as $type) {
if ($type->module == 'node') {
$name = check_plain($type->type);
$perms[] = 'create ' . $name . ' content';
$perms[] = 'edit own ' . $name . ' content';
$perms[] = 'edit ' . $name . ' content';
}
}
return $perms;
}
function node_search($op = 'search', $keys = NULL) {
switch ($op) {
case 'name':
return t('Content');
case 'reset':
variable_del('node_cron_last');
variable_del('node_cron_last_nid');
return;
case 'status':
$last = variable_get('node_cron_last', 0);
$last_nid = variable_get('node_cron_last_nid', 0);
$total = db_result(db_query('SELECT COUNT(*) FROM {node} WHERE status = 1'));
$remaining = db_result(db_query('SELECT COUNT(*) FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND ((GREATEST(n.created, n.changed, c.last_comment_timestamp) = %d AND n.nid > %d ) OR (n.created > %d OR n.changed > %d OR c.last_comment_timestamp > %d))', $last, $last_nid, $last, $last, $last));
return array(
'remaining' => $remaining,
'total' => $total,
);
case 'admin':
$form = array();
$form['content_ranking'] = array(
'#type' => 'fieldset',
'#title' => t('Content ranking'),
);
$form['content_ranking']['#theme'] = 'node_search_admin';
$form['content_ranking']['info'] = array(
'#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>',
);
$ranking = array(
'node_rank_relevance' => t('Keyword relevance'),
'node_rank_recent' => t('Recently posted'),
);
if (module_exists('comment')) {
$ranking['node_rank_comments'] = t('Number of comments');
}
if (module_exists('statistics') && variable_get('statistics_count_content_views', 0)) {
$ranking['node_rank_views'] = t('Number of views');
}
$options = drupal_map_assoc(range(0, 10));
foreach ($ranking as $var => $title) {
$form['content_ranking']['factors'][$var] = array(
'#title' => $title,
'#type' => 'select',
'#options' => $options,
'#default_value' => variable_get($var, 5),
);
}
return $form;
case 'search':
list($join1, $where1) = _db_rewrite_sql();
$arguments1 = array();
$conditions1 = 'n.status = 1';
if ($type = search_query_extract($keys, 'type')) {
$types = array();
foreach (explode(',', $type) as $t) {
$types[] = "n.type = '%s'";
$arguments1[] = $t;
}
$conditions1 .= ' AND (' . implode(' OR ', $types) . ')';
$keys = search_query_insert($keys, 'type');
}
if ($category = search_query_extract($keys, 'category')) {
$categories = array();
foreach (explode(',', $category) as $c) {
$categories[] = "tn.tid = %d";
$arguments1[] = $c;
}
$conditions1 .= ' AND (' . implode(' OR ', $categories) . ')';
$join1 .= ' INNER JOIN {term_node} tn ON n.nid = tn.nid';
$keys = search_query_insert($keys, 'category');
}
$ranking = array();
$arguments2 = array();
$join2 = '';
$stats_join = FALSE;
$total = 0;
if ($weight = (int) variable_get('node_rank_relevance', 5)) {
$ranking[] = '%d * i.relevance';
$arguments2[] = $weight;
$total += $weight;
}
if ($weight = (int) variable_get('node_rank_recent', 5)) {
$ranking[] = '%d * POW(2, (GREATEST(n.created, n.changed, c.last_comment_timestamp) - %d) * 6.43e-8)';
$arguments2[] = $weight;
$arguments2[] = (int) variable_get('node_cron_last', 0);
$join2 .= ' INNER JOIN {node} n ON n.nid = i.sid LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
$stats_join = TRUE;
$total += $weight;
}
if (module_exists('comment') && ($weight = (int) variable_get('node_rank_comments', 5))) {
$scale = variable_get('node_cron_comments_scale', 0.0);
$ranking[] = '%d * (2.0 - 2.0 / (1.0 + c.comment_count * %f))';
$arguments2[] = $weight;
$arguments2[] = $scale;
if (!$stats_join) {
$join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
}
$total += $weight;
}
if (module_exists('statistics') && variable_get('statistics_count_content_views', 0) && ($weight = (int) variable_get('node_rank_views', 5))) {
$scale = variable_get('node_cron_views_scale', 0.0);
$ranking[] = '%d * (2.0 - 2.0 / (1.0 + nc.totalcount * %f))';
$arguments2[] = $weight;
$arguments2[] = $scale;
$join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
$total += $weight;
}
if ($total == 0) {
$select2 = 'i.relevance AS score';
$total = 1;
}
else {
$select2 = implode(' + ', $ranking) . ' AS score';
}
$find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid ' . $join1 . ' INNER JOIN {users} u ON n.uid = u.uid', $conditions1 . (empty($where1) ? '' : ' AND ' . $where1), $arguments1, $select2, $join2, $arguments2);
$results = array();
foreach ($find as $item) {
$node = node_load($item->sid);
$node = node_build_content($node, FALSE, FALSE);
$node->body = drupal_render($node->content);
$node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
$node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index');
$extra = node_invoke_nodeapi($node, 'search result');
$results[] = array(
'link' => url('node/' . $item->sid, NULL, NULL, TRUE),
'type' => node_get_types('name', $node),
'title' => $node->title,
'user' => theme('username', $node),
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
'score' => $item->score / $total,
'snippet' => search_excerpt($keys, $node->body),
);
}
return $results;
}
}
function node_user($op, &$edit, &$user) {
if ($op == 'delete') {
db_query('UPDATE {node} SET uid = 0 WHERE uid = %d', $user->uid);
db_query('UPDATE {node_revisions} SET uid = 0 WHERE uid = %d', $user->uid);
}
}
function theme_node_search_admin($form) {
$output = drupal_render($form['info']);
$header = array(
t('Factor'),
t('Weight'),
);
foreach (element_children($form['factors']) as $key) {
$row = array();
$row[] = $form['factors'][$key]['#title'];
unset($form['factors'][$key]['#title']);
$row[] = drupal_render($form['factors'][$key]);
$rows[] = $row;
}
$output .= theme('table', $header, $rows);
$output .= drupal_render($form);
return $output;
}
function node_configure() {
if (db_result(db_query('SELECT COUNT(*) FROM {node_access}')) != 1 || count(module_implements('node_grants')) > 0) {
$status = '<p>' . t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Possible causes for permission problems are disabling modules or configuration changes to permissions. Rebuilding will remove all privileges to posts, and replace them with permissions based on the current modules and settings.') . '</p>';
$status .= '<p>' . t('Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed posts will automatically use the new permissions.') . '</p>';
$form['access'] = array(
'#type' => 'fieldset',
'#title' => t('Node access status'),
);
$form['access']['status'] = array(
'#value' => $status,
);
$form['access']['rebuild'] = array(
'#type' => 'submit',
'#value' => t('Rebuild permissions'),
);
}
$form['default_nodes_main'] = array(
'#type' => 'select',
'#title' => t('Number of posts on main page'),
'#default_value' => variable_get('default_nodes_main', 10),
'#options' => drupal_map_assoc(array(
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
15,
20,
25,
30,
)),
'#description' => t('The default maximum number of posts to display per page on overview pages such as the main page.'),
);
$form['teaser_length'] = array(
'#type' => 'select',
'#title' => t('Length of trimmed posts'),
'#default_value' => variable_get('teaser_length', 600),
'#options' => array(
0 => t('Unlimited'),
200 => t('200 characters'),
400 => t('400 characters'),
600 => t('600 characters'),
800 => t('800 characters'),
1000 => t('1000 characters'),
1200 => t('1200 characters'),
1400 => t('1400 characters'),
1600 => t('1600 characters'),
1800 => t('1800 characters'),
2000 => t('2000 characters'),
),
'#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."),
);
$form['node_preview'] = array(
'#type' => 'radios',
'#title' => t('Preview post'),
'#default_value' => variable_get('node_preview', 0),
'#options' => array(
t('Optional'),
t('Required'),
),
'#description' => t('Must users preview posts before submitting?'),
);
return system_settings_form($form);
}
function node_configure_validate($form_id, $form_values) {
if ($form_values['op'] == t('Rebuild permissions')) {
drupal_goto('admin/content/node-settings/rebuild');
}
}
function node_configure_rebuild_confirm() {
return confirm_form(array(), t('Are you sure you want to rebuild node permissions on the site?'), 'admin/content/node-settings', t('This will wipe all current node permissions and rebuild them based on current settings. Rebuilding the permissions may take a while so please be patient. This action cannot be undone.'), t('Rebuild permissions'), t('Cancel'));
}
function node_configure_rebuild_confirm_submit($form_id, &$form) {
node_access_rebuild();
drupal_set_message(t('The node access table has been rebuilt.'));
return 'admin/content/node-settings';
}
function node_comment_mode($nid) {
static $comment_mode;
if (!isset($comment_mode[$nid])) {
$comment_mode[$nid] = db_result(db_query('SELECT comment FROM {node} WHERE nid = %d', $nid));
}
return $comment_mode[$nid];
}
function node_link($type, $node = NULL, $teaser = FALSE) {
$links = array();
if ($type == 'node') {
if ($teaser == 1 && $node->teaser && $node->readmore) {
$links['node_read_more'] = array(
'title' => t('Read more'),
'href' => "node/{$node->nid}",
'attributes' => array(
'title' => t('Read the rest of this posting.'),
),
);
}
}
return $links;
}
function node_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/content',
'title' => t('Content management'),
'description' => t("Manage your site's content."),
'position' => 'left',
'weight' => -10,
'callback' => 'system_admin_menu_block_page',
'access' => user_access('administer site configuration'),
);
$items[] = array(
'path' => 'admin/content/node',
'title' => t('Content'),
'description' => t("View, edit, and delete your site's content."),
'callback' => 'node_admin_content',
'access' => user_access('administer nodes'),
);
$items[] = array(
'path' => 'admin/content/node/overview',
'title' => t('List'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
if (module_exists('search')) {
$items[] = array(
'path' => 'admin/content/search',
'title' => t('Search content'),
'description' => t('Search content by keyword.'),
'callback' => 'node_admin_search',
'access' => user_access('administer nodes'),
'type' => MENU_NORMAL_ITEM,
);
}
$items[] = array(
'path' => 'admin/content/node-settings',
'title' => t('Post settings'),
'description' => t('Control posting behavior, such as teaser length, requiring previews before posting, and the number of posts on the front page.'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'node_configure',
),
'access' => user_access('administer nodes'),
);
$items[] = array(
'path' => 'admin/content/node-settings/rebuild',
'title' => t('rebuild permissions'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'node_configure_rebuild_confirm',
),
'access' => user_access('administer nodes'),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/content/types',
'title' => t('Content types'),
'description' => t('Manage posts by content type, including default status, front page promotion, etc.'),
'callback' => 'node_overview_types',
'access' => user_access('administer content types'),
);
$items[] = array(
'path' => 'admin/content/types/list',
'title' => t('List'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items[] = array(
'path' => 'admin/content/types/add',
'title' => t('Add content type'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'node_type_form',
),
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'node',
'title' => t('Content'),
'callback' => 'node_page_default',
'access' => user_access('access content'),
'type' => MENU_MODIFIABLE_BY_ADMIN,
);
$items[] = array(
'path' => 'node/add',
'title' => t('Create content'),
'callback' => 'node_add',
'access' => user_access('access content'),
'type' => MENU_ITEM_GROUPING,
'weight' => 1,
);
$items[] = array(
'path' => 'rss.xml',
'title' => t('RSS feed'),
'callback' => 'node_feed',
'access' => user_access('access content'),
'type' => MENU_CALLBACK,
);
foreach (node_get_types() as $type) {
if (function_exists($type->module . '_form')) {
$type_url_str = str_replace('_', '-', $type->type);
$items[] = array(
'path' => 'node/add/' . $type_url_str,
'title' => drupal_ucfirst($type->name),
'access' => node_access('create', $type->type),
);
}
}
for ($error_code = 403; $error_code <= 404; $error_code++) {
if (preg_match('|^node/(?P<nid>\\d+)(?:/view)?$|', drupal_get_normal_path(variable_get('site_' . $error_code, '')), $matches) && ($node = node_load($matches['nid']))) {
$items[] = array(
'path' => 'node/' . $node->nid,
'title' => t('View'),
'callback' => 'node_page_view',
'callback arguments' => array(
$node,
),
'access' => TRUE,
'type' => MENU_CALLBACK,
);
}
}
}
else {
drupal_add_css(drupal_get_path('module', 'node') . '/node.css');
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
if ($node->nid) {
$items[] = array(
'path' => 'node/' . arg(1),
'title' => t('View'),
'callback' => 'node_page_view',
'callback arguments' => array(
$node,
),
'access' => node_access('view', $node),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'node/' . arg(1) . '/view',
'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items[] = array(
'path' => 'node/' . arg(1) . '/edit',
'title' => t('Edit'),
'callback' => 'node_page_edit',
'callback arguments' => array(
$node,
),
'access' => node_access('update', $node),
'weight' => 1,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'node/' . arg(1) . '/delete',
'title' => t('Delete'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'node_delete_confirm',
$node,
),
'access' => node_access('delete', $node),
'weight' => 1,
'type' => MENU_CALLBACK,
);
$revisions_access = (user_access('view revisions') || user_access('administer nodes')) && node_access('view', $node) && db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', arg(1))) > 1;
$items[] = array(
'path' => 'node/' . arg(1) . '/revisions',
'title' => t('Revisions'),
'callback' => 'node_revisions',
'access' => $revisions_access,
'weight' => 2,
'type' => MENU_LOCAL_TASK,
);
if (!is_null(arg(3))) {
$items[] = array(
'path' => 'node/' . arg(1) . '/revisions/' . arg(3) . '/delete',
'callback' => 'node_revision_delete',
'callback arguments' => array(
arg(1),
arg(3),
),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'node/' . arg(1) . '/revisions/' . arg(3) . '/revert',
'callback' => 'node_revision_revert',
'callback arguments' => array(
arg(1),
arg(3),
),
'type' => MENU_CALLBACK,
);
}
}
}
if (arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'types') {
include_once './' . drupal_get_path('module', 'node') . '/content_types.inc';
if (arg(3) != NULL) {
$type_name = arg(3);
$type_name = !empty($type_name) ? str_replace('-', '_', $type_name) : NULL;
$type = node_get_types('type', $type_name);
if (!empty($type)) {
$type_url_str = str_replace('_', '-', $type->type);
$items[] = array(
'path' => 'admin/content/types/' . $type_url_str,
'title' => t($type->name),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'node_type_form',
$type,
),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/content/types/' . $type_url_str . '/delete',
'title' => t('Delete'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'node_type_delete_confirm',
$type,
),
'type' => MENU_CALLBACK,
);
}
}
}
}
return $items;
}
function node_last_changed($nid) {
$node = db_fetch_object(db_query('SELECT changed FROM {node} WHERE nid = %d', $nid));
return $node->changed;
}
function node_node_operations() {
$operations = array(
'publish' => array(
'label' => t('Publish'),
'callback' => 'node_operations_publish',
),
'unpublish' => array(
'label' => t('Unpublish'),
'callback' => 'node_operations_unpublish',
),
'promote' => array(
'label' => t('Promote to front page'),
'callback' => 'node_operations_promote',
),
'demote' => array(
'label' => t('Demote from front page'),
'callback' => 'node_operations_demote',
),
'sticky' => array(
'label' => t('Make sticky'),
'callback' => 'node_operations_sticky',
),
'unsticky' => array(
'label' => t('Remove stickiness'),
'callback' => 'node_operations_unsticky',
),
'delete' => array(
'label' => t('Delete'),
),
);
return $operations;
}
function node_operations_publish($nodes) {
$placeholders = implode(',', array_fill(0, count($nodes), '%d'));
db_query('UPDATE {node} SET status = 1 WHERE nid IN(' . $placeholders . ')', $nodes);
}
function node_operations_unpublish($nodes) {
$placeholders = implode(',', array_fill(0, count($nodes), '%d'));
db_query('UPDATE {node} SET status = 0 WHERE nid IN(' . $placeholders . ')', $nodes);
}
function node_operations_promote($nodes) {
$placeholders = implode(',', array_fill(0, count($nodes), '%d'));
db_query('UPDATE {node} SET status = 1, promote = 1 WHERE nid IN(' . $placeholders . ')', $nodes);
}
function node_operations_demote($nodes) {
$placeholders = implode(',', array_fill(0, count($nodes), '%d'));
db_query('UPDATE {node} SET promote = 0 WHERE nid IN(' . $placeholders . ')', $nodes);
}
function node_operations_sticky($nodes) {
$placeholders = implode(',', array_fill(0, count($nodes), '%d'));
db_query('UPDATE {node} SET status = 1, sticky = 1 WHERE nid IN(' . $placeholders . ')', $nodes);
}
function node_operations_unsticky($nodes) {
$placeholders = implode(',', array_fill(0, count($nodes), '%d'));
db_query('UPDATE {node} SET sticky = 0 WHERE nid IN(' . $placeholders . ')', $nodes);
}
function node_filters() {
$filters['status'] = array(
'title' => t('status'),
'options' => array(
'status-1' => t('published'),
'status-0' => t('not published'),
'promote-1' => t('promoted'),
'promote-0' => t('not promoted'),
'sticky-1' => t('sticky'),
'sticky-0' => t('not sticky'),
),
);
$filters['type'] = array(
'title' => t('type'),
'options' => node_get_types('names'),
);
if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
$filters['category'] = array(
'title' => t('category'),
'options' => $taxonomy,
);
}
return $filters;
}
function node_build_filter_query() {
$filters = node_filters();
$where = $args = array();
$join = '';
foreach ($_SESSION['node_overview_filter'] as $index => $filter) {
list($key, $value) = $filter;
switch ($key) {
case 'status':
list($key, $value) = explode('-', $value, 2);
$where[] = 'n.' . $key . ' = %d';
break;
case 'category':
$table = "tn{$index}";
$where[] = "{$table}.tid = %d";
$join .= "INNER JOIN {term_node} {$table} ON n.nid = {$table}.nid ";
break;
case 'type':
$where[] = "n.type = '%s'";
}
$args[] = $value;
}
$where = count($where) ? 'WHERE ' . implode(' AND ', $where) : '';
return array(
'where' => $where,
'join' => $join,
'args' => $args,
);
}
function node_filter_form() {
$session =& $_SESSION['node_overview_filter'];
$session = is_array($session) ? $session : array();
$filters = node_filters();
$i = 0;
$form['filters'] = array(
'#type' => 'fieldset',
'#title' => t('Show only items where'),
'#theme' => 'node_filters',
);
foreach ($session as $filter) {
list($type, $value) = $filter;
if ($type == 'category') {
$value = module_invoke('taxonomy', 'get_term', $value);
$value = $value->name;
}
else {
$value = $filters[$type]['options'][$value];
}
$string = $i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>';
$form['filters']['current'][] = array(
'#value' => t($string, array(
'%a' => $filters[$type]['title'],
'%b' => $value,
)),
);
if ($type == 'type') {
unset($filters['type']);
}
}
foreach ($filters as $key => $filter) {
$names[$key] = $filter['title'];
$form['filters']['status'][$key] = array(
'#type' => 'select',
'#options' => $filter['options'],
);
}
$form['filters']['filter'] = array(
'#type' => 'radios',
'#options' => $names,
'#default_value' => 'status',
);
$form['filters']['buttons']['submit'] = array(
'#type' => 'submit',
'#value' => count($session) ? t('Refine') : t('Filter'),
);
if (count($session)) {
$form['filters']['buttons']['undo'] = array(
'#type' => 'submit',
'#value' => t('Undo'),
);
$form['filters']['buttons']['reset'] = array(
'#type' => 'submit',
'#value' => t('Reset'),
);
}
return $form;
}
function theme_node_filter_form($form) {
$output .= '<div id="node-admin-filter">';
$output .= drupal_render($form['filters']);
$output .= '</div>';
$output .= drupal_render($form);
return $output;
}
function theme_node_filters($form) {
$output .= '<ul class="clear-block">';
if (sizeof($form['current'])) {
foreach (element_children($form['current']) as $key) {
$output .= '<li>' . drupal_render($form['current'][$key]) . '</li>';
}
}
$output .= '<li><dl class="multiselect">' . (sizeof($form['current']) ? '<dt><em>' . t('and') . '</em> ' . t('where') . '</dt>' : '') . '<dd class="a">';
foreach (element_children($form['filter']) as $key) {
$output .= drupal_render($form['filter'][$key]);
}
$output .= '</dd>';
$output .= '<dt>' . t('is') . '</dt><dd class="b">';
foreach (element_children($form['status']) as $key) {
$output .= drupal_render($form['status'][$key]);
}
$output .= '</dd>';
$output .= '</dl>';
$output .= '<div class="container-inline" id="node-admin-buttons">' . drupal_render($form['buttons']) . '</div>';
$output .= '</li></ul>';
return $output;
}
function node_filter_form_submit($form_id, $form_values) {
$filters = node_filters();
switch ($form_values['op']) {
case t('Filter'):
case t('Refine'):
if (isset($form_values['filter'])) {
$filter = $form_values['filter'];
$flat_options = form_options_flatten($filters[$filter]['options']);
if (isset($flat_options[$form_values[$filter]])) {
$_SESSION['node_overview_filter'][] = array(
$filter,
$form_values[$filter],
);
}
}
break;
case t('Undo'):
array_pop($_SESSION['node_overview_filter']);
break;
case t('Reset'):
$_SESSION['node_overview_filter'] = array();
break;
}
}
function node_admin_nodes_submit($form_id, $form_values) {
$operations = module_invoke_all('node_operations');
$operation = $operations[$form_values['operation']];
$nodes = array_filter($form_values['nodes']);
if ($function = $operation['callback']) {
if (isset($operation['callback arguments'])) {
$args = array_merge(array(
$nodes,
), $operation['callback arguments']);
}
else {
$args = array(
$nodes,
);
}
call_user_func_array($function, $args);
cache_clear_all();
drupal_set_message(t('The update has been performed.'));
}
}
function node_admin_nodes_validate($form_id, $form_values) {
$nodes = array_filter($form_values['nodes']);
if (count($nodes) == 0) {
form_set_error('', t('No items selected.'));
}
}
function node_admin_content() {
$output = drupal_get_form('node_filter_form');
if ($_POST['operation'] == 'delete' && $_POST['nodes']) {
return drupal_get_form('node_multiple_delete_confirm');
}
$output .= drupal_get_form('node_admin_nodes');
return $output;
}
function node_admin_nodes() {
$filter = node_build_filter_query();
$result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n ' . $filter['join'] . ' INNER JOIN {users} u ON n.uid = u.uid ' . $filter['where'] . ' ORDER BY n.changed DESC', 50, 0, NULL, $filter['args']);
$form['options'] = array(
'#type' => 'fieldset',
'#title' => t('Update options'),
'#prefix' => '<div class="container-inline">',
'#suffix' => '</div>',
);
$options = array();
foreach (module_invoke_all('node_operations') as $operation => $array) {
$options[$operation] = $array['label'];
}
$form['options']['operation'] = array(
'#type' => 'select',
'#options' => $options,
'#default_value' => 'approve',
);
$form['options']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update'),
);
$destination = drupal_get_destination();
while ($node = db_fetch_object($result)) {
$nodes[$node->nid] = '';
$form['title'][$node->nid] = array(
'#value' => l($node->title, 'node/' . $node->nid) . ' ' . theme('mark', node_mark($node->nid, $node->changed)),
);
$form['name'][$node->nid] = array(
'#value' => check_plain(node_get_types('name', $node)),
);
$form['username'][$node->nid] = array(
'#value' => theme('username', $node),
);
$form['status'][$node->nid] = array(
'#value' => $node->status ? t('published') : t('not published'),
);
$form['operations'][$node->nid] = array(
'#value' => l(t('edit'), 'node/' . $node->nid . '/edit', array(), $destination),
);
}
$form['nodes'] = array(
'#type' => 'checkboxes',
'#options' => $nodes,
);
$form['pager'] = array(
'#value' => theme('pager', NULL, 50, 0),
);
return $form;
}
function theme_node_admin_nodes($form) {
$header = array(
theme('table_select_header_cell'),
t('Title'),
t('Type'),
t('Author'),
t('Status'),
t('Operations'),
);
$output .= drupal_render($form['options']);
if (isset($form['title']) && is_array($form['title'])) {
foreach (element_children($form['title']) as $key) {
$row = array();
$row[] = drupal_render($form['nodes'][$key]);
$row[] = drupal_render($form['title'][$key]);
$row[] = drupal_render($form['name'][$key]);
$row[] = drupal_render($form['username'][$key]);
$row[] = drupal_render($form['status'][$key]);
$row[] = drupal_render($form['operations'][$key]);
$rows[] = $row;
}
}
else {
$rows[] = array(
array(
'data' => t('No posts available.'),
'colspan' => '6',
),
);
}
$output .= theme('table', $header, $rows);
if ($form['pager']['#value']) {
$output .= drupal_render($form['pager']);
}
$output .= drupal_render($form);
return $output;
}
function node_multiple_delete_confirm() {
$edit = $_POST;
$form['nodes'] = array(
'#prefix' => '<ul>',
'#suffix' => '</ul>',
'#tree' => TRUE,
);
foreach (array_filter($edit['nodes']) as $nid => $value) {
$title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid));
$form['nodes'][$nid] = array(
'#type' => 'hidden',
'#value' => $nid,
'#prefix' => '<li>',
'#suffix' => check_plain($title) . "</li>\n",
);
}
$form['operation'] = array(
'#type' => 'hidden',
'#value' => 'delete',
);
return confirm_form($form, t('Are you sure you want to delete these items?'), 'admin/content/node', t('This action cannot be undone.'), t('Delete all'), t('Cancel'));
}
function node_multiple_delete_confirm_submit($form_id, $form_values) {
if ($form_values['confirm']) {
foreach ($form_values['nodes'] as $nid => $value) {
node_delete($nid);
}
drupal_set_message(t('The items have been deleted.'));
}
return 'admin/content/node';
}
function node_revision_overview($node) {
drupal_set_title(t('Revisions for %title', array(
'%title' => $node->title,
)));
$header = array(
t('Revision'),
array(
'data' => t('Operations'),
'colspan' => 2,
),
);
$revisions = node_revision_list($node);
$rows = array();
$revert_permission = FALSE;
if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {
$revert_permission = TRUE;
}
$delete_permission = FALSE;
if (user_access('administer nodes')) {
$delete_permission = TRUE;
}
foreach ($revisions as $revision) {
$row = array();
$operations = array();
if ($revision->current_vid > 0) {
$row[] = array(
'data' => t('!date by !username', array(
'!date' => l(format_date($revision->timestamp, 'small'), "node/{$node->nid}"),
'!username' => theme('username', $revision),
)) . ($revision->log != '' ? '<p class="revision-log">' . filter_xss($revision->log) . '</p>' : ''),
'class' => 'revision-current',
);
$operations[] = array(
'data' => theme('placeholder', t('current revision')),
'class' => 'revision-current',
'colspan' => 2,
);
}
else {
$row[] = t('!date by !username', array(
'!date' => l(format_date($revision->timestamp, 'small'), "node/{$node->nid}/revisions/{$revision->vid}/view"),
'!username' => theme('username', $revision),
)) . ($revision->log != '' ? '<p class="revision-log">' . filter_xss($revision->log) . '</p>' : '');
if ($revert_permission) {
$operations[] = l(t('revert'), "node/{$node->nid}/revisions/{$revision->vid}/revert");
}
if ($delete_permission) {
$operations[] = l(t('delete'), "node/{$node->nid}/revisions/{$revision->vid}/delete");
}
}
$rows[] = array_merge($row, $operations);
}
return theme('table', $header, $rows);
}
function node_revision_revert($nid, $revision) {
global $user;
$node = node_load($nid, $revision);
if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {
if ($node->vid) {
return drupal_get_form('node_revision_revert_confirm', $node);
}
else {
drupal_set_message(t('You tried to revert to an invalid revision.'), 'error');
}
drupal_goto('node/' . $nid . '/revisions');
}
drupal_access_denied();
}
function node_revision_revert_confirm($node) {
$form['node'] = array(
'#type' => 'value',
'#value' => $node,
);
return confirm_form($form, t('Are you sure you want to revert to the revision from %revision-date?', array(
'%revision-date' => format_date($node->revision_timestamp),
)), 'node/' . $node->nid . '/revisions', '', t('Revert'), t('Cancel'));
}
function node_revision_revert_confirm_submit($form_id, $form_values) {
$node = $form_values['node'];
$node->revision = 1;
$node->log = t('Copy of the revision from %date.', array(
'%date' => format_date($node->revision_timestamp),
));
if (module_exists('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' => format_date($node->revision_timestamp),
'%title' => $node->title,
)));
watchdog('content', t('@type: reverted %title revision %revision.', array(
'@type' => t($node->type),
'%title' => $node->title,
'%revision' => $node->vid,
)));
return 'node/' . $node->nid . '/revisions';
}
function node_revision_delete($nid, $revision) {
if (user_access('administer nodes')) {
$node = node_load($nid);
if (node_access('delete', $node)) {
if ($revision != $node->vid) {
if ($node = node_load($nid, $revision)) {
return drupal_get_form('node_revision_delete_confirm', $node);
}
else {
drupal_set_message(t('Deletion failed. You tried to delete a non-existing revision.'));
}
}
else {
drupal_set_message(t('Deletion failed. You tried to delete the current revision.'));
}
if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $nid)) > 1) {
drupal_goto('node/' . $nid . '/revisions');
}
else {
drupal_goto('node/' . $nid);
}
}
}
drupal_access_denied();
}
function node_revision_delete_confirm($node) {
$form['node'] = array(
'#type' => 'value',
'#value' => $node,
);
return confirm_form($form, t('Are you sure you want to delete the revision from %revision-date?', array(
'%revision-date' => format_date($node->revision_timestamp),
)), 'node/' . $node->nid . '/revisions', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
function node_revision_delete_confirm_submit($form_id, $form_values) {
$node = $form_values['node'];
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' => $node->title,
'%revision' => $node->vid,
)));
watchdog('content', t('@type: deleted %title revision %revision.', array(
'@type' => t($node->type),
'%title' => $node->title,
'%revision' => $node->vid,
)));
if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) > 1) {
return 'node/' . $node->nid . '/revisions';
}
else {
return 'node/' . $node->nid;
}
}
function node_revision_list($node) {
$revisions = array();
$result = db_query('SELECT r.vid, r.title, r.log, r.uid, n.vid AS current_vid, r.timestamp, u.name FROM {node_revisions} r LEFT JOIN {node} n ON n.vid = r.vid INNER JOIN {users} u ON u.uid = r.uid WHERE r.nid = %d ORDER BY r.timestamp DESC', $node->nid);
while ($revision = db_fetch_object($result)) {
$revisions[] = $revision;
}
return $revisions;
}
function node_admin_search() {
return drupal_get_form('search_form', url('admin/content/search'), $_POST['keys'], 'node') . search_data($_POST['keys'], 'node');
}
function node_block($op = 'list', $delta = 0) {
if ($op == 'list') {
$blocks[0]['info'] = t('Syndicate');
return $blocks;
}
else {
if ($op == 'view') {
$block['subject'] = t('Syndicate');
$block['content'] = theme('feed_icon', url('rss.xml'));
return $block;
}
}
}
function node_feed($nodes = 0, $channel = array()) {
global $base_url, $locale;
if (!$nodes) {
$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));
}
$item_length = variable_get('feed_item_length', 'teaser');
$namespaces = array(
'xmlns:dc="http://purl.org/dc/elements/1.1/"',
);
while ($node = db_fetch_object($nodes)) {
$item = node_load($node->nid);
$link = url("node/{$node->nid}", NULL, NULL, 1);
if ($item_length != 'title') {
$teaser = $item_length == 'teaser' ? TRUE : FALSE;
if (node_hook($item, 'view')) {
$item = node_invoke($item, 'view', $teaser, FALSE);
}
else {
$item = node_prepare($item, $teaser);
}
node_invoke_nodeapi($item, 'view', $teaser, FALSE);
}
$extra = node_invoke_nodeapi($item, 'rss item');
$extra = array_merge($extra, array(
array(
'key' => 'pubDate',
'value' => gmdate('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']);
}
}
switch ($item_length) {
case 'fulltext':
$item_text = $item->body;
break;
case 'teaser':
$item_text = $item->teaser;
if ($item->readmore) {
$item_text .= '<p>' . l(t('read more'), 'node/' . $item->nid, NULL, NULL, NULL, TRUE) . '</p>';
}
break;
case 'title':
$item_text = '';
break;
}
$items .= format_rss_item($item->title, $link, $item_text, $extra);
}
$channel_defaults = array(
'version' => '2.0',
'title' => variable_get('site_name', 'Drupal') . (variable_get('site_slogan', '') ? ' - ' . variable_get('site_slogan', '') : ''),
'link' => $base_url,
'description' => variable_get('site_mission', ''),
'language' => $locale,
);
$channel = array_merge($channel_defaults, $channel);
$output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$output .= "<rss version=\"" . $channel["version"] . "\" xml:base=\"" . $base_url . "\" " . implode(' ', $namespaces) . ">\n";
$output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
$output .= "</rss>\n";
drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
print $output;
}
function node_submit($node) {
global $user;
$node = (object) $node;
if (!isset($node->teaser)) {
$node->teaser = isset($node->body) ? node_teaser($node->body, isset($node->format) ? $node->format : NULL) : '';
}
if (user_access('administer nodes')) {
if ($account = user_load(array(
'name' => $node->name,
))) {
$node->uid = $account->uid;
}
else {
$node->uid = 0;
}
}
$node->created = !empty($node->date) ? strtotime($node->date) : time();
node_invoke($node, 'submit');
node_invoke_nodeapi($node, 'submit');
$node->validated = TRUE;
return $node;
}
function node_validate($node, $form = array()) {
$node = (object) $node;
$type = node_get_types('type', $node);
if (isset($node->body) && count(explode(' ', $node->body)) < $type->min_word_count) {
form_set_error('body', t('The body of your @type is too short. You need at least %words words.', array(
'%words' => $type->min_word_count,
'@type' => $type->name,
)));
}
if (isset($node->nid) && node_last_changed($node->nid) > $node->changed) {
form_set_error('changed', t('This content has been modified by another user, changes cannot be saved.'));
}
if (user_access('administer nodes')) {
if (!empty($node->name) && !($account = user_load(array(
'name' => $node->name,
)))) {
form_set_error('name', t('The username %name does not exist.', array(
'%name' => $node->name,
)));
}
if (!empty($node->date) && strtotime($node->date) <= 0) {
form_set_error('date', t('You have to specify a valid date.'));
}
}
node_invoke($node, 'validate', $form);
node_invoke_nodeapi($node, 'validate', $form);
}
function node_form_validate($form_id, $form_values, $form) {
node_validate($form_values, $form);
}
function node_object_prepare(&$node) {
if (!isset($node->created)) {
$node->created = time();
}
if (!isset($node->date)) {
$node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
}
node_invoke($node, 'prepare');
node_invoke_nodeapi($node, 'prepare');
}
function node_form($node, $form_values = NULL) {
global $user;
$node = (object) $node;
node_object_prepare($node);
$form['#id'] = 'node-form';
foreach (array(
'nid',
'vid',
'uid',
'created',
'type',
) as $key) {
$form[$key] = array(
'#type' => 'value',
'#value' => $node->{$key},
);
}
$form['changed'] = array(
'#type' => 'hidden',
'#default_value' => $node->changed,
);
if ($extra = node_invoke($node, 'form', $form_values)) {
$form = array_merge_recursive($form, $extra);
}
if (!isset($form['title']['#weight'])) {
$form['title']['#weight'] = -5;
}
$node_options = variable_get('node_options_' . $node->type, array(
'status',
'promote',
));
if (!isset($node->nid)) {
foreach (array(
'status',
'promote',
'sticky',
) as $key) {
$node->{$key} = in_array($key, $node_options);
}
global $user;
$node->uid = $user->uid;
}
$node->revision = in_array('revision', $node_options);
$form['#node'] = $node;
if ($node->revision || user_access('administer nodes')) {
$form['log'] = array(
'#type' => 'textarea',
'#title' => t('Log message'),
'#rows' => 2,
'#weight' => 20,
'#description' => t('An explanation of the additions or updates being made to help other authors understand your motivations.'),
);
}
$form['author'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer nodes'),
'#title' => t('Authoring information'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 20,
);
$form['author']['name'] = array(
'#type' => 'textfield',
'#title' => t('Authored by'),
'#maxlength' => 60,
'#autocomplete_path' => 'user/autocomplete',
'#default_value' => $node->name ? $node->name : '',
'#weight' => -1,
'#description' => t('Leave blank for %anonymous.', array(
'%anonymous' => variable_get('anonymous', t('Anonymous')),
)),
);
$form['author']['date'] = array(
'#type' => 'textfield',
'#title' => t('Authored on'),
'#maxlength' => 25,
'#description' => t('Format: %time. Leave blank to use the time of form submission.', array(
'%time' => !empty($node->date) ? $node->date : format_date($node->created, 'custom', 'Y-m-d H:i:s O'),
)),
);
if (isset($node->date)) {
$form['author']['date']['#default_value'] = $node->date;
}
$form['options'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer nodes'),
'#title' => t('Publishing options'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 25,
);
$form['options']['status'] = array(
'#type' => 'checkbox',
'#title' => t('Published'),
'#default_value' => $node->status,
);
$form['options']['promote'] = array(
'#type' => 'checkbox',
'#title' => t('Promoted to front page'),
'#default_value' => $node->promote,
);
$form['options']['sticky'] = array(
'#type' => 'checkbox',
'#title' => t('Sticky at top of lists'),
'#default_value' => $node->sticky,
);
$form['options']['revision'] = array(
'#type' => 'checkbox',
'#title' => t('Create new revision'),
'#default_value' => $node->revision,
);
foreach (array(
'uid',
'created',
) as $key) {
$form[$key] = array(
'#type' => 'value',
'#value' => $node->{$key},
);
}
$form['preview'] = array(
'#type' => 'button',
'#value' => t('Preview'),
'#weight' => 40,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#weight' => 45,
);
if ($node->nid && node_access('delete', $node)) {
$form['delete'] = array(
'#type' => 'button',
'#value' => t('Delete'),
'#weight' => 50,
);
}
$form['#after_build'] = array(
'node_form_add_preview',
);
$form['#validate']['node_form_validate'] = array();
$node_validate = $node->type . '_node_form_validate';
if (function_exists($node_validate)) {
$form['#validate'][$node_validate] = array();
}
$form['#base'] = 'node_form';
return $form;
}
function node_form_add_preview($form) {
global $form_values;
$op = isset($form_values['op']) ? $form_values['op'] : '';
if ($op == t('Preview')) {
drupal_validate_form($form['form_id']['#value'], $form);
if (!form_get_errors()) {
$preview = node_preview((object) $form_values);
$form['#prefix'] = isset($form['#prefix']) ? $preview . $form['#prefix'] : $preview;
}
}
if (variable_get('node_preview', 0) && (form_get_errors() || $op != t('Preview'))) {
unset($form['submit']);
}
return $form;
}
function theme_node_form($form) {
$output = "\n<div class=\"node-form\">\n";
$admin = '';
if (isset($form['author'])) {
$admin .= " <div class=\"authored\">\n";
$admin .= drupal_render($form['author']);
$admin .= " </div>\n";
}
if (isset($form['options'])) {
$admin .= " <div class=\"options\">\n";
$admin .= drupal_render($form['options']);
$admin .= " </div>\n";
}
$buttons = drupal_render($form['preview']);
$buttons .= drupal_render($form['submit']);
$buttons .= isset($form['delete']) ? drupal_render($form['delete']) : '';
$output .= " <div class=\"standard\">\n";
$output .= drupal_render($form);
$output .= " </div>\n";
if (!empty($admin)) {
$output .= " <div class=\"admin\">\n";
$output .= $admin;
$output .= " </div>\n";
}
$output .= $buttons;
$output .= "</div>\n";
return $output;
}
function node_add($type = NULL) {
global $user;
$types = node_get_types();
$type = isset($type) ? str_replace('-', '_', $type) : NULL;
if (isset($types[$type]) && node_access('create', $type)) {
$node = array(
'uid' => $user->uid,
'name' => $user->name,
'type' => $type,
);
drupal_set_title(t('Submit @name', array(
'@name' => $types[$type]->name,
)));
$output = drupal_get_form($type . '_node_form', $node);
}
else {
foreach ($types as $type) {
if (function_exists($type->module . '_form') && node_access('create', $type->type)) {
$type_url_str = str_replace('_', '-', $type->type);
$title = t('Add a new @s.', array(
'@s' => $type->name,
));
$out = '<dt>' . l(drupal_ucfirst($type->name), "node/add/{$type_url_str}", array(
'title' => $title,
)) . '</dt>';
$out .= '<dd>' . filter_xss_admin($type->description) . '</dd>';
$item[$type->name] = $out;
}
}
if (isset($item)) {
uksort($item, 'strnatcasecmp');
$output = t('Choose the appropriate item from the list:') . '<dl>' . implode('', $item) . '</dl>';
}
else {
$output = t('No content types available.');
}
}
return $output;
}
function node_preview($node) {
if (node_access('create', $node) || node_access('update', $node)) {
if (isset($node->name)) {
if ($user = user_load(array(
'name' => $node->name,
))) {
$node->uid = $user->uid;
$node->picture = $user->picture;
}
else {
$node->uid = 0;
}
}
else {
if ($node->uid) {
$user = user_load(array(
'uid' => $node->uid,
));
$node->name = $user->name;
$node->picture = $user->picture;
}
}
$node->changed = time();
if (!isset($node->teaser)) {
$node->teaser = node_teaser($node->body, $node->format);
}
if (!form_get_errors()) {
$cloned_node = drupal_clone($node);
$cloned_node->in_preview = TRUE;
$output = theme('node_preview', $cloned_node);
}
drupal_set_title(t('Preview'));
drupal_set_breadcrumb(array(
l(t('Home'), NULL),
l(t('Create content'), 'node/add'),
l(t('Submit @name', array(
'@name' => node_get_types('name', $node),
)), 'node/add/' . $node->type),
));
return $output;
}
}
function theme_node_preview($node) {
$output = '<div class="preview">';
if ($node->teaser && $node->teaser != $node->body) {
drupal_set_message(t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication. You can insert the delimiter "<!--break-->" (without the quotes) to fine-tune where your post gets split.'));
$output .= '<h3>' . t('Preview trimmed version') . '</h3>';
$output .= node_view(drupal_clone($node), 1, FALSE, 0);
$output .= '<h3>' . t('Preview full version') . '</h3>';
$output .= node_view($node, 0, FALSE, 0);
}
else {
$output .= node_view($node, 0, FALSE, 0);
}
$output .= "</div>\n";
return $output;
}
function theme_node_log_message($log) {
return '<div class="log"><div class="title">' . t('Log') . ':</div>' . $log . '</div>';
}
function node_form_submit($form_id, $form_values) {
global $user;
$node = node_submit($form_values);
if ($node->nid) {
node_save($node);
watchdog('content', t('@type: updated %title.', array(
'@type' => t($node->type),
'%title' => $node->title,
)), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid));
drupal_set_message(t('The %post has been updated.', array(
'%post' => node_get_types('name', $node),
)));
}
else {
node_save($node);
watchdog('content', t('@type: added %title.', array(
'@type' => t($node->type),
'%title' => $node->title,
)), WATCHDOG_NOTICE, l(t('view'), "node/{$node->nid}"));
drupal_set_message(t('Your %post has been created.', array(
'%post' => node_get_types('name', $node),
)));
}
if ($node->nid) {
if (node_access('view', $node)) {
return 'node/' . $node->nid;
}
else {
return '';
}
}
return FALSE;
}
function node_delete_confirm($node) {
$form['nid'] = array(
'#type' => 'value',
'#value' => $node->nid,
);
return confirm_form($form, t('Are you sure you want to delete %title?', array(
'%title' => $node->title,
)), isset($_GET['destination']) ? $_GET['destination'] : 'node/' . $node->nid, t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
function node_delete_confirm_submit($form_id, $form_values) {
if ($form_values['confirm']) {
node_delete($form_values['nid']);
}
return '<front>';
}
function node_delete($nid) {
$node = node_load($nid);
if (node_access('delete', $node)) {
db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid);
node_invoke($node, 'delete');
node_invoke_nodeapi($node, 'delete');
cache_clear_all();
if (function_exists('search_wipe')) {
search_wipe($node->nid, 'node');
}
drupal_set_message(t('%title has been deleted.', array(
'%title' => $node->title,
)));
watchdog('content', t('@type: deleted %title.', array(
'@type' => t($node->type),
'%title' => $node->title,
)));
}
}
function node_revisions() {
if (is_numeric(arg(1)) && arg(2) == 'revisions') {
$op = arg(4) ? arg(4) : 'overview';
switch ($op) {
case 'overview':
$node = node_load(arg(1));
if ((user_access('view revisions') || user_access('administer nodes')) && node_access('view', $node)) {
return node_revision_overview($node);
}
drupal_access_denied();
return;
case 'view':
if (is_numeric(arg(3))) {
$node = node_load(arg(1), arg(3));
if ($node->nid) {
if ((user_access('view revisions') || user_access('administer nodes')) && node_access('view', $node)) {
drupal_set_title(t('Revision of %title from %date', array(
'%title' => $node->title,
'%date' => format_date($node->revision_timestamp),
)));
return node_show($node, arg(2));
}
drupal_access_denied();
return;
}
}
break;
}
}
drupal_not_found();
}
function node_page_default($arg = NULL) {
if (isset($arg)) {
return MENU_NOT_FOUND;
}
$result = pager_query(db_rewrite_sql('SELECT n.nid, n.sticky, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC'), variable_get('default_nodes_main', 10));
if (db_num_rows($result)) {
$feed_url = url('rss.xml', NULL, NULL, TRUE);
drupal_add_feed($feed_url, variable_get('site_name', 'Drupal') . ' ' . t('RSS'));
$output = '';
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load($node->nid), 1);
}
$output .= theme('pager', NULL, variable_get('default_nodes_main', 10));
}
else {
$admin = db_result(db_query('SELECT uid FROM {users} WHERE uid = 1'));
$default_message = t('<h1 class="title">Welcome to your new Drupal website!</h1><p>Please follow these steps to set up and start using your website:</p>');
$default_message .= '<ol>';
if (!$admin) {
$default_message .= '<li>' . t('<strong>Create your administrator account</strong> 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.', array(
'@register' => url('user/register'),
)) . '</li>';
}
$default_message .= '<li>' . t('<strong>Configure your website</strong> 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.', array(
'@admin' => url('admin'),
'@config' => url('admin/settings'),
)) . '</li>';
$default_message .= '<li>' . t('<strong>Enable additional functionality</strong> 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>.', array(
'@modules' => url('admin/build/modules'),
'@download_modules' => 'http://drupal.org/project/Modules',
)) . '</li>';
$default_message .= '<li>' . t('<strong>Customize your website design</strong> 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>.', array(
'@themes' => url('admin/build/themes'),
'@download_themes' => 'http://drupal.org/project/Themes',
)) . '</li>';
$default_message .= '<li>' . t('<strong>Start posting content</strong> Finally, you can <a href="@content">create content</a> for your website. This message will disappear once you have promoted a post to the front page.', array(
'@content' => url('node/add'),
)) . '</li>';
$default_message .= '</ol>';
$default_message .= '<p>' . t('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.', array(
'@help' => url('admin/help'),
'@handbook' => 'http://drupal.org/handbooks',
'@forum' => 'http://drupal.org/forum',
'@support' => 'http://drupal.org/support',
)) . '</p>';
$output = '<div id="first-time">' . $default_message . '</div>';
}
drupal_set_title('');
return $output;
}
function node_page_view($node, $cid = NULL) {
drupal_set_title(check_plain($node->title));
return node_show($node, $cid);
}
function node_page_edit($node) {
if ($_POST['op'] == t('Delete')) {
if ($_REQUEST['destination']) {
$destination = drupal_get_destination();
unset($_REQUEST['destination']);
}
drupal_goto('node/' . $node->nid . '/delete', $destination);
}
drupal_set_title(check_plain($node->title));
return drupal_get_form($node->type . '_node_form', $node);
}
function node_update_shutdown() {
global $last_change, $last_nid;
if ($last_change && $last_nid) {
variable_set('node_cron_last', $last_change);
variable_set('node_cron_last_nid', $last_nid);
}
}
function node_update_index() {
global $last_change, $last_nid;
register_shutdown_function('node_update_shutdown');
$last = variable_get('node_cron_last', 0);
$last_nid = variable_get('node_cron_last_nid', 0);
$limit = (int) variable_get('search_cron_limit', 100);
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_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node_counter}'))));
$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);
while ($node = db_fetch_object($result)) {
$last_change = $node->last_change;
$last_nid = $node->nid;
$node = node_load($node->nid);
$node = node_build_content($node, FALSE, FALSE);
$node->body = drupal_render($node->content);
node_invoke_nodeapi($node, 'alter');
$text = '<h1>' . check_plain($node->title) . '</h1>' . $node->body;
$extra = node_invoke_nodeapi($node, 'update index');
foreach ($extra as $t) {
$text .= $t;
}
search_index($node->nid, 'node', $text);
}
}
function node_form_alter($form_id, &$form) {
if ($form_id == 'search_form' && arg(1) == 'node' && user_access('use advanced search')) {
$form['advanced'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced search'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#attributes' => array(
'class' => 'search-advanced',
),
);
$form['advanced']['keywords'] = array(
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
);
$form['advanced']['keywords']['or'] = array(
'#type' => 'textfield',
'#title' => t('Containing any of the words'),
'#size' => 30,
'#maxlength' => 255,
);
$form['advanced']['keywords']['phrase'] = array(
'#type' => 'textfield',
'#title' => t('Containing the phrase'),
'#size' => 30,
'#maxlength' => 255,
);
$form['advanced']['keywords']['negative'] = array(
'#type' => 'textfield',
'#title' => t('Containing none of the words'),
'#size' => 30,
'#maxlength' => 255,
);
if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
$form['advanced']['category'] = array(
'#type' => 'select',
'#title' => t('Only in the category(s)'),
'#prefix' => '<div class="criterion">',
'#size' => 10,
'#suffix' => '</div>',
'#options' => $taxonomy,
'#multiple' => TRUE,
);
}
$types = array_map('check_plain', node_get_types('names'));
$form['advanced']['type'] = array(
'#type' => 'checkboxes',
'#title' => t('Only of the type(s)'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $types,
);
$form['advanced']['submit'] = array(
'#type' => 'submit',
'#value' => t('Advanced search'),
'#prefix' => '<div class="action">',
'#suffix' => '</div>',
);
$form['#validate']['node_search_validate'] = array();
}
}
function node_search_validate($form_id, $form_values, $form) {
$keys = $form_values['processed_keys'];
if (isset($form_values['type']) && is_array($form_values['type'])) {
$form_values['type'] = array_filter($form_values['type']);
if (count($form_values['type'])) {
$keys = search_query_insert($keys, 'type', implode(',', array_keys($form_values['type'])));
}
}
if (isset($form_values['category']) && is_array($form_values['category'])) {
$keys = search_query_insert($keys, 'category', implode(',', $form_values['category']));
}
if ($form_values['or'] != '') {
if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' ' . $form_values['or'], $matches)) {
$keys .= ' ' . implode(' OR ', $matches[1]);
}
}
if ($form_values['negative'] != '') {
if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' ' . $form_values['negative'], $matches)) {
$keys .= ' -' . implode(' -', $matches[1]);
}
}
if ($form_values['phrase'] != '') {
$keys .= ' "' . str_replace('"', ' ', $form_values['phrase']) . '"';
}
if (!empty($keys)) {
form_set_value($form['basic']['inline']['processed_keys'], trim($keys));
}
}
function node_access($op, $node = NULL) {
global $user;
if (!$node || !in_array($op, array(
'view',
'update',
'delete',
'create',
), TRUE)) {
return FALSE;
}
if ($op != 'create') {
$node = (object) $node;
}
if ($op == 'update' && !filter_access($node->format)) {
return FALSE;
}
if (user_access('administer nodes')) {
return TRUE;
}
if (!user_access('access content')) {
return FALSE;
}
$module = node_get_types('module', $node);
if ($module == 'node') {
$module = 'node_content';
}
$access = module_invoke($module, 'access', $op, $node);
if (!is_null($access)) {
return $access;
}
if ($op != 'create' && $node->nid && $node->status) {
$grants = array();
foreach (node_access_grants($op) as $realm => $gids) {
foreach ($gids as $gid) {
$grants[] = "(gid = {$gid} AND realm = '{$realm}')";
}
}
$grants_sql = '';
if (count($grants)) {
$grants_sql = 'AND (' . implode(' OR ', $grants) . ')';
}
$sql = "SELECT COUNT(*) FROM {node_access} WHERE (nid = 0 OR nid = %d) {$grants_sql} AND grant_{$op} >= 1";
$result = db_query($sql, $node->nid);
return db_result($result);
}
if ($op == 'view' && $user->uid == $node->uid && $user->uid != 0) {
return TRUE;
}
return FALSE;
}
function _node_access_join_sql($node_alias = 'n', $node_access_alias = 'na') {
if (user_access('administer nodes')) {
return '';
}
return 'INNER JOIN {node_access} ' . $node_access_alias . ' ON ' . $node_access_alias . '.nid = ' . $node_alias . '.nid';
}
function _node_access_where_sql($op = 'view', $node_access_alias = 'na', $uid = NULL) {
if (user_access('administer nodes')) {
return;
}
$grants = array();
foreach (node_access_grants($op, $uid) as $realm => $gids) {
foreach ($gids as $gid) {
$grants[] = "({$node_access_alias}.gid = {$gid} AND {$node_access_alias}.realm = '{$realm}')";
}
}
$grants_sql = '';
if (count($grants)) {
$grants_sql = 'AND (' . implode(' OR ', $grants) . ')';
}
$sql = "{$node_access_alias}.grant_{$op} >= 1 {$grants_sql}";
return $sql;
}
function node_access_grants($op, $uid = NULL) {
global $user;
if (isset($uid)) {
$user_object = user_load(array(
'uid' => $uid,
));
}
else {
$user_object = $user;
}
return array_merge(array(
'all' => array(
0,
),
), module_invoke_all('node_grants', $user_object, $op));
}
function node_access_view_all_nodes() {
static $access;
if (!isset($access)) {
$grants = array();
foreach (node_access_grants('view') as $realm => $gids) {
foreach ($gids as $gid) {
$grants[] = "(gid = {$gid} AND realm = '{$realm}')";
}
}
$grants_sql = '';
if (count($grants)) {
$grants_sql = 'AND (' . implode(' OR ', $grants) . ')';
}
$sql = "SELECT COUNT(*) FROM {node_access} WHERE nid = 0 {$grants_sql} AND grant_view >= 1";
$result = db_query($sql);
$access = db_result($result);
}
return $access;
}
function node_db_rewrite_sql($query, $primary_table, $primary_field) {
if ($primary_field == 'nid' && !node_access_view_all_nodes()) {
$return['join'] = _node_access_join_sql($primary_table);
$return['where'] = _node_access_where_sql();
$return['distinct'] = 1;
return $return;
}
}
function node_access_acquire_grants($node) {
$grants = module_invoke_all('node_access_records', $node);
if (!$grants) {
$grants[] = array(
'realm' => 'all',
'gid' => 0,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
);
}
else {
$grant_by_priority = array();
foreach ($grants as $g) {
$grant_by_priority[intval($g['priority'])][] = $g;
}
krsort($grant_by_priority);
$grants = array_shift($grant_by_priority);
}
node_access_write_grants($node, $grants);
}
function node_access_write_grants($node, $grants, $realm = NULL, $delete = TRUE) {
if ($delete) {
$query = 'DELETE FROM {node_access} WHERE nid = %d';
if ($realm) {
$query .= " AND realm in ('%s', 'all')";
}
db_query($query, $node->nid, $realm);
}
if (count(module_implements('node_grants'))) {
foreach ($grants as $grant) {
if ($realm && $realm != $grant['realm']) {
continue;
}
if ($grant['grant_view'] || $grant['grant_update'] || $grant['grant_delete']) {
db_query("INSERT INTO {node_access} (nid, realm, gid, grant_view, grant_update, grant_delete) VALUES (%d, '%s', %d, %d, %d, %d)", $node->nid, $grant['realm'], $grant['gid'], $grant['grant_view'], $grant['grant_update'], $grant['grant_delete']);
}
}
}
}
function node_access_rebuild() {
db_query("DELETE FROM {node_access}");
if (count(module_implements('node_grants'))) {
if (!ini_get('safe_mode')) {
set_time_limit(240);
}
$result = db_query("SELECT nid FROM {node}");
while ($node = db_fetch_object($result)) {
$loaded_node = node_load($node->nid, NULL, TRUE);
if (!empty($loaded_node)) {
node_access_acquire_grants($loaded_node);
}
}
}
else {
db_query("INSERT INTO {node_access} VALUES (0, 0, 'all', 1, 0, 0)");
}
cache_clear_all();
}
function node_content_access($op, $node) {
global $user;
$type = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
if ($op == 'create') {
return user_access('create ' . $type . ' content');
}
if ($op == 'update' || $op == 'delete') {
if (user_access('edit ' . $type . ' content') || user_access('edit own ' . $type . ' content') && $user->uid == $node->uid) {
return TRUE;
}
}
}
function node_content_form($node) {
$type = node_get_types('type', $node);
$form = array();
if ($type->has_title) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -5,
);
}
if ($type->has_body) {
$form['body_filter']['body'] = array(
'#type' => 'textarea',
'#title' => check_plain($type->body_label),
'#default_value' => $node->body,
'#rows' => 20,
'#required' => $type->min_word_count > 0,
);
$form['body_filter']['format'] = filter_form($node->format);
}
return $form;
}
function node_forms() {
foreach (array_keys(node_get_types()) as $type) {
$forms[$type . '_node_form']['callback'] = 'node_form';
}
return $forms;
}