View source
<?php
define('NODE_NEW_LIMIT', time() - 30 * 24 * 60 * 60);
define('NODE_BUILD_NORMAL', 0);
define('NODE_BUILD_PREVIEW', 1);
define('NODE_BUILD_SEARCH_INDEX', 2);
define('NODE_BUILD_SEARCH_RESULT', 3);
define('NODE_BUILD_RSS', 4);
define('NODE_BUILD_PRINT', 5);
function node_help($path, $arg) {
if ($path != 'admin/content/node-settings/rebuild' && $path != 'batch' && strpos($path, '#') === FALSE && user_access('access administration pages') && node_access_needs_rebuild()) {
if ($path == 'admin/content/node-settings') {
$message = t('The content access permissions need to be rebuilt.');
}
else {
$message = t('The content access permissions need to be rebuilt. Please visit <a href="@node_access_rebuild">this page</a>.', array(
'@node_access_rebuild' => url('admin/content/node-settings/rebuild'),
));
}
drupal_set_message($message, 'error');
}
switch ($path) {
case 'admin/help#node':
$output = '<p>' . t('The node module manages content on your site, and stores all posts (regardless of type) as a "node". In addition to basic publishing settings, including whether the post has been published, promoted to the site front page, or should remain present (or sticky) at the top of lists, the node module also records basic information about the author of a post. Optional revision control over edits is available. For additional functionality, the node module is often extended by other modules.') . '</p>';
$output .= '<p>' . t('Though each post on your site is a node, each post is also of a particular <a href="@content-type">content type</a>. <a href="@content-type">Content types</a> are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Each content type may have different default settings for <em>Publishing options</em> and other workflow controls. By default, the two content types in a standard Drupal installation are <em>Page</em> and <em>Story</em>. Use the <a href="@content-type">content types page</a> to add new or edit existing content types. Additional content types also become available as you enable additional core, contributed and custom modules.', array(
'@content-type' => url('admin/content/types'),
)) . '</p>';
$output .= '<p>' . t('The administrative <a href="@content">content page</a> allows you to review and manage your site content. The <a href="@post-settings">post settings page</a> sets certain options for the display of posts. The node module makes a number of permissions available for each content type, which may be set by role on the <a href="@permissions">permissions page</a>.', array(
'@content' => url('admin/content/node'),
'@post-settings' => url('admin/content/node-settings'),
'@permissions' => url('admin/user/permissions'),
)) . '</p>';
$output .= '<p>' . t('For more information, see the online handbook entry for <a href="@node">Node module</a>.', array(
'@node' => 'http://drupal.org/handbook/modules/node/',
)) . '</p>';
return $output;
case 'admin/content/node':
return ' ';
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>';
case 'node/%/revisions':
return '<p>' . t('The revisions let you track differences between multiple versions of a post.') . '</p>';
case 'node/%/edit':
$node = node_load($arg[1]);
$type = node_get_types('type', $node->type);
return !empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '';
}
if ($arg[0] == 'node' && $arg[1] == 'add' && $arg[2]) {
$type = node_get_types('type', str_replace('-', '_', $arg[2]));
return !empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '';
}
}
function node_theme() {
return array(
'node' => array(
'arguments' => array(
'node' => NULL,
'teaser' => FALSE,
'page' => FALSE,
),
'template' => 'node',
),
'node_list' => array(
'arguments' => array(
'items' => NULL,
'title' => NULL,
),
),
'node_search_admin' => array(
'arguments' => array(
'form' => NULL,
),
),
'node_filter_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'node.admin.inc',
),
'node_filters' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'node.admin.inc',
),
'node_admin_nodes' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'node.admin.inc',
),
'node_add_list' => array(
'arguments' => array(
'content' => NULL,
),
'file' => 'node.pages.inc',
),
'node_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'node.pages.inc',
),
'node_preview' => array(
'arguments' => array(
'node' => NULL,
),
'file' => 'node.pages.inc',
),
'node_log_message' => array(
'arguments' => array(
'log' => NULL,
),
),
'node_submitted' => array(
'arguments' => array(
'node' => NULL,
),
),
);
}
function node_cron() {
db_query('DELETE FROM {history} WHERE timestamp < %d', NODE_NEW_LIMIT);
}
function node_title_list($result, $title = NULL) {
$items = array();
$num_rows = FALSE;
while ($node = db_fetch_object($result)) {
$items[] = l($node->title, 'node/' . $node->nid, !empty($node->comment_count) ? array(
'attributes' => array(
'title' => format_plural($node->comment_count, '1 comment', '@count comments'),
),
) : array());
$num_rows = TRUE;
}
return $num_rows ? theme('node_list', $items, $title) : FALSE;
}
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_js(&$form, &$form_state) {
if (isset($form['#post']['teaser_js'])) {
if (trim($form_state['values']['teaser_js'])) {
$body = trim($form_state['values']['teaser_js']) . "\r\n<!--break-->\r\n" . trim($form_state['values']['body']);
}
else {
$body = '<!--break-->' . $form_state['values']['body'];
}
form_set_value($form['body'], $body, $form_state);
$form['body']['#value'] = $body;
}
return $form;
}
function node_teaser_include_verify(&$form, &$form_state) {
$message = '';
if (isset($form['#post']['body']) && isset($form_state['values']['teaser_include']) && !$form_state['values']['teaser_include']) {
if (strpos($form_state['values']['body'], '<!--break-->') === 0) {
$message = t('You specified that the summary should not be shown when this post is displayed in full view. This setting is ignored when the summary is empty.');
}
elseif (strpos($form_state['values']['body'], '<!--break-->') === FALSE) {
$message = t('You specified that the summary should not be shown when this post is displayed in full view. This setting has been ignored since you have not defined a summary for the post. (To define a summary, insert the delimiter "<!--break-->" (without the quotes) in the Body of the post to indicate the end of the summary and the start of the main content.)');
}
if (!empty($message)) {
drupal_set_message($message, 'warning');
form_set_value($form['teaser_include'], 1, $form_state);
$form['teaser_include']['#value'] = 1;
}
}
return $form;
}
function node_teaser($body, $format = NULL, $size = NULL) {
if (!isset($size)) {
$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['php/0']) && strpos($body, '<?') !== FALSE) {
return $body;
}
}
if (drupal_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/1'])) {
$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 isset($_node_types[$type]) ? $_node_types[$type] : FALSE;
case 'module':
return isset($_node_types[$type]->module) ? $_node_types[$type]->module : FALSE;
case 'names':
return $_node_names;
case 'name':
return isset($_node_names[$type]) ? $_node_names[$type] : FALSE;
}
}
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_result(db_query("SELECT COUNT(*) FROM {node_type} WHERE type = '%s'", $existing_type));
if (!isset($info->help)) {
$info->help = '';
}
if (!isset($info->min_word_count)) {
$info->min_word_count = 0;
}
if (!isset($info->body_label)) {
$info->body_label = '';
}
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) {
$info = node_get_types('type', $type);
db_query("DELETE FROM {node_type} WHERE type = '%s'", $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) {
if (isset($nodes[$param])) {
return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param];
}
}
$cond = 'n.nid = %d';
$arguments[] = $param;
}
elseif (is_array($param)) {
foreach ($param as $key => $value) {
$cond[] = 'n.' . db_escape_table($key) . " = '%s'";
$arguments[] = $value;
}
$cond = implode(' AND ', $cond);
}
else {
return FALSE;
}
$fields = drupal_schema_fields_sql('node', 'n');
$fields = array_merge($fields, drupal_schema_fields_sql('node_revisions', 'r'));
$fields = array_merge($fields, array(
'u.name',
'u.picture',
'u.data',
));
$fields = array_diff($fields, array(
'n.vid',
'n.title',
'r.nid',
));
$fields = implode(', ', $fields);
$fields = str_replace('r.timestamp', 'r.timestamp AS revision_timestamp', $fields);
$fields = str_replace('r.uid', 'r.uid AS revision_uid', $fields);
if ($revision) {
array_unshift($arguments, $revision);
$node = db_fetch_object(db_query('SELECT ' . $fields . ' 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 ' . $fields . ' 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 && $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_validate($node, $form = array()) {
$node = (object) $node;
$type = node_get_types('type', $node);
if (!empty($type->min_word_count) && isset($node->body) && count(explode(' ', $node->body)) < $type->min_word_count) {
form_set_error('body', t('The @body_label of your @type is too short. You need at least %words words.', array(
'@body_label' => $type->body_label,
'@type' => $type->name,
'%words' => $type->min_word_count,
)));
}
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_submit($node) {
global $user;
$node = (object) $node;
if (!isset($node->teaser)) {
if (isset($node->body)) {
$node->teaser = node_teaser($node->body, isset($node->format) ? $node->format : NULL);
if (isset($node->teaser_include) && !$node->teaser_include && $node->teaser == substr($node->body, 0, strlen($node->teaser))) {
$node->body = substr($node->body, strlen($node->teaser));
}
}
else {
$node->teaser = '';
$node->format = 0;
}
}
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->validated = TRUE;
return $node;
}
function node_save(&$node) {
node_invoke_nodeapi($node, 'presave');
global $user;
$node->is_new = empty($node->nid);
if ($node->is_new || !empty($node->revision)) {
if (!isset($node->log)) {
$node->log = '';
}
}
elseif (empty($node->log)) {
unset($node->log);
}
if (!isset($node->teaser)) {
$node->teaser = '';
}
if (!isset($node->body)) {
$node->body = '';
}
if (!$node->is_new && !empty($node->revision) && $node->vid) {
$node->old_vid = $node->vid;
}
$time = time();
if (empty($node->created)) {
$node->created = $time;
}
$node->changed = $time;
$node->timestamp = $time;
$node->format = isset($node->format) ? $node->format : FILTER_FORMAT_DEFAULT;
if ($node->is_new) {
_node_save_revision($node, $user->uid);
drupal_write_record('node', $node);
db_query('UPDATE {node_revisions} SET nid = %d WHERE vid = %d', $node->nid, $node->vid);
$op = 'insert';
}
else {
drupal_write_record('node', $node, 'nid');
if (!empty($node->revision)) {
_node_save_revision($node, $user->uid);
db_query('UPDATE {node} SET vid = %d WHERE nid = %d', $node->vid, $node->nid);
}
else {
_node_save_revision($node, $user->uid, 'vid');
}
$op = 'update';
}
node_invoke($node, $op);
node_invoke_nodeapi($node, $op);
node_access_acquire_grants($node);
cache_clear_all();
}
function _node_save_revision(&$node, $uid, $update = NULL) {
$temp_uid = $node->uid;
$node->uid = $uid;
if (isset($update)) {
drupal_write_record('node_revisions', $node, $update);
}
else {
drupal_write_record('node_revisions', $node);
}
$node->uid = $temp_uid;
}
function node_delete($nid) {
$node = node_load($nid, NULL, TRUE);
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);
db_query('DELETE FROM {node_access} 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');
}
watchdog('content', '@type: deleted %title.', array(
'@type' => $node->type,
'%title' => $node->title,
));
drupal_set_message(t('@type %title has been deleted.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
)));
}
}
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);
drupal_alter('link', $node->links, $node);
}
$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 = $node->teaser != $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) {
if (!isset($node->build_mode)) {
$node->build_mode = NODE_BUILD_NORMAL;
}
$node->body = isset($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, $message = FALSE) {
if ($message) {
drupal_set_title(t('Revision of %title from %date', array(
'%title' => $node->title,
'%date' => format_date($node->revision_timestamp),
)));
}
$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 theme_node_log_message($log) {
return '<div class="log"><div class="title">' . t('Log') . ':</div>' . $log . '</div>';
}
function node_perm() {
$perms = array(
'administer content types',
'administer nodes',
'access content',
'view revisions',
'revert revisions',
'delete revisions',
);
foreach (node_get_types() as $type) {
if ($type->module == 'node') {
$name = check_plain($type->type);
$perms[] = 'create ' . $name . ' content';
$perms[] = 'delete own ' . $name . ' content';
$perms[] = 'delete any ' . $name . ' content';
$perms[] = 'edit own ' . $name . ' content';
$perms[] = 'edit any ' . $name . ' content';
}
}
return $perms;
}
function node_search($op = 'search', $keys = NULL) {
switch ($op) {
case 'name':
return t('Content');
case 'reset':
db_query("UPDATE {search_dataset} SET reindex = %d WHERE type = 'node'", time());
return;
case 'status':
$total = db_result(db_query('SELECT COUNT(*) FROM {node} WHERE status = 1'));
$remaining = db_result(db_query("SELECT COUNT(*) FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE n.status = 1 AND (d.sid IS NULL OR d.reindex <> 0)"));
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.vid = tn.vid';
$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(MAX(n.created), MAX(n.changed), COALESCE(MAX(c.last_comment_timestamp), 0)) - %d) * 6.43e-8)';
$arguments2[] = $weight;
$arguments2[] = (int) variable_get('node_cron_last', 0);
$join2 .= ' 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 + MAX(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 + MAX(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, $conditions1 . (empty($where1) ? '' : ' AND ' . $where1), $arguments1, $select2, $join2, $arguments2);
$results = array();
foreach ($find as $item) {
$node = node_load($item->sid);
$node->build_mode = NODE_BUILD_SEARCH_RESULT;
$node = node_build_content($node, FALSE, FALSE);
$node->body = drupal_render($node->content);
if (module_exists('comment')) {
$node->body .= comment_nodeapi($node, 'update index');
}
if (module_exists('taxonomy')) {
$node->body .= taxonomy_nodeapi($node, 'update index');
}
$extra = node_invoke_nodeapi($node, 'search result');
$results[] = array(
'link' => url('node/' . $item->sid, array(
'absolute' => TRUE,
)),
'type' => check_plain(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_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 && !empty($node->readmore)) {
$links['node_read_more'] = array(
'title' => t('Read more'),
'href' => "node/{$node->nid}",
'attributes' => array(
'title' => t('Read the rest of !title.', array(
'!title' => $node->title,
)),
),
);
}
}
return $links;
}
function _node_revision_access($node, $op = 'view') {
static $access = array();
if (!isset($access[$node->vid])) {
$node_current_revision = node_load($node->nid);
$is_current_revision = $node_current_revision->vid == $node->vid;
if ($is_current_revision && (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) == 1 || $op == 'update' || $op == 'delete')) {
$access[$node->vid] = FALSE;
}
elseif (user_access('administer nodes')) {
$access[$node->vid] = TRUE;
}
else {
$map = array(
'view' => 'view revisions',
'update' => 'revert revisions',
'delete' => 'delete revisions',
);
$access[$node->vid] = isset($map[$op]) && user_access($map[$op]) && node_access($op, $node_current_revision) && ($is_current_revision || node_access($op, $node));
}
}
return $access[$node->vid];
}
function _node_add_access() {
$types = node_get_types();
foreach ($types as $type) {
if (node_hook($type->type, 'form') && node_access('create', $type->type)) {
return TRUE;
}
}
return FALSE;
}
function node_menu() {
$items['admin/content/node'] = array(
'title' => 'Content',
'description' => "View, edit, and delete your site's content.",
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_admin_content',
),
'access arguments' => array(
'administer nodes',
),
'file' => 'node.admin.inc',
);
$items['admin/content/node/overview'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/content/node-settings'] = array(
'title' => 'Post settings',
'description' => 'Control posting behavior, such as teaser length, requiring previews before posting, and the number of posts on the front page.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_configure',
),
'access arguments' => array(
'administer nodes',
),
'file' => 'node.admin.inc',
);
$items['admin/content/node-settings/rebuild'] = array(
'title' => 'Rebuild permissions',
'page arguments' => array(
'node_configure_rebuild_confirm',
),
'file' => 'node.admin.inc',
'access arguments' => array(
'access administration pages',
),
'type' => MENU_CALLBACK,
);
$items['admin/content/types'] = array(
'title' => 'Content types',
'description' => 'Manage posts by content type, including default status, front page promotion, etc.',
'page callback' => 'node_overview_types',
'access arguments' => array(
'administer content types',
),
'file' => 'content_types.inc',
);
$items['admin/content/types/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/content/types/add'] = array(
'title' => 'Add content type',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_type_form',
),
'access arguments' => array(
'administer content types',
),
'file' => 'content_types.inc',
'type' => MENU_LOCAL_TASK,
);
$items['node'] = array(
'title' => 'Content',
'page callback' => 'node_page_default',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
$items['node/add'] = array(
'title' => 'Create content',
'page callback' => 'node_add_page',
'access callback' => '_node_add_access',
'weight' => 1,
'file' => 'node.pages.inc',
);
$items['rss.xml'] = array(
'title' => 'RSS feed',
'page callback' => 'node_feed',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
foreach (node_get_types('types', NULL, TRUE) as $type) {
$type_url_str = str_replace('_', '-', $type->type);
$items['node/add/' . $type_url_str] = array(
'title' => drupal_ucfirst($type->name),
'title callback' => 'check_plain',
'page callback' => 'node_add',
'page arguments' => array(
2,
),
'access callback' => 'node_access',
'access arguments' => array(
'create',
$type->type,
),
'description' => $type->description,
'file' => 'node.pages.inc',
);
$items['admin/content/node-type/' . $type_url_str] = array(
'title' => $type->name,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_type_form',
$type,
),
'access arguments' => array(
'administer content types',
),
'file' => 'content_types.inc',
'type' => MENU_CALLBACK,
);
$items['admin/content/node-type/' . $type_url_str . '/edit'] = array(
'title' => 'Edit',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/content/node-type/' . $type_url_str . '/delete'] = array(
'title' => 'Delete',
'page arguments' => array(
'node_type_delete_confirm',
$type,
),
'access arguments' => array(
'administer content types',
),
'file' => 'content_types.inc',
'type' => MENU_CALLBACK,
);
}
$items['node/%node'] = array(
'title callback' => 'node_page_title',
'title arguments' => array(
1,
),
'page callback' => 'node_page_view',
'page arguments' => array(
1,
),
'access callback' => 'node_access',
'access arguments' => array(
'view',
1,
),
'type' => MENU_CALLBACK,
);
$items['node/%node/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['node/%node/edit'] = array(
'title' => 'Edit',
'page callback' => 'node_page_edit',
'page arguments' => array(
1,
),
'access callback' => 'node_access',
'access arguments' => array(
'update',
1,
),
'weight' => 1,
'file' => 'node.pages.inc',
'type' => MENU_LOCAL_TASK,
);
$items['node/%node/delete'] = array(
'title' => 'Delete',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_delete_confirm',
1,
),
'access callback' => 'node_access',
'access arguments' => array(
'delete',
1,
),
'file' => 'node.pages.inc',
'weight' => 1,
'type' => MENU_CALLBACK,
);
$items['node/%node/revisions'] = array(
'title' => 'Revisions',
'page callback' => 'node_revision_overview',
'page arguments' => array(
1,
),
'access callback' => '_node_revision_access',
'access arguments' => array(
1,
),
'weight' => 2,
'file' => 'node.pages.inc',
'type' => MENU_LOCAL_TASK,
);
$items['node/%node/revisions/%/view'] = array(
'title' => 'Revisions',
'load arguments' => array(
3,
),
'page callback' => 'node_show',
'page arguments' => array(
1,
NULL,
TRUE,
),
'access callback' => '_node_revision_access',
'access arguments' => array(
1,
),
'type' => MENU_CALLBACK,
);
$items['node/%node/revisions/%/revert'] = array(
'title' => 'Revert to earlier revision',
'load arguments' => array(
3,
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_revision_revert_confirm',
1,
),
'access callback' => '_node_revision_access',
'access arguments' => array(
1,
'update',
),
'file' => 'node.pages.inc',
'type' => MENU_CALLBACK,
);
$items['node/%node/revisions/%/delete'] = array(
'title' => 'Delete earlier revision',
'load arguments' => array(
3,
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_revision_delete_confirm',
1,
),
'access callback' => '_node_revision_access',
'access arguments' => array(
1,
'delete',
),
'file' => 'node.pages.inc',
'type' => MENU_CALLBACK,
);
return $items;
}
function node_page_title($node) {
return $node->title;
}
function node_init() {
drupal_add_css(drupal_get_path('module', 'node') . '/node.css');
}
function node_last_changed($nid) {
$node = db_fetch_object(db_query('SELECT changed FROM {node} WHERE nid = %d', $nid));
return $node->changed;
}
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.vid DESC', $node->nid);
while ($revision = db_fetch_object($result)) {
$revisions[$revision->vid] = $revision;
}
return $revisions;
}
function node_block($op = 'list', $delta = 0) {
if ($op == 'list') {
$blocks[0]['info'] = t('Syndicate');
$blocks[0]['cache'] = BLOCK_NO_CACHE;
return $blocks;
}
else {
if ($op == 'view') {
$block['subject'] = t('Syndicate');
$block['content'] = theme('feed_icon', url('rss.xml'), t('Syndicate'));
return $block;
}
}
}
function node_feed($nids = FALSE, $channel = array()) {
global $base_url, $language;
if ($nids === FALSE) {
$nids = array();
$result = 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));
while ($row = db_fetch_object($result)) {
$nids[] = $row->nid;
}
}
$item_length = variable_get('feed_item_length', 'teaser');
$namespaces = array(
'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
);
$items = '';
foreach ($nids as $nid) {
$item = node_load($nid);
$item->build_mode = NODE_BUILD_RSS;
$item->link = url("node/{$nid}", array(
'absolute' => TRUE,
));
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);
$content = drupal_render($item->content);
if ($teaser) {
$item->teaser = $content;
unset($item->body);
}
else {
$item->body = $content;
unset($item->teaser);
}
node_invoke_nodeapi($item, 'alter', $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 (isset($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 (!empty($item->readmore)) {
$item_text .= '<p>' . l(t('read more'), 'node/' . $item->nid, array(
'absolute' => TRUE,
'attributes' => array(
'target' => '_blank',
),
)) . '</p>';
}
break;
case 'title':
$item_text = '';
break;
}
$items .= format_rss_item($item->title, $item->link, $item_text, $extra);
}
$channel_defaults = array(
'version' => '2.0',
'title' => variable_get('site_name', 'Drupal'),
'link' => $base_url,
'description' => variable_get('site_mission', ''),
'language' => $language->language,
);
$channel = array_merge($channel_defaults, $channel);
$output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$output .= "<rss version=\"" . $channel["version"] . "\" xml:base=\"" . $base_url . "\" " . drupal_attributes($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_page_default() {
$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));
$output = '';
$num_rows = FALSE;
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load($node->nid), 1);
$num_rows = TRUE;
}
if ($num_rows) {
$feed_url = url('rss.xml', array(
'absolute' => TRUE,
));
drupal_add_feed($feed_url, variable_get('site_name', 'Drupal') . ' ' . t('RSS'));
$output .= theme('pager', NULL, variable_get('default_nodes_main', 10));
}
else {
$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>';
$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_update_index() {
$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 n.nid FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, n.nid ASC", 0, $limit);
while ($node = db_fetch_object($result)) {
_node_index_node($node);
}
}
function _node_index_node($node) {
$node = node_load($node->nid);
variable_set('node_cron_last', $node->changed);
$node->build_mode = NODE_BUILD_SEARCH_INDEX;
$node = node_build_content($node, FALSE, FALSE);
$node->body = drupal_render($node->content);
$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, $form_state, $form_id) {
if ($form_id == 'search_form' && $form['module']['#value'] == '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';
}
}
function node_search_validate($form, &$form_state) {
$keys = $form_state['values']['processed_keys'];
if (isset($form_state['values']['type']) && is_array($form_state['values']['type'])) {
$form_state['values']['type'] = array_filter($form_state['values']['type']);
if (count($form_state['values']['type'])) {
$keys = search_query_insert($keys, 'type', implode(',', array_keys($form_state['values']['type'])));
}
}
if (isset($form_state['values']['category']) && is_array($form_state['values']['category'])) {
$keys = search_query_insert($keys, 'category', implode(',', $form_state['values']['category']));
}
if ($form_state['values']['or'] != '') {
if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' ' . $form_state['values']['or'], $matches)) {
$keys .= ' ' . implode(' OR ', $matches[1]);
}
}
if ($form_state['values']['negative'] != '') {
if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' ' . $form_state['values']['negative'], $matches)) {
$keys .= ' -' . implode(' -', $matches[1]);
}
}
if ($form_state['values']['phrase'] != '') {
$keys .= ' "' . str_replace('"', ' ', $form_state['values']['phrase']) . '"';
}
if (!empty($keys)) {
form_set_value($form['basic']['inline']['processed_keys'], trim($keys), $form_state);
}
}
function node_access($op, $node, $account = NULL) {
global $user;
if (!$node || !in_array($op, array(
'view',
'update',
'delete',
'create',
), TRUE)) {
return FALSE;
}
if ($op != 'create') {
$node = (object) $node;
}
if (empty($account)) {
$account = $user;
}
if ($op == 'update' && !filter_access($node->format)) {
return FALSE;
}
if (user_access('administer nodes', $account)) {
return TRUE;
}
if (!user_access('access content', $account)) {
return FALSE;
}
$module = node_get_types('module', $node);
if ($module == 'node') {
$module = 'node_content';
}
$access = module_invoke($module, 'access', $op, $node, $account);
if (!is_null($access)) {
return $access;
}
if ($op != 'create' && $node->nid && $node->status) {
$grants = array();
foreach (node_access_grants($op, $account) 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 1 FROM {node_access} WHERE (nid = 0 OR nid = %d) {$grants_sql} AND grant_{$op} >= 1";
$result = db_query_range($sql, $node->nid, 0, 1);
return (bool) db_result($result);
}
if ($op == 'view' && $account->uid == $node->uid && $account->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', $account = NULL) {
if (user_access('administer nodes')) {
return;
}
$grants = array();
foreach (node_access_grants($op, $account) 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, $account = NULL) {
if (!isset($account)) {
$account = $GLOBALS['user'];
}
return array_merge(array(
'all' => array(
0,
),
), module_invoke_all('node_grants', $account, $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 (empty($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_needs_rebuild($rebuild = NULL) {
if (!isset($rebuild)) {
return variable_get('node_access_needs_rebuild', FALSE);
}
elseif ($rebuild) {
variable_set('node_access_needs_rebuild', TRUE);
}
else {
variable_del('node_access_needs_rebuild');
}
}
function node_access_rebuild($batch_mode = FALSE) {
db_query("DELETE FROM {node_access}");
if (count(module_implements('node_grants'))) {
if ($batch_mode) {
$batch = array(
'title' => t('Rebuilding content access permissions'),
'operations' => array(
array(
'_node_access_rebuild_batch_operation',
array(),
),
),
'finished' => '_node_access_rebuild_batch_finished',
);
batch_set($batch);
}
else {
if (function_exists('set_time_limit')) {
@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)");
}
if (!isset($batch)) {
drupal_set_message(t('Content permissions have been rebuilt.'));
node_access_needs_rebuild(FALSE);
cache_clear_all();
}
}
function _node_access_rebuild_batch_operation(&$context) {
if (empty($context['sandbox'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_node'] = 0;
$context['sandbox']['max'] = db_result(db_query('SELECT COUNT(DISTINCT nid) FROM {node}'));
}
$limit = 20;
$result = db_query_range("SELECT nid FROM {node} WHERE nid > %d ORDER BY nid ASC", $context['sandbox']['current_node'], 0, $limit);
while ($row = db_fetch_array($result)) {
$loaded_node = node_load($row['nid'], NULL, TRUE);
if (!empty($loaded_node)) {
node_access_acquire_grants($loaded_node);
}
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $row['nid'];
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
function _node_access_rebuild_batch_finished($success, $results, $operations) {
if ($success) {
drupal_set_message(t('The content access permissions have been rebuilt.'));
node_access_needs_rebuild(FALSE);
}
else {
drupal_set_message(t('The content access permissions have not been properly rebuilt.'), 'error');
}
cache_clear_all();
}
function node_content_access($op, $node, $account) {
$type = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
if ($op == 'create') {
return user_access('create ' . $type . ' content', $account);
}
if ($op == 'update') {
if (user_access('edit any ' . $type . ' content', $account) || user_access('edit own ' . $type . ' content', $account) && $account->uid == $node->uid) {
return TRUE;
}
}
if ($op == 'delete') {
if (user_access('delete any ' . $type . ' content', $account) || user_access('delete own ' . $type . ' content', $account) && $account->uid == $node->uid) {
return TRUE;
}
}
}
function node_content_form($node, $form_state) {
$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,
'#maxlength' => 255,
'#weight' => -5,
);
}
if ($type->has_body) {
$form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count);
}
return $form;
}
function node_forms() {
$forms = array();
if ($types = node_get_types()) {
foreach (array_keys($types) as $type) {
$forms[$type . '_node_form']['callback'] = 'node_form';
}
}
return $forms;
}
function theme_node_submitted($node) {
return t('Submitted by !username on @datetime', array(
'!username' => theme('username', $node),
'@datetime' => format_date($node->created),
));
}
function node_hook_info() {
return array(
'node' => array(
'nodeapi' => array(
'presave' => array(
'runs when' => t('When either saving a new post or updating an existing post'),
),
'insert' => array(
'runs when' => t('After saving a new post'),
),
'update' => array(
'runs when' => t('After saving an updated post'),
),
'delete' => array(
'runs when' => t('After deleting a post'),
),
'view' => array(
'runs when' => t('When content is viewed by an authenticated user'),
),
),
),
);
}
function node_action_info() {
return array(
'node_publish_action' => array(
'type' => 'node',
'description' => t('Publish post'),
'configurable' => FALSE,
'behavior' => array(
'changes_node_property',
),
'hooks' => array(
'nodeapi' => array(
'presave',
),
'comment' => array(
'insert',
'update',
),
),
),
'node_unpublish_action' => array(
'type' => 'node',
'description' => t('Unpublish post'),
'configurable' => FALSE,
'behavior' => array(
'changes_node_property',
),
'hooks' => array(
'nodeapi' => array(
'presave',
),
'comment' => array(
'delete',
'insert',
'update',
),
),
),
'node_make_sticky_action' => array(
'type' => 'node',
'description' => t('Make post sticky'),
'configurable' => FALSE,
'behavior' => array(
'changes_node_property',
),
'hooks' => array(
'nodeapi' => array(
'presave',
),
'comment' => array(
'insert',
'update',
),
),
),
'node_make_unsticky_action' => array(
'type' => 'node',
'description' => t('Make post unsticky'),
'configurable' => FALSE,
'behavior' => array(
'changes_node_property',
),
'hooks' => array(
'nodeapi' => array(
'presave',
),
'comment' => array(
'delete',
'insert',
'update',
),
),
),
'node_promote_action' => array(
'type' => 'node',
'description' => t('Promote post to front page'),
'configurable' => FALSE,
'behavior' => array(
'changes_node_property',
),
'hooks' => array(
'nodeapi' => array(
'presave',
),
'comment' => array(
'insert',
'update',
),
),
),
'node_unpromote_action' => array(
'type' => 'node',
'description' => t('Remove post from front page'),
'configurable' => FALSE,
'behavior' => array(
'changes_node_property',
),
'hooks' => array(
'nodeapi' => array(
'presave',
),
'comment' => array(
'delete',
'insert',
'update',
),
),
),
'node_assign_owner_action' => array(
'type' => 'node',
'description' => t('Change the author of a post'),
'configurable' => TRUE,
'behavior' => array(
'changes_node_property',
),
'hooks' => array(
'any' => TRUE,
'nodeapi' => array(
'presave',
),
'comment' => array(
'delete',
'insert',
'update',
),
),
),
'node_save_action' => array(
'type' => 'node',
'description' => t('Save post'),
'configurable' => FALSE,
'hooks' => array(
'comment' => array(
'delete',
'insert',
'update',
),
),
),
'node_unpublish_by_keyword_action' => array(
'type' => 'node',
'description' => t('Unpublish post containing keyword(s)'),
'configurable' => TRUE,
'hooks' => array(
'nodeapi' => array(
'presave',
'insert',
'update',
),
),
),
);
}
function node_publish_action(&$node, $context = array()) {
$node->status = 1;
watchdog('action', 'Set @type %title to published.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
}
function node_unpublish_action(&$node, $context = array()) {
$node->status = 0;
watchdog('action', 'Set @type %title to unpublished.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
}
function node_make_sticky_action(&$node, $context = array()) {
$node->sticky = 1;
watchdog('action', 'Set @type %title to sticky.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
}
function node_make_unsticky_action(&$node, $context = array()) {
$node->sticky = 0;
watchdog('action', 'Set @type %title to unsticky.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
}
function node_promote_action(&$node, $context = array()) {
$node->promote = 1;
watchdog('action', 'Promoted @type %title to front page.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
}
function node_unpromote_action(&$node, $context = array()) {
$node->promote = 0;
watchdog('action', 'Removed @type %title from front page.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
}
function node_save_action($node) {
node_save($node);
watchdog('action', 'Saved @type %title', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
}
function node_assign_owner_action(&$node, $context) {
$node->uid = $context['owner_uid'];
$owner_name = db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $context['owner_uid']));
watchdog('action', 'Changed owner of @type %title to uid %name.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
'%name' => $owner_name,
));
}
function node_assign_owner_action_form($context) {
$description = t('The username of the user to which you would like to assign ownership.');
$count = db_result(db_query("SELECT COUNT(*) FROM {users}"));
$owner_name = '';
if (isset($context['owner_uid'])) {
$owner_name = db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $context['owner_uid']));
}
if (intval($count) < 200) {
$options = array();
$result = db_query("SELECT uid, name FROM {users} WHERE uid > 0 ORDER BY name");
while ($data = db_fetch_object($result)) {
$options[$data->name] = $data->name;
}
$form['owner_name'] = array(
'#type' => 'select',
'#title' => t('Username'),
'#default_value' => $owner_name,
'#options' => $options,
'#description' => $description,
);
}
else {
$form['owner_name'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#default_value' => $owner_name,
'#autocomplete_path' => 'user/autocomplete',
'#size' => '6',
'#maxlength' => '60',
'#description' => $description,
);
}
return $form;
}
function node_assign_owner_action_validate($form, $form_state) {
$count = db_result(db_query("SELECT COUNT(*) FROM {users} WHERE name = '%s'", $form_state['values']['owner_name']));
if (intval($count) != 1) {
form_set_error('owner_name', t('Please enter a valid username.'));
}
}
function node_assign_owner_action_submit($form, $form_state) {
$uid = db_result(db_query("SELECT uid from {users} WHERE name = '%s'", $form_state['values']['owner_name']));
return array(
'owner_uid' => $uid,
);
}
function node_unpublish_by_keyword_action_form($context) {
$form['keywords'] = array(
'#title' => t('Keywords'),
'#type' => 'textarea',
'#description' => t('The post will be unpublished if it contains any of the character sequences above. Use a comma-separated list of character sequences. Example: funny, bungee jumping, "Company, Inc.". Character sequences are case-sensitive.'),
'#default_value' => isset($context['keywords']) ? drupal_implode_tags($context['keywords']) : '',
);
return $form;
}
function node_unpublish_by_keyword_action_submit($form, $form_state) {
return array(
'keywords' => drupal_explode_tags($form_state['values']['keywords']),
);
}
function node_unpublish_by_keyword_action($node, $context) {
foreach ($context['keywords'] as $keyword) {
if (strstr(node_view(drupal_clone($node)), $keyword) || strstr($node->title, $keyword)) {
$node->status = 0;
watchdog('action', 'Set @type %title to unpublished.', array(
'@type' => node_get_types('name', $node),
'%title' => $node->title,
));
break;
}
}
}