View source
<?php
define('NODE_NOT_PUBLISHED', 0);
define('NODE_PUBLISHED', 1);
define('NODE_NOT_PROMOTED', 0);
define('NODE_PROMOTED', 1);
define('NODE_NOT_STICKY', 0);
define('NODE_STICKY', 1);
define('NODE_NEW_LIMIT', REQUEST_TIME - 30 * 24 * 60 * 60);
define('NODE_ACCESS_ALLOW', 'allow');
define('NODE_ACCESS_DENY', 'deny');
define('NODE_ACCESS_IGNORE', NULL);
function node_help($path, $arg) {
if ($path != 'admin/reports/status/rebuild' && $path != 'batch' && strpos($path, '#') === FALSE && user_access('access administration pages') && node_access_needs_rebuild()) {
if ($path == 'admin/reports/status') {
$message = t('The content access permissions need to be rebuilt.');
}
else {
$message = t('The content access permissions need to be rebuilt. <a href="@node_access_rebuild">Rebuild permissions</a>.', array(
'@node_access_rebuild' => url('admin/reports/status/rebuild'),
));
}
drupal_set_message($message, 'error');
}
switch ($path) {
case 'admin/help#node':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Node module manages the creation, editing, deletion, settings, and display of the main site content. Content items managed by the Node module are typically displayed as pages on your site, and include a title, some meta-data (author, creation time, content type, etc.), and optional fields containing text or other data (fields are managed by the <a href="@field">Field module</a>). For more information, see the online handbook entry for <a href="@node">Node module</a>.', array(
'@node' => 'http://drupal.org/documentation/modules/node',
'@field' => url('admin/help/field'),
)) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Creating content') . '</dt>';
$output .= '<dd>' . t('When new content is created, the Node module records basic information about the content, including the author, date of creation, and the <a href="@content-type">Content type</a>. It also manages the <em>publishing options</em>, which define whether or not the content is published, promoted to the front page of the site, and/or sticky at the top of content lists. Default settings can be configured for each <a href="@content-type">type of content</a> on your site.', array(
'@content-type' => url('admin/structure/types'),
)) . '</dd>';
$output .= '<dt>' . t('Creating custom content types') . '</dt>';
$output .= '<dd>' . t('The Node module gives users with the <em>Administer content types</em> permission the ability to <a href="@content-new">create new content types</a> in addition to the default ones already configured. Creating custom content types allows you the flexibility to add <a href="@field">fields</a> and configure default settings that suit the differing needs of various site content.', array(
'@content-new' => url('admin/structure/types/add'),
'@field' => url('admin/help/field'),
)) . '</dd>';
$output .= '<dt>' . t('Administering content') . '</dt>';
$output .= '<dd>' . t('The <a href="@content">Content administration page</a> allows you to review and bulk manage your site content.', array(
'@content' => url('admin/content'),
)) . '</dd>';
$output .= '<dt>' . t('Creating revisions') . '</dt>';
$output .= '<dd>' . t('The Node module also enables you to create multiple versions of any content, and revert to older versions using the <em>Revision information</em> settings.') . '</dd>';
$output .= '<dt>' . t('User permissions') . '</dt>';
$output .= '<dd>' . t('The Node module makes a number of permissions available for each content type, which can be set by role on the <a href="@permissions">permissions page</a>.', array(
'@permissions' => url('admin/people/permissions', array(
'fragment' => 'module-node',
)),
)) . '</dd>';
$output .= '</dl>';
return $output;
case 'admin/structure/types/add':
return '<p>' . t('Individual content types can have different fields, behaviors, and permissions assigned to them.') . '</p>';
case 'admin/structure/types/manage/%/display':
return '<p>' . t('Content items can be displayed using different view modes: Teaser, Full content, Print, RSS, etc. <em>Teaser</em> is a short format that is typically used in lists of multiple content items. <em>Full content</em> is typically used when the content is displayed on its own page.') . '</p>' . '<p>' . t('Here, you can define which fields are shown and hidden when %type content is displayed in each view mode, and define how the fields are displayed in each view mode.', array(
'%type' => node_type_get_name($arg[4]),
)) . '</p>';
case 'node/%/revisions':
return '<p>' . t('Revisions allow you to track differences between multiple versions of your content, and revert back to older versions.') . '</p>';
case 'node/%/edit':
$node = node_load($arg[1]);
$type = node_type_get_type($node);
return !empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '';
}
if ($arg[0] == 'node' && $arg[1] == 'add' && $arg[2]) {
$type = node_type_get_type(str_replace('-', '_', $arg[2]));
return !empty($type->help) ? '<p>' . filter_xss_admin($type->help) . '</p>' : '';
}
}
function node_theme() {
return array(
'node' => array(
'render element' => 'elements',
'template' => 'node',
),
'node_search_admin' => array(
'render element' => 'form',
),
'node_add_list' => array(
'variables' => array(
'content' => NULL,
),
'file' => 'node.pages.inc',
),
'node_preview' => array(
'variables' => array(
'node' => NULL,
),
'file' => 'node.pages.inc',
),
'node_admin_overview' => array(
'variables' => array(
'name' => NULL,
'type' => NULL,
),
'file' => 'content_types.inc',
),
'node_recent_block' => array(
'variables' => array(
'nodes' => NULL,
),
),
'node_recent_content' => array(
'variables' => array(
'node' => NULL,
),
),
);
}
function node_cron() {
db_delete('history')
->condition('timestamp', NODE_NEW_LIMIT, '<')
->execute();
}
function node_entity_info() {
$return = array(
'node' => array(
'label' => t('Node'),
'controller class' => 'NodeController',
'base table' => 'node',
'revision table' => 'node_revision',
'uri callback' => 'node_uri',
'fieldable' => TRUE,
'entity keys' => array(
'id' => 'nid',
'revision' => 'vid',
'bundle' => 'type',
'label' => 'title',
'language' => 'language',
),
'bundle keys' => array(
'bundle' => 'type',
),
'bundles' => array(),
'view modes' => array(
'full' => array(
'label' => t('Full content'),
'custom settings' => FALSE,
),
'teaser' => array(
'label' => t('Teaser'),
'custom settings' => TRUE,
),
'rss' => array(
'label' => t('RSS'),
'custom settings' => FALSE,
),
),
),
);
if (module_exists('search')) {
$return['node']['view modes'] += array(
'search_index' => array(
'label' => t('Search index'),
'custom settings' => FALSE,
),
'search_result' => array(
'label' => t('Search result highlighting input'),
'custom settings' => FALSE,
),
);
}
foreach (node_type_get_names() as $type => $name) {
$return['node']['bundles'][$type] = array(
'label' => $name,
'admin' => array(
'path' => 'admin/structure/types/manage/%node_type',
'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type),
'bundle argument' => 4,
'access arguments' => array(
'administer content types',
),
),
);
}
return $return;
}
function node_field_display_node_alter(&$display, $context) {
if ($context['view_mode'] == 'search_index') {
$display['label'] = 'hidden';
}
}
function node_uri($node) {
return array(
'path' => 'node/' . $node->nid,
);
}
function node_admin_paths() {
if (variable_get('node_admin_theme')) {
$paths = array(
'node/*/edit' => TRUE,
'node/*/delete' => TRUE,
'node/*/revisions' => TRUE,
'node/*/revisions/*/revert' => TRUE,
'node/*/revisions/*/delete' => TRUE,
'node/add' => TRUE,
'node/add/*' => TRUE,
);
return $paths;
}
}
function node_title_list($result, $title = NULL) {
$items = array();
$num_rows = FALSE;
foreach ($result as $node) {
$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 ? array(
'#theme' => 'item_list__node',
'#items' => $items,
'#title' => $title,
) : FALSE;
}
function node_tag_new($node) {
global $user;
if ($user->uid) {
db_merge('history')
->key(array(
'uid' => $user->uid,
'nid' => $node->nid,
))
->fields(array(
'timestamp' => REQUEST_TIME,
))
->execute();
}
}
function node_last_viewed($nid) {
global $user;
$history =& drupal_static(__FUNCTION__, array());
if (!isset($history[$nid])) {
$history[$nid] = db_query("SELECT timestamp FROM {history} WHERE uid = :uid AND nid = :nid", array(
':uid' => $user->uid,
':nid' => $nid,
))
->fetchObject();
}
return isset($history[$nid]->timestamp) ? $history[$nid]->timestamp : 0;
}
function node_mark($nid, $timestamp) {
global $user;
$cache =& drupal_static(__FUNCTION__, array());
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_extract_type($node) {
return is_object($node) ? $node->type : $node;
}
function node_type_get_types() {
return _node_types_build()->types;
}
function node_type_get_type($node) {
$type = _node_extract_type($node);
$types = _node_types_build()->types;
return isset($types[$type]) ? $types[$type] : FALSE;
}
function node_type_get_base($node) {
$type = _node_extract_type($node);
$types = _node_types_build()->types;
return isset($types[$type]) && isset($types[$type]->base) ? $types[$type]->base : FALSE;
}
function node_type_get_names() {
return _node_types_build()->names;
}
function node_type_get_name($node) {
$type = _node_extract_type($node);
$types = _node_types_build()->names;
return isset($types[$type]) ? $types[$type] : FALSE;
}
function node_types_rebuild() {
_node_types_build(TRUE);
}
function node_type_load($name) {
return node_type_get_type(strtr($name, array(
'-' => '_',
)));
}
function node_type_save($info) {
$existing_type = !empty($info->old_type) ? $info->old_type : $info->type;
$is_existing = (bool) db_query_range('SELECT 1 FROM {node_type} WHERE type = :type', 0, 1, array(
':type' => $existing_type,
))
->fetchField();
$type = node_type_set_defaults($info);
$fields = array(
'type' => (string) $type->type,
'name' => (string) $type->name,
'base' => (string) $type->base,
'has_title' => (int) $type->has_title,
'title_label' => (string) $type->title_label,
'description' => (string) $type->description,
'help' => (string) $type->help,
'custom' => (int) $type->custom,
'modified' => (int) $type->modified,
'locked' => (int) $type->locked,
'disabled' => (int) $type->disabled,
'module' => $type->module,
);
if ($is_existing) {
db_update('node_type')
->fields($fields)
->condition('type', $existing_type)
->execute();
if (!empty($type->old_type) && $type->old_type != $type->type) {
field_attach_rename_bundle('node', $type->old_type, $type->type);
}
module_invoke_all('node_type_update', $type);
$status = SAVED_UPDATED;
}
else {
$fields['orig_type'] = (string) $type->orig_type;
db_insert('node_type')
->fields($fields)
->execute();
field_attach_create_bundle('node', $type->type);
module_invoke_all('node_type_insert', $type);
$status = SAVED_NEW;
}
node_type_cache_reset();
return $status;
}
function node_add_body_field($type, $label = 'Body') {
$field = field_info_field('body');
$instance = field_info_instance('node', 'body', $type->type);
if (empty($field)) {
$field = array(
'field_name' => 'body',
'type' => 'text_with_summary',
'entity_types' => array(
'node',
),
);
$field = field_create_field($field);
}
if (empty($instance)) {
$instance = array(
'field_name' => 'body',
'entity_type' => 'node',
'bundle' => $type->type,
'label' => $label,
'widget' => array(
'type' => 'text_textarea_with_summary',
),
'settings' => array(
'display_summary' => TRUE,
),
'display' => array(
'default' => array(
'label' => 'hidden',
'type' => 'text_default',
),
'teaser' => array(
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
),
),
);
$instance = field_create_instance($instance);
}
return $instance;
}
function node_field_extra_fields() {
$extra = array();
foreach (node_type_get_types() as $type) {
if ($type->has_title) {
$extra['node'][$type->type] = array(
'form' => array(
'title' => array(
'label' => $type->title_label,
'description' => t('Node module element'),
'weight' => -5,
),
),
);
}
}
return $extra;
}
function node_type_delete($type) {
$info = node_type_get_type($type);
db_delete('node_type')
->condition('type', $type)
->execute();
field_attach_delete_bundle('node', $type);
module_invoke_all('node_type_delete', $info);
node_type_cache_reset();
}
function node_type_update_nodes($old_type, $type) {
return db_update('node')
->fields(array(
'type' => $type,
))
->condition('type', $old_type)
->execute();
}
function _node_types_build($rebuild = FALSE) {
$cid = 'node_types:' . $GLOBALS['language']->language;
if (!$rebuild) {
$_node_types =& drupal_static(__FUNCTION__);
if (isset($_node_types)) {
return $_node_types;
}
if ($cache = cache_get($cid)) {
$_node_types = $cache->data;
return $_node_types;
}
}
$_node_types = (object) array(
'types' => array(),
'names' => array(),
);
foreach (module_implements('node_info') as $module) {
$info_array = module_invoke($module, 'node_info');
foreach ($info_array as $type => $info) {
$info['type'] = $type;
$_node_types->types[$type] = node_type_set_defaults($info);
$_node_types->types[$type]->module = $module;
$_node_types->names[$type] = $info['name'];
}
}
$query = db_select('node_type', 'nt')
->addTag('translatable')
->addTag('node_type_access')
->fields('nt')
->orderBy('nt.type', 'ASC');
if (!$rebuild) {
$query
->condition('disabled', 0);
}
foreach ($query
->execute() as $type_object) {
$type_db = $type_object->type;
$disabled = $type_object->disabled;
if (isset($type_object->base) && $type_object->base != 'node_content' && empty($_node_types->types[$type_db])) {
$type_object->disabled = TRUE;
}
if (isset($_node_types->types[$type_db])) {
$type_object->disabled = FALSE;
}
if (!isset($_node_types->types[$type_db]) || $type_object->modified) {
$_node_types->types[$type_db] = $type_object;
$_node_types->names[$type_db] = $type_object->name;
if ($type_db != $type_object->orig_type) {
unset($_node_types->types[$type_object->orig_type]);
unset($_node_types->names[$type_object->orig_type]);
}
}
$_node_types->types[$type_db]->disabled = $type_object->disabled;
$_node_types->types[$type_db]->disabled_changed = $disabled != $type_object->disabled;
}
if ($rebuild) {
foreach ($_node_types->types as $type => $type_object) {
if (!empty($type_object->is_new) || !empty($type_object->disabled_changed)) {
node_type_save($type_object);
}
}
}
asort($_node_types->names);
cache_set($cid, $_node_types);
return $_node_types;
}
function node_type_cache_reset() {
cache_clear_all('node_types:', 'cache', TRUE);
drupal_static_reset('_node_types_build');
}
function node_type_set_defaults($info = array()) {
$info = (array) $info;
$new_type = $info + array(
'type' => '',
'name' => '',
'base' => '',
'description' => '',
'help' => '',
'custom' => 0,
'modified' => 0,
'locked' => 1,
'disabled' => 0,
'is_new' => 1,
'has_title' => 1,
'title_label' => 'Title',
);
$new_type = (object) $new_type;
if (!$new_type->has_title) {
$new_type->title_label = '';
}
if (empty($new_type->module)) {
$new_type->module = $new_type->base == 'node_content' ? 'node' : '';
}
$new_type->orig_type = isset($info['type']) ? $info['type'] : '';
return $new_type;
}
function node_rdf_mapping() {
return array(
array(
'type' => 'node',
'bundle' => RDF_DEFAULT_BUNDLE,
'mapping' => array(
'rdftype' => array(
'sioc:Item',
'foaf:Document',
),
'title' => array(
'predicates' => array(
'dc:title',
),
),
'created' => array(
'predicates' => array(
'dc:date',
'dc:created',
),
'datatype' => 'xsd:dateTime',
'callback' => 'date_iso8601',
),
'changed' => array(
'predicates' => array(
'dc:modified',
),
'datatype' => 'xsd:dateTime',
'callback' => 'date_iso8601',
),
'body' => array(
'predicates' => array(
'content:encoded',
),
),
'uid' => array(
'predicates' => array(
'sioc:has_creator',
),
'type' => 'rel',
),
'name' => array(
'predicates' => array(
'foaf:name',
),
),
'comment_count' => array(
'predicates' => array(
'sioc:num_replies',
),
'datatype' => 'xsd:integer',
),
'last_activity' => array(
'predicates' => array(
'sioc:last_activity_date',
),
'datatype' => 'xsd:dateTime',
'callback' => 'date_iso8601',
),
),
),
);
}
function node_hook($node, $hook) {
$base = node_type_get_base($node);
return module_hook($base, $hook);
}
function node_invoke($node, $hook, $a2 = NULL, $a3 = NULL, $a4 = NULL) {
if (node_hook($node, $hook)) {
$base = node_type_get_base($node);
$function = $base . '_' . $hook;
return $function($node, $a2, $a3, $a4);
}
}
function node_load_multiple($nids = array(), $conditions = array(), $reset = FALSE) {
return entity_load('node', $nids, $conditions, $reset);
}
function node_load($nid = NULL, $vid = NULL, $reset = FALSE) {
$nids = isset($nid) ? array(
$nid,
) : array();
$conditions = isset($vid) ? array(
'vid' => $vid,
) : array();
$node = node_load_multiple($nids, $conditions, $reset);
return $node ? reset($node) : FALSE;
}
function node_object_prepare($node) {
$node_options = variable_get('node_options_' . $node->type, array(
'status',
'promote',
));
if (!isset($node->nid) || isset($node->is_new)) {
foreach (array(
'status',
'promote',
'sticky',
) as $key) {
if (!isset($node->{$key})) {
$node->{$key} = (int) in_array($key, $node_options);
}
}
global $user;
$node->uid = $user->uid;
$node->created = REQUEST_TIME;
}
else {
$node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
$node->log = NULL;
}
$node->revision = in_array('revision', $node_options);
node_invoke($node, 'prepare');
module_invoke_all('node_prepare', $node);
}
function node_validate($node, $form, &$form_state) {
if (isset($node->nid) && node_last_changed($node->nid) > $node->changed) {
form_set_error('changed', t('The content on this page has either been modified by another user, or you have already submitted modifications using this form. As a result, your changes cannot be saved.'));
}
if (!empty($node->name) && !($account = user_load_by_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) === FALSE) {
form_set_error('date', t('You have to specify a valid date.'));
}
$function = node_type_get_base($node) . '_validate';
if (function_exists($function)) {
$function($node, $form, $form_state);
}
foreach (module_implements('node_validate') as $module) {
$function = $module . '_node_validate';
$function($node, $form, $form_state);
}
}
function node_submit($node) {
if (isset($node->name)) {
if ($account = user_load_by_name($node->name)) {
$node->uid = $account->uid;
}
else {
$node->uid = 0;
}
}
$node->created = !empty($node->date) ? strtotime($node->date) : REQUEST_TIME;
$node->validated = TRUE;
return $node;
}
function node_save($node) {
$transaction = db_transaction();
try {
if (!empty($node->nid) && !isset($node->original)) {
$node->original = entity_load_unchanged('node', $node->nid);
}
field_attach_presave('node', $node);
global $user;
if (!isset($node->is_new)) {
$node->is_new = empty($node->nid);
}
if (empty($node->created)) {
$node->created = REQUEST_TIME;
}
$node->changed = REQUEST_TIME;
$node->timestamp = REQUEST_TIME;
$update_node = TRUE;
module_invoke_all('node_presave', $node);
module_invoke_all('entity_presave', $node, 'node');
if ($node->is_new || !empty($node->revision)) {
if (!isset($node->log)) {
$node->log = '';
}
}
elseif (!isset($node->log) || $node->log === '') {
unset($node->log);
}
if (!$node->is_new && !empty($node->revision) && $node->vid) {
$node->old_vid = $node->vid;
unset($node->vid);
}
if ($node->is_new) {
drupal_write_record('node', $node);
_node_save_revision($node, $user->uid);
$op = 'insert';
}
else {
drupal_write_record('node', $node, 'nid');
if (!empty($node->revision)) {
_node_save_revision($node, $user->uid);
}
else {
_node_save_revision($node, $user->uid, 'vid');
$update_node = FALSE;
}
$op = 'update';
}
if ($update_node) {
db_update('node')
->fields(array(
'vid' => $node->vid,
))
->condition('nid', $node->nid)
->execute();
}
node_invoke($node, $op);
$function = "field_attach_{$op}";
$function('node', $node);
module_invoke_all('node_' . $op, $node);
module_invoke_all('entity_' . $op, $node, 'node');
node_access_acquire_grants($node);
unset($node->is_new);
unset($node->original);
entity_get_controller('node')
->resetCache(array(
$node->nid,
));
db_ignore_slave();
} catch (Exception $e) {
$transaction
->rollback();
watchdog_exception('node', $e);
throw $e;
}
}
function _node_save_revision($node, $uid, $update = NULL) {
$temp_uid = $node->uid;
$node->uid = $uid;
if (isset($update)) {
drupal_write_record('node_revision', $node, $update);
}
else {
drupal_write_record('node_revision', $node);
}
$node->uid = $temp_uid;
}
function node_delete($nid) {
node_delete_multiple(array(
$nid,
));
}
function node_delete_multiple($nids) {
$transaction = db_transaction();
if (!empty($nids)) {
$nodes = node_load_multiple($nids, array());
try {
foreach ($nodes as $nid => $node) {
node_invoke($node, 'delete');
module_invoke_all('node_delete', $node);
module_invoke_all('entity_delete', $node, 'node');
field_attach_delete('node', $node);
if (module_exists('search')) {
search_reindex($nid, 'node');
}
}
db_delete('node')
->condition('nid', $nids, 'IN')
->execute();
db_delete('node_revision')
->condition('nid', $nids, 'IN')
->execute();
db_delete('history')
->condition('nid', $nids, 'IN')
->execute();
db_delete('node_access')
->condition('nid', $nids, 'IN')
->execute();
} catch (Exception $e) {
$transaction
->rollback();
watchdog_exception('node', $e);
throw $e;
}
entity_get_controller('node')
->resetCache();
}
}
function node_revision_delete($revision_id) {
if ($revision = node_load(NULL, $revision_id)) {
$node = node_load($revision->nid);
if ($revision_id == $node->vid) {
return FALSE;
}
db_delete('node_revision')
->condition('nid', $revision->nid)
->condition('vid', $revision->vid)
->execute();
module_invoke_all('node_revision_delete', $revision);
field_attach_delete_revision('node', $revision);
return TRUE;
}
return FALSE;
}
function node_view($node, $view_mode = 'full', $langcode = NULL) {
if (!isset($langcode)) {
$langcode = $GLOBALS['language_content']->language;
}
node_build_content($node, $view_mode, $langcode);
$build = $node->content;
unset($node->content);
$build += array(
'#theme' => 'node',
'#node' => $node,
'#view_mode' => $view_mode,
'#language' => $langcode,
);
if (!empty($node->nid) && !($view_mode == 'full' && node_is_page($node))) {
$build['#contextual_links']['node'] = array(
'node',
array(
$node->nid,
),
);
}
$type = 'node';
drupal_alter(array(
'node_view',
'entity_view',
), $build, $type);
return $build;
}
function node_build_content($node, $view_mode = 'full', $langcode = NULL) {
if (!isset($langcode)) {
$langcode = $GLOBALS['language_content']->language;
}
$node->content = array();
$view_mode = key(entity_view_mode_prepare('node', array(
$node->nid => $node,
), $view_mode, $langcode));
if (node_hook($node, 'view')) {
$node = node_invoke($node, 'view', $view_mode, $langcode);
}
field_attach_prepare_view('node', array(
$node->nid => $node,
), $view_mode, $langcode);
entity_prepare_view('node', array(
$node->nid => $node,
), $langcode);
$node->content += field_attach_view('node', $node, $view_mode, $langcode);
$links = array();
$node->content['links'] = array(
'#theme' => 'links__node',
'#pre_render' => array(
'drupal_pre_render_links',
),
'#attributes' => array(
'class' => array(
'links',
'inline',
),
),
);
if ($view_mode == 'teaser') {
$node_title_stripped = strip_tags($node->title);
$links['node-readmore'] = array(
'title' => t('Read more<span class="element-invisible"> about @title</span>', array(
'@title' => $node_title_stripped,
)),
'href' => 'node/' . $node->nid,
'html' => TRUE,
'attributes' => array(
'rel' => 'tag',
'title' => $node_title_stripped,
),
);
}
$node->content['links']['node'] = array(
'#theme' => 'links__node__node',
'#links' => $links,
'#attributes' => array(
'class' => array(
'links',
'inline',
),
),
);
module_invoke_all('node_view', $node, $view_mode, $langcode);
module_invoke_all('entity_view', $node, 'node', $view_mode, $langcode);
$node->content += array(
'#view_mode' => $view_mode,
);
}
function node_show($node, $message = FALSE) {
if ($message) {
drupal_set_title(t('Revision of %title from %date', array(
'%title' => $node->title,
'%date' => format_date($node->revision_timestamp),
)), PASS_THROUGH);
}
$nodes = node_view_multiple(array(
$node->nid => $node,
), 'full');
node_tag_new($node);
return $nodes;
}
function node_is_page($node) {
$page_node = menu_get_object();
return !empty($page_node) ? $page_node->nid == $node->nid : FALSE;
}
function template_preprocess_node(&$variables) {
$variables['view_mode'] = $variables['elements']['#view_mode'];
$variables['teaser'] = $variables['view_mode'] == 'teaser';
$variables['node'] = $variables['elements']['#node'];
$node = $variables['node'];
$variables['date'] = format_date($node->created);
$variables['name'] = theme('username', array(
'account' => $node,
));
$uri = entity_uri('node', $node);
$variables['node_url'] = url($uri['path'], $uri['options']);
$variables['title'] = check_plain($node->title);
$variables['page'] = $variables['view_mode'] == 'full' && node_is_page($node);
$variables = array_merge((array) $node, $variables);
$variables += array(
'content' => array(),
);
foreach (element_children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
field_attach_preprocess('node', $node, $variables['content'], $variables);
if (variable_get('node_submitted_' . $node->type, TRUE)) {
$variables['display_submitted'] = TRUE;
$variables['submitted'] = t('Submitted by !username on !datetime', array(
'!username' => $variables['name'],
'!datetime' => $variables['date'],
));
$variables['user_picture'] = theme_get_setting('toggle_node_user_picture') ? theme('user_picture', array(
'account' => $node,
)) : '';
}
else {
$variables['display_submitted'] = FALSE;
$variables['submitted'] = '';
$variables['user_picture'] = '';
}
$variables['classes_array'][] = drupal_html_class('node-' . $node->type);
if ($variables['promote']) {
$variables['classes_array'][] = 'node-promoted';
}
if ($variables['sticky']) {
$variables['classes_array'][] = 'node-sticky';
}
if (!$variables['status']) {
$variables['classes_array'][] = 'node-unpublished';
}
if ($variables['teaser']) {
$variables['classes_array'][] = 'node-teaser';
}
if (isset($variables['preview'])) {
$variables['classes_array'][] = 'node-preview';
}
$variables['theme_hook_suggestions'][] = 'node__' . $node->type;
$variables['theme_hook_suggestions'][] = 'node__' . $node->nid;
}
function node_permission() {
$perms = array(
'bypass node access' => array(
'title' => t('Bypass content access control'),
'description' => t('View, edit and delete all content regardless of permission restrictions.'),
'restrict access' => TRUE,
),
'administer content types' => array(
'title' => t('Administer content types'),
'restrict access' => TRUE,
),
'administer nodes' => array(
'title' => t('Administer content'),
'restrict access' => TRUE,
),
'access content overview' => array(
'title' => t('Access the content overview page'),
'description' => t('Get an overview of <a href="@url">all content</a>.', array(
'@url' => url('admin/content'),
)),
),
'access content' => array(
'title' => t('View published content'),
),
'view own unpublished content' => array(
'title' => t('View own unpublished content'),
),
'view revisions' => array(
'title' => t('View content revisions'),
),
'revert revisions' => array(
'title' => t('Revert content revisions'),
),
'delete revisions' => array(
'title' => t('Delete content revisions'),
),
);
foreach (node_permissions_get_configured_types() as $type) {
$perms += node_list_permissions($type);
}
return $perms;
}
function _node_rankings(SelectQueryExtender $query) {
if ($ranking = module_invoke_all('ranking')) {
$tables =& $query
->getTables();
foreach ($ranking as $rank => $values) {
if ($node_rank = variable_get('node_rank_' . $rank, 0)) {
if (isset($values['join']) && !isset($tables[$values['join']['alias']])) {
$query
->addJoin($values['join']['type'], $values['join']['table'], $values['join']['alias'], $values['join']['on']);
}
$arguments = isset($values['arguments']) ? $values['arguments'] : array();
$query
->addScore($values['score'], $arguments, $node_rank);
}
}
}
}
function node_search_info() {
return array(
'title' => 'Content',
'path' => 'node',
);
}
function node_search_access() {
return user_access('access content');
}
function node_search_reset() {
db_update('search_dataset')
->fields(array(
'reindex' => REQUEST_TIME,
))
->condition('type', 'node')
->execute();
}
function node_search_status() {
$total = db_query('SELECT COUNT(*) FROM {node}')
->fetchField();
$remaining = db_query("SELECT COUNT(*) 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")
->fetchField();
return array(
'remaining' => $remaining,
'total' => $total,
);
}
function node_search_admin() {
$form['content_ranking'] = array(
'#type' => 'fieldset',
'#title' => t('Content ranking'),
);
$form['content_ranking']['#theme'] = 'node_search_admin';
$form['content_ranking']['info'] = array(
'#markup' => '<p><em>' . t('Influence is a numeric multiplier used in ordering search results. A higher number means the corresponding factor has more influence on search results; zero means the factor is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '</em></p>',
);
$options = drupal_map_assoc(range(0, 10));
foreach (module_invoke_all('ranking') as $var => $values) {
$form['content_ranking']['factors']['node_rank_' . $var] = array(
'#title' => $values['title'],
'#type' => 'select',
'#options' => $options,
'#default_value' => variable_get('node_rank_' . $var, 0),
);
}
return $form;
}
function node_search_execute($keys = NULL, $conditions = NULL) {
$query = db_select('search_index', 'i', array(
'target' => 'slave',
))
->extend('SearchQuery')
->extend('PagerDefault');
$query
->join('node', 'n', 'n.nid = i.sid');
$query
->condition('n.status', 1)
->addTag('node_access')
->searchExpression($keys, 'node');
$query
->setOption('type', 'n.type');
$query
->setOption('language', 'n.language');
if ($query
->setOption('term', 'ti.tid')) {
$query
->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
}
if (!$query
->executeFirstPass()) {
return array();
}
_node_rankings($query);
$find = $query
->limit(10)
->execute();
$results = array();
foreach ($find as $item) {
$node = node_load($item->sid);
$build = node_view($node, 'search_result');
unset($build['#theme']);
$node->rendered = drupal_render($build);
$node->rendered .= ' ' . module_invoke('comment', 'node_update_index', $node);
$extra = module_invoke_all('node_search_result', $node);
$uri = entity_uri('node', $node);
$results[] = array(
'link' => url($uri['path'], array_merge($uri['options'], array(
'absolute' => TRUE,
))),
'type' => check_plain(node_type_get_name($node)),
'title' => $node->title,
'user' => theme('username', array(
'account' => $node,
)),
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
'score' => $item->calculated_score,
'snippet' => search_excerpt($keys, $node->rendered),
'language' => entity_language('node', $node),
);
}
return $results;
}
function node_ranking() {
$ranking = array(
'relevance' => array(
'title' => t('Keyword relevance'),
'score' => 'i.relevance',
),
'sticky' => array(
'title' => t('Content is sticky at top of lists'),
'score' => 'n.sticky',
),
'promote' => array(
'title' => t('Content is promoted to the front page'),
'score' => 'n.promote',
),
);
if ($node_cron_last = variable_get('node_cron_last', 0)) {
$ranking['recent'] = array(
'title' => t('Recently posted'),
'score' => 'POW(2.0, (GREATEST(n.created, n.changed) - :node_cron_last) * 6.43e-8)',
'arguments' => array(
':node_cron_last' => $node_cron_last,
),
);
}
return $ranking;
}
function node_user_cancel($edit, $account, $method) {
switch ($method) {
case 'user_cancel_block_unpublish':
module_load_include('inc', 'node', 'node.admin');
$nodes = db_select('node', 'n')
->fields('n', array(
'nid',
))
->condition('uid', $account->uid)
->execute()
->fetchCol();
node_mass_update($nodes, array(
'status' => 0,
));
break;
case 'user_cancel_reassign':
module_load_include('inc', 'node', 'node.admin');
$nodes = db_select('node', 'n')
->fields('n', array(
'nid',
))
->condition('uid', $account->uid)
->execute()
->fetchCol();
node_mass_update($nodes, array(
'uid' => 0,
));
db_update('node_revision')
->fields(array(
'uid' => 0,
))
->condition('uid', $account->uid)
->execute();
db_delete('history')
->condition('uid', $account->uid)
->execute();
break;
}
}
function node_user_delete($account) {
$nodes = db_select('node', 'n')
->fields('n', array(
'nid',
))
->condition('uid', $account->uid)
->execute()
->fetchCol();
node_delete_multiple($nodes);
$revisions = db_query('SELECT vid FROM {node_revision} WHERE uid = :uid', array(
':uid' => $account->uid,
))
->fetchCol();
foreach ($revisions as $revision) {
node_revision_delete($revision);
}
db_delete('history')
->condition('uid', $account->uid)
->execute();
}
function theme_node_search_admin($variables) {
$form = $variables['form'];
$output = drupal_render($form['info']);
$header = array(
t('Factor'),
t('Influence'),
);
foreach (element_children($form['factors']) as $key) {
$row = array();
$row[] = $form['factors'][$key]['#title'];
$form['factors'][$key]['#title_display'] = 'invisible';
$row[] = drupal_render($form['factors'][$key]);
$rows[] = $row;
}
$output .= theme('table', array(
'header' => $header,
'rows' => $rows,
));
$output .= drupal_render_children($form);
return $output;
}
function _node_revision_access($node, $op = 'view', $account = NULL) {
$access =& drupal_static(__FUNCTION__, array());
$map = array(
'view' => 'view revisions',
'update' => 'revert revisions',
'delete' => 'delete revisions',
);
if (!$node || !isset($map[$op])) {
return FALSE;
}
if (!isset($account)) {
$account = $GLOBALS['user'];
}
$cid = $node->vid . ':' . $account->uid . ':' . $op;
if (!isset($access[$cid])) {
if (!user_access($map[$op], $account) && !user_access('administer nodes', $account)) {
return $access[$cid] = FALSE;
}
$node_current_revision = node_load($node->nid);
$is_current_revision = $node_current_revision->vid == $node->vid;
if ($is_current_revision && (db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid', array(
':nid' => $node->nid,
))
->fetchField() == 1 || $op == 'update' || $op == 'delete')) {
$access[$cid] = FALSE;
}
elseif (user_access('administer nodes', $account)) {
$access[$cid] = TRUE;
}
else {
$access[$cid] = node_access($op, $node_current_revision, $account) && ($is_current_revision || node_access($op, $node, $account));
}
}
return $access[$cid];
}
function _node_add_access() {
$types = node_type_get_types();
foreach ($types as $type) {
if (node_hook($type->type, 'form') && node_access('create', $type->type)) {
return TRUE;
}
}
if (user_access('administer content types')) {
return TRUE;
}
return FALSE;
}
function node_menu() {
$items['admin/content'] = array(
'title' => 'Content',
'description' => 'Find and manage content.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_admin_content',
),
'access arguments' => array(
'access content overview',
),
'weight' => -10,
'file' => 'node.admin.inc',
);
$items['admin/content/node'] = array(
'title' => 'Content',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/reports/status/rebuild'] = array(
'title' => 'Rebuild permissions',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_configure_rebuild_confirm',
),
'access arguments' => array(
'access administration pages',
),
'type' => MENU_CALLBACK,
'file' => 'node.admin.inc',
);
$items['admin/structure/types'] = array(
'title' => 'Content types',
'description' => 'Manage content types, including default status, front page promotion, comment settings, etc.',
'page callback' => 'node_overview_types',
'access arguments' => array(
'administer content types',
),
'file' => 'content_types.inc',
);
$items['admin/structure/types/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/types/add'] = array(
'title' => 'Add content type',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_type_form',
),
'access arguments' => array(
'administer content types',
),
'type' => MENU_LOCAL_ACTION,
'file' => 'content_types.inc',
);
$items['admin/structure/types/manage/%node_type'] = array(
'title' => 'Edit content type',
'title callback' => 'node_type_page_title',
'title arguments' => array(
4,
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'node_type_form',
4,
),
'access arguments' => array(
'administer content types',
),
'file' => 'content_types.inc',
);
$items['admin/structure/types/manage/%node_type/edit'] = array(
'title' => 'Edit',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/structure/types/manage/%node_type/delete'] = array(
'title' => 'Delete',
'page arguments' => array(
'node_type_delete_confirm',
4,
),
'access arguments' => array(
'administer content types',
),
'file' => 'content_types.inc',
);
$items['node'] = array(
'page callback' => 'node_page_default',
'access arguments' => array(
'access content',
),
'menu_name' => 'navigation',
'type' => MENU_CALLBACK,
);
$items['node/add'] = array(
'title' => 'Add content',
'page callback' => 'node_add_page',
'access callback' => '_node_add_access',
'file' => 'node.pages.inc',
);
$items['rss.xml'] = array(
'title' => 'RSS feed',
'page callback' => 'node_feed',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
'page arguments' => array(
FALSE,
array(),
),
);
node_type_cache_reset();
foreach (node_type_get_types() as $type) {
$type_url_str = str_replace('_', '-', $type->type);
$items['node/add/' . $type_url_str] = array(
'title' => $type->name,
'title callback' => 'check_plain',
'page callback' => 'node_add',
'page arguments' => array(
$type->type,
),
'access callback' => 'node_access',
'access arguments' => array(
'create',
$type->type,
),
'description' => $type->description,
'file' => 'node.pages.inc',
);
}
$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,
),
);
$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' => 0,
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
'file' => 'node.pages.inc',
);
$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,
),
'weight' => 1,
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_INLINE,
'file' => 'node.pages.inc',
);
$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,
'type' => MENU_LOCAL_TASK,
'file' => 'node.pages.inc',
);
$items['node/%node/revisions/%/view'] = array(
'title' => 'Revisions',
'load arguments' => array(
3,
),
'page callback' => 'node_show',
'page arguments' => array(
1,
TRUE,
),
'access callback' => '_node_revision_access',
'access arguments' => array(
1,
),
);
$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',
);
$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',
);
return $items;
}
function node_menu_local_tasks_alter(&$data, $router_item, $root_path) {
if ($root_path == 'admin/content') {
$item = menu_get_item('node/add');
if ($item['access']) {
$data['actions']['output'][] = array(
'#theme' => 'menu_local_action',
'#link' => $item,
);
}
}
}
function node_type_page_title($type) {
return $type->name;
}
function node_page_title($node) {
return $node->title;
}
function node_last_changed($nid) {
return db_query('SELECT changed FROM {node} WHERE nid = :nid', array(
':nid' => $nid,
))
->fetch()->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_revision} r LEFT JOIN {node} n ON n.vid = r.vid INNER JOIN {users} u ON u.uid = r.uid WHERE r.nid = :nid ORDER BY r.vid DESC', array(
':nid' => $node->nid,
));
foreach ($result as $revision) {
$revisions[$revision->vid] = $revision;
}
return $revisions;
}
function node_block_info() {
$blocks['syndicate']['info'] = t('Syndicate');
$blocks['syndicate']['cache'] = DRUPAL_NO_CACHE;
$blocks['recent']['info'] = t('Recent content');
$blocks['recent']['properties']['administrative'] = TRUE;
return $blocks;
}
function node_block_view($delta = '') {
$block = array();
switch ($delta) {
case 'syndicate':
$block['subject'] = t('Syndicate');
$block['content'] = theme('feed_icon', array(
'url' => 'rss.xml',
'title' => t('Syndicate'),
));
break;
case 'recent':
if (user_access('access content')) {
$block['subject'] = t('Recent content');
if ($nodes = node_get_recent(variable_get('node_recent_block_count', 10))) {
$block['content'] = theme('node_recent_block', array(
'nodes' => $nodes,
));
}
else {
$block['content'] = t('No content available.');
}
}
break;
}
return $block;
}
function node_block_configure($delta = '') {
$form = array();
if ($delta == 'recent') {
$form['node_recent_block_count'] = array(
'#type' => 'select',
'#title' => t('Number of recent content items to display'),
'#default_value' => variable_get('node_recent_block_count', 10),
'#options' => drupal_map_assoc(array(
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
25,
30,
)),
);
}
return $form;
}
function node_block_save($delta = '', $edit = array()) {
if ($delta == 'recent') {
variable_set('node_recent_block_count', $edit['node_recent_block_count']);
}
}
function node_get_recent($number = 10) {
$query = db_select('node', 'n');
if (!user_access('bypass node access')) {
if (user_access('view own unpublished content') && ($own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = :status', array(
':uid' => $GLOBALS['user']->uid,
':status' => NODE_NOT_PUBLISHED,
))
->fetchCol())) {
$query
->condition(db_or()
->condition('n.status', NODE_PUBLISHED)
->condition('n.nid', $own_unpublished, 'IN'));
}
else {
$query
->condition('n.status', NODE_PUBLISHED);
}
}
$nids = $query
->fields('n', array(
'nid',
))
->orderBy('n.changed', 'DESC')
->range(0, $number)
->addTag('node_access')
->execute()
->fetchCol();
$nodes = node_load_multiple($nids);
return $nodes ? $nodes : array();
}
function theme_node_recent_block($variables) {
$rows = array();
$output = '';
$l_options = array(
'query' => drupal_get_destination(),
);
foreach ($variables['nodes'] as $node) {
$row = array();
$row[] = array(
'data' => theme('node_recent_content', array(
'node' => $node,
)),
'class' => 'title-author',
);
$row[] = array(
'data' => node_access('update', $node) ? l(t('edit'), 'node/' . $node->nid . '/edit', $l_options) : '',
'class' => 'edit',
);
$row[] = array(
'data' => node_access('delete', $node) ? l(t('delete'), 'node/' . $node->nid . '/delete', $l_options) : '',
'class' => 'delete',
);
$rows[] = $row;
}
if ($rows) {
$output = theme('table', array(
'rows' => $rows,
));
if (user_access('access content overview')) {
$output .= theme('more_link', array(
'url' => 'admin/content',
'title' => t('Show more content'),
));
}
}
return $output;
}
function theme_node_recent_content($variables) {
$node = $variables['node'];
$output = '<div class="node-title">';
$output .= l($node->title, 'node/' . $node->nid);
$output .= theme('mark', array(
'type' => node_mark($node->nid, $node->changed),
));
$output .= '</div><div class="node-author">';
$output .= theme('username', array(
'account' => user_load($node->uid),
));
$output .= '</div>';
return $output;
}
function node_form_block_add_block_form_alter(&$form, &$form_state) {
node_form_block_admin_configure_alter($form, $form_state);
}
function node_form_block_admin_configure_alter(&$form, &$form_state) {
$default_type_options = db_query("SELECT type FROM {block_node_type} WHERE module = :module AND delta = :delta", array(
':module' => $form['module']['#value'],
':delta' => $form['delta']['#value'],
))
->fetchCol();
$form['visibility']['node_type'] = array(
'#type' => 'fieldset',
'#title' => t('Content types'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'visibility',
'#weight' => 5,
);
$form['visibility']['node_type']['types'] = array(
'#type' => 'checkboxes',
'#title' => t('Show block for specific content types'),
'#default_value' => $default_type_options,
'#options' => node_type_get_names(),
'#description' => t('Show this block only on pages that display content of the given type(s). If you select no types, there will be no type-specific limitation.'),
);
$form['#submit'][] = 'node_form_block_admin_configure_submit';
}
function node_form_block_admin_configure_submit($form, &$form_state) {
db_delete('block_node_type')
->condition('module', $form_state['values']['module'])
->condition('delta', $form_state['values']['delta'])
->execute();
$query = db_insert('block_node_type')
->fields(array(
'type',
'module',
'delta',
));
foreach (array_filter($form_state['values']['types']) as $type) {
$query
->values(array(
'type' => $type,
'module' => $form_state['values']['module'],
'delta' => $form_state['values']['delta'],
));
}
$query
->execute();
}
function node_form_block_custom_block_delete_alter(&$form, &$form_state) {
$form['#submit'][] = 'node_form_block_custom_block_delete_submit';
}
function node_form_block_custom_block_delete_submit($form, &$form_state) {
db_delete('block_node_type')
->condition('module', 'block')
->condition('delta', $form_state['values']['bid'])
->execute();
}
function node_modules_uninstalled($modules) {
db_delete('block_node_type')
->condition('module', $modules, 'IN')
->execute();
}
function node_block_list_alter(&$blocks) {
global $theme_key;
$block_node_types = array();
$result = db_query('SELECT module, delta, type FROM {block_node_type}');
foreach ($result as $record) {
$block_node_types[$record->module][$record->delta][$record->type] = TRUE;
}
$node = menu_get_object();
$node_types = node_type_get_types();
if (arg(0) == 'node' && arg(1) == 'add' && arg(2)) {
$node_add_arg = strtr(arg(2), '-', '_');
}
foreach ($blocks as $key => $block) {
if (!isset($block->theme) || !isset($block->status) || $block->theme != $theme_key || $block->status != 1) {
continue;
}
if (isset($block_node_types[$block->module][$block->delta])) {
if (!empty($node)) {
if (!isset($block_node_types[$block->module][$block->delta][$node->type])) {
unset($blocks[$key]);
continue;
}
}
elseif (isset($node_add_arg) && isset($node_types[$node_add_arg])) {
if (!isset($block_node_types[$block->module][$block->delta][$node_add_arg])) {
unset($blocks[$key]);
continue;
}
}
else {
unset($blocks[$key]);
continue;
}
}
}
}
function node_feed($nids = FALSE, $channel = array()) {
global $base_url, $language_content;
if ($nids === FALSE) {
$nids = db_select('node', 'n')
->fields('n', array(
'nid',
'created',
))
->condition('n.promote', 1)
->condition('n.status', 1)
->orderBy('n.created', 'DESC')
->range(0, variable_get('feed_default_items', 10))
->addTag('node_access')
->execute()
->fetchCol();
}
$item_length = variable_get('feed_item_length', 'fulltext');
$namespaces = array(
'xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
);
$nodes = node_load_multiple($nids);
$items = '';
foreach ($nodes as $node) {
$item_text = '';
$node->link = url("node/{$node->nid}", array(
'absolute' => TRUE,
));
$node->rss_namespaces = array();
$account = user_load($node->uid);
$node->rss_elements = array(
array(
'key' => 'pubDate',
'value' => gmdate('r', $node->created),
),
array(
'key' => 'dc:creator',
'value' => format_username($account),
),
array(
'key' => 'guid',
'value' => $node->nid . ' at ' . $base_url,
'attributes' => array(
'isPermaLink' => 'false',
),
),
);
$build = node_view($node, 'rss');
unset($build['#theme']);
if (!empty($node->rss_namespaces)) {
$namespaces = array_merge($namespaces, $node->rss_namespaces);
}
if ($item_length != 'title') {
$build['links']['#weight'] = 1000;
$item_text .= drupal_render($build);
}
$items .= format_rss_item($node->title, $node->link, $item_text, $node->rss_elements);
}
$channel_defaults = array(
'version' => '2.0',
'title' => variable_get('site_name', 'Drupal'),
'link' => $base_url,
'description' => variable_get('feed_description', ''),
'language' => $language_content->language,
);
$channel_extras = array_diff_key($channel, $channel_defaults);
$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'], $channel_extras);
$output .= "</rss>\n";
drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
print $output;
}
function node_view_multiple($nodes, $view_mode = 'teaser', $weight = 0, $langcode = NULL) {
$build = array(
'nodes' => array(),
);
$entities_by_view_mode = entity_view_mode_prepare('node', $nodes, $view_mode, $langcode);
foreach ($entities_by_view_mode as $entity_view_mode => $entities) {
field_attach_prepare_view('node', $entities, $entity_view_mode, $langcode);
entity_prepare_view('node', $entities, $langcode);
foreach ($entities as $entity) {
$build['nodes'][$entity->nid] = node_view($entity, $entity_view_mode, $langcode);
}
}
foreach ($nodes as $node) {
$build['nodes'][$node->nid]['#weight'] = $weight;
$weight++;
}
uasort($build['nodes'], 'element_sort');
$build['nodes']['#sorted'] = TRUE;
return $build;
}
function node_page_default() {
$select = db_select('node', 'n')
->fields('n', array(
'nid',
'sticky',
'created',
))
->condition('n.promote', 1)
->condition('n.status', 1)
->orderBy('n.sticky', 'DESC')
->orderBy('n.created', 'DESC')
->extend('PagerDefault')
->limit(variable_get('default_nodes_main', 10))
->addTag('node_access');
$nids = $select
->execute()
->fetchCol();
if (!empty($nids)) {
$nodes = node_load_multiple($nids);
$build = node_view_multiple($nodes);
drupal_add_feed('rss.xml', variable_get('site_name', 'Drupal') . ' ' . t('RSS'));
$build['pager'] = array(
'#theme' => 'pager',
'#weight' => 5,
);
drupal_set_title('');
}
else {
drupal_set_title(t('Welcome to @site-name', array(
'@site-name' => variable_get('site_name', 'Drupal'),
)), PASS_THROUGH);
$default_message = '<p>' . t('No front page content has been created yet.') . '</p>';
$default_links = array();
if (_node_add_access()) {
$default_links[] = l(t('Add new content'), 'node/add');
}
if (!empty($default_links)) {
$default_message .= theme('item_list', array(
'items' => $default_links,
));
}
$build['default_message'] = array(
'#markup' => $default_message,
'#prefix' => '<div id="first-time">',
'#suffix' => '</div>',
);
}
return $build;
}
function node_page_view($node) {
drupal_set_title($node->title);
$uri = entity_uri('node', $node);
drupal_add_html_head_link(array(
'rel' => 'canonical',
'href' => url($uri['path'], $uri['options']),
), TRUE);
drupal_add_html_head_link(array(
'rel' => 'shortlink',
'href' => url($uri['path'], array_merge($uri['options'], array(
'alias' => TRUE,
))),
), TRUE);
return node_show($node);
}
function node_update_index() {
$limit = (int) variable_get('search_cron_limit', 100);
$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, array(), array(
'target' => 'slave',
));
foreach ($result as $node) {
_node_index_node($node);
}
}
function _node_index_node($node) {
$node = node_load($node->nid);
variable_set('node_cron_last', $node->changed);
$build = node_view($node, 'search_index');
unset($build['#theme']);
$node->rendered = drupal_render($build);
$text = '<h1>' . check_plain($node->title) . '</h1>' . $node->rendered;
$extra = module_invoke_all('node_update_index', $node);
foreach ($extra as $t) {
$text .= $t;
}
search_index($node->nid, 'node', $text);
}
function node_form_search_form_alter(&$form, $form_state) {
if (isset($form['module']) && $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' => array(
'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,
);
$types = array_map('check_plain', node_type_get_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>',
'#weight' => 100,
);
$language_options = array();
foreach (language_list('language') as $key => $entity) {
if ($entity->enabled) {
$language_options[$key] = $entity->name;
}
}
if (count($language_options) > 1) {
$form['advanced']['language'] = array(
'#type' => 'checkboxes',
'#title' => t('Languages'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $language_options,
);
}
$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_expression_insert($keys, 'type', implode(',', array_keys($form_state['values']['type'])));
}
}
if (isset($form_state['values']['term']) && is_array($form_state['values']['term']) && count($form_state['values']['term'])) {
$keys = search_expression_insert($keys, 'term', implode(',', $form_state['values']['term']));
}
if (isset($form_state['values']['language']) && is_array($form_state['values']['language'])) {
$languages = array_filter($form_state['values']['language']);
if (count($languages)) {
$keys = search_expression_insert($keys, 'language', implode(',', $languages));
}
}
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']['processed_keys'], trim($keys), $form_state);
}
}
function node_access($op, $node, $account = NULL) {
$rights =& drupal_static(__FUNCTION__, array());
if (!$node || !in_array($op, array(
'view',
'update',
'delete',
'create',
), TRUE)) {
return FALSE;
}
if (empty($account)) {
$account = $GLOBALS['user'];
}
$cid = is_object($node) ? $node->nid : $node;
if (isset($rights[$account->uid][$cid][$op])) {
return $rights[$account->uid][$cid][$op];
}
if (user_access('bypass node access', $account)) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
if (!user_access('access content', $account)) {
$rights[$account->uid][$cid][$op] = FALSE;
return FALSE;
}
$access = module_invoke_all('node_access', $node, $op, $account);
if (in_array(NODE_ACCESS_DENY, $access, TRUE)) {
$rights[$account->uid][$cid][$op] = FALSE;
return FALSE;
}
elseif (in_array(NODE_ACCESS_ALLOW, $access, TRUE)) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
if ($op == 'view' && !$node->status && user_access('view own unpublished content', $account) && $account->uid == $node->uid && $account->uid != 0) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
if ($op != 'create' && $node->nid) {
if (module_implements('node_grants')) {
$query = db_select('node_access');
$query
->addExpression('1');
$query
->condition('grant_' . $op, 1, '>=');
$nids = db_or()
->condition('nid', $node->nid);
if ($node->status) {
$nids
->condition('nid', 0);
}
$query
->condition($nids);
$query
->range(0, 1);
$grants = node_add_node_grants_to_query(node_access_grants($op, $account));
if (count($grants) > 0) {
$query
->condition($grants);
}
$result = (bool) $query
->execute()
->fetchField();
$rights[$account->uid][$cid][$op] = $result;
return $result;
}
elseif (is_object($node) && $op == 'view' && $node->status) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
}
return FALSE;
}
function node_add_node_grants_to_query($node_access_grants, $table_alias = '') {
$grants = db_or();
$prefix = $table_alias ? $table_alias . '.' : '';
foreach ($node_access_grants as $realm => $gids) {
if (!empty($gids)) {
$grants
->condition(db_and()
->condition($prefix . 'gid', $gids, 'IN')
->condition($prefix . 'realm', $realm));
}
}
return $grants;
}
function node_node_access($node, $op, $account) {
$type = is_string($node) ? $node : $node->type;
if (in_array($type, node_permissions_get_configured_types())) {
if ($op == 'create' && user_access('create ' . $type . ' content', $account)) {
return NODE_ACCESS_ALLOW;
}
if ($op == 'update') {
if (user_access('edit any ' . $type . ' content', $account) || user_access('edit own ' . $type . ' content', $account) && $account->uid == $node->uid) {
return NODE_ACCESS_ALLOW;
}
}
if ($op == 'delete') {
if (user_access('delete any ' . $type . ' content', $account) || user_access('delete own ' . $type . ' content', $account) && $account->uid == $node->uid) {
return NODE_ACCESS_ALLOW;
}
}
}
return NODE_ACCESS_IGNORE;
}
function node_list_permissions($type) {
$info = node_type_get_type($type);
$perms = array(
"create {$type} content" => array(
'title' => t('%type_name: Create new content', array(
'%type_name' => $info->name,
)),
),
"edit own {$type} content" => array(
'title' => t('%type_name: Edit own content', array(
'%type_name' => $info->name,
)),
),
"edit any {$type} content" => array(
'title' => t('%type_name: Edit any content', array(
'%type_name' => $info->name,
)),
),
"delete own {$type} content" => array(
'title' => t('%type_name: Delete own content', array(
'%type_name' => $info->name,
)),
),
"delete any {$type} content" => array(
'title' => t('%type_name: Delete any content', array(
'%type_name' => $info->name,
)),
),
);
return $perms;
}
function node_permissions_get_configured_types() {
$configured_types = array();
foreach (node_type_get_types() as $type => $info) {
if (variable_get('node_permissions_' . $type, 1)) {
$configured_types[] = $type;
}
}
return $configured_types;
}
function node_access_grants($op, $account = NULL) {
if (!isset($account)) {
$account = $GLOBALS['user'];
}
$grants = module_invoke_all('node_grants', $account, $op);
drupal_alter('node_grants', $grants, $account, $op);
return array_merge(array(
'all' => array(
0,
),
), $grants);
}
function node_access_view_all_nodes($account = NULL) {
global $user;
if (!$account) {
$account = $user;
}
$access =& drupal_static(__FUNCTION__);
if (isset($access[$account->uid])) {
return $access[$account->uid];
}
if (!module_implements('node_grants')) {
$access[$account->uid] = TRUE;
}
else {
$query = db_select('node_access');
$query
->addExpression('COUNT(*)');
$query
->condition('nid', 0)
->condition('grant_view', 1, '>=');
$grants = node_add_node_grants_to_query(node_access_grants('view', $account));
if (count($grants) > 0) {
$query
->condition($grants);
}
$access[$account->uid] = $query
->execute()
->fetchField();
}
return $access[$account->uid];
}
function node_query_node_access_alter(QueryAlterableInterface $query) {
_node_query_node_access_alter($query, 'node');
}
function node_query_entity_field_access_alter(QueryAlterableInterface $query) {
_node_query_node_access_alter($query, 'entity');
}
function _node_query_node_access_alter($query, $type) {
global $user;
if (!($account = $query
->getMetaData('account'))) {
$account = $user;
}
if (!($op = $query
->getMetaData('op'))) {
$op = 'view';
}
if (user_access('bypass node access', $account)) {
return;
}
if (!count(module_implements('node_grants'))) {
return;
}
if ($op == 'view' && node_access_view_all_nodes($account)) {
return;
}
$tables = $query
->getTables();
$base_table = $query
->getMetaData('base_table');
if (!$base_table) {
$fallback = '';
foreach ($tables as $alias => $table_info) {
if (!$table_info instanceof SelectQueryInterface) {
$table = $table_info['table'];
if ($table == 'node') {
$base_table = $table;
break;
}
if (!$base_table) {
$schema = drupal_get_schema($table);
if (isset($schema['fields']['nid'])) {
if (isset($schema['foreign keys'])) {
foreach ($schema['foreign keys'] as $relation) {
if ($relation['table'] === 'node' && $relation['columns'] === array(
'nid' => 'nid',
)) {
$base_table = $table;
}
}
}
else {
$fallback = $table;
}
}
}
}
}
if (!$base_table) {
if ($fallback) {
watchdog('security', 'Your node listing query is using @fallback as a base table in a query tagged for node access. This might not be secure and might not even work. Specify foreign keys in your schema to node.nid ', array(
'@fallback' => $fallback,
), WATCHDOG_WARNING);
$base_table = $fallback;
}
else {
throw new Exception(t('Query tagged for node access but there is no nid. Add foreign keys to node.nid in schema to fix.'));
}
}
}
$grants = node_access_grants($op, $account);
if ($type == 'entity') {
$node_conditions = db_and();
}
foreach ($tables as $nalias => $tableinfo) {
$table = $tableinfo['table'];
if (!$table instanceof SelectQueryInterface && $table == $base_table) {
$subquery = db_select('node_access', 'na')
->fields('na', array(
'nid',
));
$grant_conditions = node_add_node_grants_to_query($grants, 'na');
if (count($grant_conditions
->conditions())) {
$subquery
->condition($grant_conditions);
}
$subquery
->condition('na.grant_' . $op, 1, '>=');
$field = 'nid';
if ($type == 'entity') {
$base_alias = $nalias;
$field = 'entity_id';
}
$subquery
->where("{$nalias}.{$field} = na.nid");
if ($type == 'entity') {
$node_conditions
->exists($subquery);
}
else {
$query
->exists($subquery);
}
}
}
if ($type == 'entity' && count($subquery
->conditions())) {
$node_conditions
->condition("{$base_alias}.entity_type", 'node');
$or = db_or();
$or
->condition($node_conditions);
$or
->condition("{$base_alias}.entity_type", 'node', '<>');
$query
->condition($or);
}
}
function node_access_acquire_grants($node, $delete = TRUE) {
$grants = module_invoke_all('node_access_records', $node);
drupal_alter('node_access_records', $grants, $node);
if (empty($grants) && !empty($node->status)) {
$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, NULL, $delete);
}
function node_access_write_grants($node, $grants, $realm = NULL, $delete = TRUE) {
if ($delete) {
$query = db_delete('node_access')
->condition('nid', $node->nid);
if ($realm) {
$query
->condition('realm', array(
$realm,
'all',
), 'IN');
}
$query
->execute();
}
if (!empty($grants) && count(module_implements('node_grants'))) {
$query = db_insert('node_access')
->fields(array(
'nid',
'realm',
'gid',
'grant_view',
'grant_update',
'grant_delete',
));
foreach ($grants as $grant) {
if ($realm && $realm != $grant['realm']) {
continue;
}
if ($grant['grant_view'] || $grant['grant_update'] || $grant['grant_delete']) {
$grant['nid'] = $node->nid;
$query
->values($grant);
}
}
$query
->execute();
}
}
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_delete('node_access')
->execute();
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 {
drupal_set_time_limit(240);
$nids = db_query("SELECT nid FROM {node} ORDER BY nid DESC")
->fetchCol();
foreach ($nids as $nid) {
$node = node_load($nid, NULL, TRUE);
if (!empty($node)) {
node_access_acquire_grants($node);
}
}
}
}
else {
db_insert('node_access')
->fields(array(
'nid' => 0,
'realm' => 'all',
'gid' => 0,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
))
->execute();
}
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_query('SELECT COUNT(nid) FROM {node}')
->fetchField();
}
$limit = 20;
$nids = db_query_range("SELECT nid FROM {node} WHERE nid > :nid ORDER BY nid ASC", 0, $limit, array(
':nid' => $context['sandbox']['current_node'],
))
->fetchCol();
$nodes = node_load_multiple($nids, array(), TRUE);
foreach ($nodes as $nid => $node) {
if (!empty($node)) {
node_access_acquire_grants($node);
}
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $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_form($node, $form_state) {
$form = array();
$type = node_type_get_type($node);
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,
);
}
return $form;
}
function node_forms() {
$forms = array();
if ($types = node_type_get_types()) {
foreach (array_keys($types) as $type) {
$forms[$type . '_node_form']['callback'] = 'node_form';
}
}
return $forms;
}
function node_action_info() {
return array(
'node_publish_action' => array(
'type' => 'node',
'label' => t('Publish content'),
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'node_presave',
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_unpublish_action' => array(
'type' => 'node',
'label' => t('Unpublish content'),
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'node_presave',
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_make_sticky_action' => array(
'type' => 'node',
'label' => t('Make content sticky'),
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'node_presave',
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_make_unsticky_action' => array(
'type' => 'node',
'label' => t('Make content unsticky'),
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'node_presave',
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_promote_action' => array(
'type' => 'node',
'label' => t('Promote content to front page'),
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'node_presave',
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_unpromote_action' => array(
'type' => 'node',
'label' => t('Remove content from front page'),
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'node_presave',
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_assign_owner_action' => array(
'type' => 'node',
'label' => t('Change the author of content'),
'configurable' => TRUE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'node_presave',
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_save_action' => array(
'type' => 'node',
'label' => t('Save content'),
'configurable' => FALSE,
'triggers' => array(
'comment_insert',
'comment_update',
'comment_delete',
),
),
'node_unpublish_by_keyword_action' => array(
'type' => 'node',
'label' => t('Unpublish content containing keyword(s)'),
'configurable' => TRUE,
'triggers' => array(
'node_presave',
'node_insert',
'node_update',
),
),
);
}
function node_publish_action($node, $context = array()) {
$node->status = NODE_PUBLISHED;
watchdog('action', 'Set @type %title to published.', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
}
function node_unpublish_action($node, $context = array()) {
$node->status = NODE_NOT_PUBLISHED;
watchdog('action', 'Set @type %title to unpublished.', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
}
function node_make_sticky_action($node, $context = array()) {
$node->sticky = NODE_STICKY;
watchdog('action', 'Set @type %title to sticky.', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
}
function node_make_unsticky_action($node, $context = array()) {
$node->sticky = NODE_NOT_STICKY;
watchdog('action', 'Set @type %title to unsticky.', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
}
function node_promote_action($node, $context = array()) {
$node->promote = NODE_PROMOTED;
watchdog('action', 'Promoted @type %title to front page.', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
}
function node_unpromote_action($node, $context = array()) {
$node->promote = NODE_NOT_PROMOTED;
watchdog('action', 'Removed @type %title from front page.', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
}
function node_save_action($node) {
node_save($node);
watchdog('action', 'Saved @type %title', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
}
function node_assign_owner_action($node, $context) {
$node->uid = $context['owner_uid'];
$owner_name = db_query("SELECT name FROM {users} WHERE uid = :uid", array(
':uid' => $context['owner_uid'],
))
->fetchField();
watchdog('action', 'Changed owner of @type %title to uid %name.', array(
'@type' => node_type_get_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_query("SELECT COUNT(*) FROM {users}")
->fetchField();
$owner_name = '';
if (isset($context['owner_uid'])) {
$owner_name = db_query("SELECT name FROM {users} WHERE uid = :uid", array(
':uid' => $context['owner_uid'],
))
->fetchField();
}
if (intval($count) < 200) {
$options = array();
$result = db_query("SELECT uid, name FROM {users} WHERE uid > 0 ORDER BY name");
foreach ($result as $data) {
$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) {
$exists = (bool) db_query_range('SELECT 1 FROM {users} WHERE name = :name', 0, 1, array(
':name' => $form_state['values']['owner_name'],
))
->fetchField();
if (!$exists) {
form_set_error('owner_name', t('Enter a valid username.'));
}
}
function node_assign_owner_action_submit($form, $form_state) {
$uid = db_query('SELECT uid from {users} WHERE name = :name', array(
':name' => $form_state['values']['owner_name'],
))
->fetchField();
return array(
'owner_uid' => $uid,
);
}
function node_unpublish_by_keyword_action_form($context) {
$form['keywords'] = array(
'#title' => t('Keywords'),
'#type' => 'textarea',
'#description' => t('The content will be unpublished if it contains any of the phrases above. Use a case-sensitive, comma-separated list of phrases. Example: funny, bungee jumping, "Company, Inc."'),
'#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) {
$elements = node_view(clone $node);
if (strpos(drupal_render($elements), $keyword) !== FALSE || strpos($node->title, $keyword) !== FALSE) {
$node->status = NODE_NOT_PUBLISHED;
watchdog('action', 'Set @type %title to unpublished.', array(
'@type' => node_type_get_name($node),
'%title' => $node->title,
));
break;
}
}
}
function node_requirements($phase) {
$requirements = array();
if ($phase === 'runtime') {
$grant_count = db_query('SELECT COUNT(*) FROM {node_access}')
->fetchField();
if ($grant_count != 1 || count(module_implements('node_grants')) > 0) {
$value = format_plural($grant_count, 'One permission in use', '@count permissions in use', array(
'@count' => $grant_count,
));
}
else {
$value = t('Disabled');
}
$description = t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions.');
$requirements['node_access'] = array(
'title' => t('Node Access Permissions'),
'value' => $value,
'description' => $description . ' ' . l(t('Rebuild permissions'), 'admin/reports/status/rebuild'),
);
}
return $requirements;
}
function node_modules_enabled($modules) {
if (!node_access_needs_rebuild() && array_intersect($modules, module_implements('node_grants'))) {
node_access_needs_rebuild(TRUE);
}
}
class NodeController extends DrupalDefaultEntityController {
protected function attachLoad(&$nodes, $revision_id = FALSE) {
$typed_nodes = array();
foreach ($nodes as $id => $entity) {
$typed_nodes[$entity->type][$id] = $entity;
}
foreach ($typed_nodes as $node_type => $nodes_of_type) {
if (node_hook($node_type, 'load')) {
$function = node_type_get_base($node_type) . '_load';
$function($nodes_of_type);
}
}
$argument = array_keys($typed_nodes);
$this->hookLoadArguments = array(
$argument,
);
parent::attachLoad($nodes, $revision_id);
}
protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
$query = parent::buildQuery($ids, $conditions, $revision_id);
$fields =& $query
->getFields();
unset($fields['timestamp']);
$query
->addField('revision', 'timestamp', 'revision_timestamp');
$fields['uid']['table'] = 'base';
$query
->addField('revision', 'uid', 'revision_uid');
return $query;
}
}
function node_file_download_access($field, $entity_type, $entity) {
if ($entity_type == 'node') {
return node_access('view', $entity);
}
}