- <?php
- * @file
- * The core module that allows content to be submitted to the site.
- *
- * Modules and scripts may programmatically submit nodes using the usual form
- * API pattern.
- */
-
- * Denotes that the node is not published.
- */
- define('NODE_NOT_PUBLISHED', 0);
-
- * Denotes that the node is published.
- */
- define('NODE_PUBLISHED', 1);
-
- * Denotes that the node is not published, but scheduled for later.
- */
- define('NODE_SCHEDULED', 2);
-
- * Denotes that the node is not promoted.
- */
- define('NODE_NOT_PROMOTED', 0);
-
- * Denotes that the node is promoted.
- */
- define('NODE_PROMOTED', 1);
-
- * Denotes that the node is not sticky at the top of the page.
- */
- define('NODE_NOT_STICKY', 0);
-
- * Denotes that the node is sticky at the top of the page.
- */
- define('NODE_STICKY', 1);
-
- * Denotes the time cutoff for nodes marked as read.
- *
- * Nodes changed before this time are always marked as read. Nodes changed after
- * this time may be marked new, updated, or read, depending on their state for
- * the current user. Defaults to 30 days ago.
- */
- define('NODE_NEW_LIMIT', REQUEST_TIME - 30 * 24 * 60 * 60);
-
- * Denotes that access is allowed for a node.
- *
- * Modules should return this value from hook_node_access() to allow access to a
- * node.
- */
- define('NODE_ACCESS_ALLOW', 'allow');
-
- * Denotes that access is denied for a node.
- *
- * Modules should return this value from hook_node_access() to deny access to a
- * node.
- */
- define('NODE_ACCESS_DENY', 'deny');
-
- * Denotes that access is unaffected for a node.
- *
- * Modules should return this value from hook_node_access() to indicate no
- * effect on node access.
- */
- define('NODE_ACCESS_IGNORE', NULL);
-
- * Implements hook_theme().
- */
- function node_theme() {
- $base = array(
- 'file' => 'node.theme.inc',
- );
-
- return array(
- 'node' => array(
- 'render element' => 'elements',
- 'template' => 'templates/node',
- ) + $base,
- 'node_search_factors' => array(
- 'render element' => 'element',
- ) + $base,
- 'node_preview_banner_form' => array(
- 'render element' => 'form',
- ) + $base,
- 'node_preview' => array(
- 'render element' => 'node_preview',
- ) + $base,
- 'node_add_list' => array(
- 'variables' => array('content' => NULL),
- ) + $base,
- 'node_admin_overview' => array(
- 'variables' => array('name' => NULL, 'type' => NULL),
- ) + $base,
- 'node_recent_block' => array(
- 'variables' => array('nodes' => NULL),
- ) + $base,
- 'node_recent_content' => array(
- 'variables' => array('node' => NULL),
- ) + $base,
- 'node_type_form_permissions' => array(
- 'render element' => 'form',
- 'function' => 'theme_user_admin_permissions',
- ),
- );
- }
-
- * Implements hook_cron().
- */
- function node_cron() {
- db_delete('history')
- ->condition('timestamp', NODE_NEW_LIMIT, '<')
- ->execute();
-
- $scheduled_nodes = db_select('node', 'n')
- ->fields('n', array('nid'))
- ->condition('status', 0)
- ->condition('scheduled', 0, '!=')
- ->condition('scheduled', REQUEST_TIME, '<=')
- ->execute();
- foreach ($scheduled_nodes as $n) {
- if ($node = node_load($n->nid)) {
- $node->status = 1;
- $node->created = $node->scheduled;
- $node->scheduled = 0;
- $node->save();
- }
- }
- }
-
- * Implements hook_entity_info().
- */
- function node_entity_info() {
- $entity_info = array(
- 'node' => array(
- 'label' => t('Node'),
- 'bundle label' => t('Type'),
- 'controller class' => 'NodeStorageController',
- 'entity class' => 'Node',
- 'base table' => 'node',
- 'revision table' => 'node_revision',
- 'fieldable' => TRUE,
- 'redirect support' => TRUE,
- 'entity keys' => array(
- 'id' => 'nid',
- 'revision' => 'vid',
- 'bundle' => 'type',
- ),
- '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,
- ),
- 'token' => array(
- 'label' => t('Tokens'),
- 'custom settings' => FALSE,
- ),
- ),
- ),
- );
-
-
- if (db_table_exists('cache_entity_node')) {
- $entity_info['node']['entity cache'] = TRUE;
- $entity_info['node']['field cache'] = FALSE;
- }
-
-
-
- if (module_exists('search')) {
- $entity_info['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,
- ),
- );
- }
-
-
-
- node_type_cache_reset();
- foreach (node_type_get_names() as $type => $name) {
- $entity_info['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 $entity_info;
- }
-
- * Implements hook_field_display_ENTITY_TYPE_alter().
- */
- function node_field_display_node_alter(&$display, $context) {
-
- if ($context['view_mode'] == 'search_index') {
- $display['label'] = 'hidden';
- }
- }
-
- * Implements hook_admin_paths().
- */
- function node_admin_paths() {
- if (config_get('system.core', '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;
- }
- else {
- return array();
- }
- }
-
- * Gathers a listing of links to nodes.
- *
- * @param $result
- * A database result object from a query to fetch node entities. If your
- * query joins the {node_comment_statistics} table so that the comment_count
- * field is available, a title attribute will be added to show the number of
- * comments.
- * @param $title
- * (optional) A heading for the resulting list.
- *
- * @return
- * A renderable array containing a list of linked node titles fetched from
- * $result, or FALSE if there are no rows in $result.
- */
- 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;
- }
-
- * Updates the 'last viewed' timestamp of the specified node for current user.
- *
- * @param Node $node
- * A node entity.
- * @param bool $save_for_later
- * Save the given node ID to save its marking for at the end of the request.
- *
- * @since 1.10 $save_for_later parameter added.
- */
- function node_tag_new($node = NULL, $save_for_later = FALSE) {
- $nids_viewed = &backdrop_static(__FUNCTION__, array());
- if ($node) {
- $nids_viewed[] = $node->nid;
- }
-
-
- if ($save_for_later || empty($nids_viewed)) {
- return;
- }
-
- global $user;
- if ($user->uid) {
- foreach ($nids_viewed as $nid) {
- db_merge('history')
- ->key(array(
- 'uid' => $user->uid,
- 'nid' => $nid,
- ))
- ->fields(array('timestamp' => REQUEST_TIME))
- ->execute();
- }
- }
-
-
- $nids_viewed = array();
- }
-
- * Retrieves the timestamp for the current user's last view of a specified node.
- *
- * @param $nid
- * A node ID.
- *
- * @return
- * If a node has been previously viewed by the user, the timestamp in seconds
- * of when the last view occurred; otherwise, zero.
- */
- function node_last_viewed($nid) {
- global $user;
- $history = &backdrop_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);
- }
-
- * Decides on the type of marker to be displayed for a given node.
- *
- * @param $nid
- * Node ID whose history supplies the "last viewed" timestamp.
- * @param $timestamp
- * Time which is compared against node's "last viewed" timestamp.
- *
- * @return int
- * One of the MARK constants.
- */
- function node_mark($nid, $timestamp) {
- global $user;
- $cache = &backdrop_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;
- }
-
- * Extracts the type name.
- *
- * @param Node|string $node
- * Either a string or object, containing the node type information.
- *
- * @return string
- * Node type of the passed-in data.
- */
- function _node_extract_type($node) {
- return is_object($node) ? $node->type : $node;
- }
-
- * Returns a list of all the available node types.
- *
- * This list can include types that are queued for addition or deletion.
- * See _node_types_build() for details.
- *
- * @return stdClass[]
- * An array of node types, as objects, keyed by the type.
- *
- * @see node_type_get_type()
- */
- function node_type_get_types() {
- return _node_types_build()->types;
- }
-
- * Returns the node type of the passed node or node type string.
- *
- * @param Node|string $node
- * A node entity or string that indicates the node type to return.
- *
- * @return stdClass|FALSE
- * A single node type, as an object, or FALSE if the node type is not found.
- * The node type is an object containing fields from a node type's config
- * file, merged with the defaults from node_type_set_defaults().
- */
- function node_type_get_type($node) {
- $type = _node_extract_type($node);
- $types = _node_types_build()->types;
- return isset($types[$type]) ? $types[$type] : FALSE;
- }
-
- * Returns the node type base of the passed node or node type string.
- *
- * The base indicates which module implements this node type and is used to
- * execute node-type-specific hooks. For types defined in the user interface
- * and managed by node.module, the base is 'node_content'.
- *
- * @param Node|string $node
- * A node entity or string that indicates the node type to return.
- *
- * @return string
- * The node type base or FALSE if the node type is not found.
- *
- * @see node_invoke()
- */
- function node_type_get_base($node) {
- $type = _node_extract_type($node);
- $types = _node_types_build()->types;
- return isset($types[$type]) && !empty($types[$type]->base) ? $types[$type]->base : FALSE;
- }
-
- * Returns a list of available node type names.
- *
- * This list can include types that are queued for addition or deletion.
- * See _node_types_build() for details.
- *
- * @return array
- * An array of node type names, keyed by the type.
- */
- function node_type_get_names() {
- return _node_types_build()->names;
- }
-
- * Returns the node type name of the passed node or node type string.
- *
- * @param Node|string $node
- * A node entity or string that indicates the node type to return.
- *
- * @return string|FALSE
- * The node type name or FALSE if the node type is not found.
- */
- function node_type_get_name($node) {
- $type = _node_extract_type($node);
- $types = _node_types_build()->names;
- return isset($types[$type]) ? $types[$type] : FALSE;
- }
-
- * Menu argument loader: Loads a node type by string.
- *
- * @param $name
- * The machine-readable name of a node type to load, where '_' is replaced
- * with '-'.
- *
- * @return stdClass|FALSE
- * A node type object or FALSE if $name does not exist.
- */
- function node_type_load($name) {
- return node_type_get_type(strtr($name, array('-' => '_')));
- }
-
- * Saves a node type to the database.
- *
- * @param object $info
- * The node type to save; an object with the following properties:
- * - type: A string giving the machine name of the node type.
- * - name: A string giving the human-readable name of the node type.
- * - base: A string that indicates the base string for hook functions. For
- * example, 'node_content' is the value used by the UI when creating a new
- * node type.
- * - description: A string that describes the node type.
- * - help: A string giving the help information shown to the user when
- * creating a node of this type.
- * - custom: TRUE or FALSE indicating whether this type is defined by a module
- * (FALSE) or by a user (TRUE) via Add Content Type.
- * - modified: TRUE or FALSE indicating whether this type has been modified by
- * an administrator. Currently not used in any way.
- * - locked: TRUE or FALSE indicating whether the administrator can change the
- * machine name of this type.
- * - disabled: TRUE or FALSE indicating whether this type has been disabled.
- * - has_title: TRUE or FALSE indicating whether this type uses the node title
- * field.
- * - title_label: A string containing the label for the title.
- * - module: A string giving the module defining this type of node.
- * - orig_type: A string giving the original machine-readable name of this
- * node type. This may be different from the current type name if the locked
- * field is 0.
- *
- * @return int
- * A status flag indicating the outcome of the operation, either SAVED_NEW or
- * SAVED_UPDATED.
- */
- function node_type_save($info) {
- $type = node_type_set_defaults($info);
- $type_data = (array) $type;
- $type_data['has_title'] = (bool) $type_data['has_title'];
- $type_data['modified'] = (bool) $type_data['modified'];
- $type_data['disabled'] = (bool) $type_data['disabled'];
-
-
- if (isset($type_data['is_new'])) {
- unset($type_data['is_new']);
- }
- if (isset($type_data['old_type'])) {
- unset($type_data['old_type']);
- }
-
- $config = config('node.type.' . $type->type);
- foreach ($type_data as $key => $value) {
- $config->set($key, $value);
- }
- $config->save();
-
- if (empty($type->is_new)) {
- 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 {
- field_attach_create_bundle('node', $type->type);
- module_invoke_all('node_type_insert', $type);
- $status = SAVED_NEW;
- }
-
-
- if (isset($type->old_type) && $type->type !== $type->old_type) {
- config('node.type.' . $type->old_type)->delete();
- }
-
-
- node_type_cache_reset();
-
- return $status;
- }
-
- * Adds the default body field to a node type.
- *
- * @param $type
- * A node type object.
- * @param $label
- * (optional) The label for the body instance.
- *
- * @return array
- * Body field instance.
- */
- 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_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;
- }
-
- * Implements hook_field_extra_fields().
- */
- function node_field_extra_fields() {
- $extra = array();
- $module_language_enabled = module_exists('language');
- $description = t('Node module element');
-
- foreach (node_type_get_types() as $type) {
- if ($type->has_title) {
- $extra['node'][$type->type]['form']['title'] = array(
- 'label' => $type->title_label,
- 'description' => $description,
- 'weight' => -5,
- );
- }
-
-
-
- if ($module_language_enabled && $type->settings['language']) {
- $extra['node'][$type->type]['form']['langcode'] = array(
- 'label' => t('Language'),
- 'description' => $description,
- 'weight' => 0,
- );
- }
- }
-
- return $extra;
- }
-
- * Deletes a node type from the database.
- *
- * @param string $type
- * The machine-readable name of the node type to be deleted.
- */
- function node_type_delete($type) {
- if ($info = node_type_get_type($type)) {
- $config = config('node.type.' . $type);
- $config->delete();
- field_attach_delete_bundle('node', $type);
- module_invoke_all('node_type_delete', $info);
-
-
- node_type_cache_reset();
- }
- }
-
- * Updates all nodes of one type to be of another type.
- *
- * @param $old_type
- * The current node type of the nodes.
- * @param $type
- * The new node type of the nodes.
- *
- * @return
- * The number of nodes whose node type field was modified.
- */
- function node_type_update_nodes($old_type, $type) {
- return db_update('node')
- ->fields(array('type' => $type))
- ->condition('type', $old_type)
- ->execute();
- }
-
- * Builds and returns the list of available node types.
- *
- * This function reads from disk individual config files that define the
- * available content types in the system. Modules may bundle a content type with
- * their module by including a "node.type.[type_name].json" config file in their
- * module's config directory. Each file should contain:
- * - name: (required) The human-readable name of the node type.
- * - base: (required) The base string used to construct callbacks
- * corresponding to this node type (for example, if base is defined as
- * example_foo, then example_foo_insert will be called when inserting a node
- * of that type). This string is usually the name of the module, but not
- * always.
- * - description: (required) A brief description of the node type.
- * - help: (optional) Help information shown to the user when creating a node
- * of this type.
- * - has_title: (optional) A Boolean indicating whether or not this node type
- * has a title field.
- * - title_label: (optional) The label for the title field of this content
- * type.
- * - locked: (optional) A Boolean indicating whether the administrator can
- * change the machine name of this type. FALSE = changeable (not locked),
- * TRUE = unchangeable (locked).
- *
- * @return
- * An object with two properties:
- * - names: Associative array of the names of node types, keyed by the type.
- * - types: Associative array of node type objects, keyed by the type.
- * These arrays will also include obsolete types: types that were previously
- * defined by modules that have been disabled, likely by a module that was
- * provided a node type and then was disabled. These are indicated in the
- * type object by $type->disabled being set to TRUE.
- */
- function _node_types_build() {
- $cid = 'node_types:' . $GLOBALS['language']->langcode;
-
- $_node_types = &backdrop_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());
- module_load_include('inc', 'node', 'node.types');
-
- $config_names = config_get_names_with_prefix('node.type.');
- foreach ($config_names as $config_name) {
- $node_type_data = config($config_name)->get();
-
-
- $module = $node_type_data['module'];
- $module_disabled = TRUE;
- if ($module === 'node' || module_exists($module)) {
- $module_disabled = FALSE;
- }
-
-
- $node_type_data['disabled'] = !empty($node_type_data['disabled']) || $module_disabled;
-
- $type = str_replace('node.type.', '', $config_name);
- $_node_types->types[$type] = node_type_set_defaults($node_type_data);
- $_node_types->names[$type] = $node_type_data['name'];
- }
-
-
- foreach (module_implements('node_type_load') as $module) {
- $function = $module . '_node_type_load';
- $function($_node_types->types);
- }
-
- cache()->set($cid, $_node_types);
-
- return $_node_types;
- }
-
- * Clears the node type cache.
- */
- function node_type_cache_reset() {
- cache()->deletePrefix('node_types:');
- backdrop_static_reset('_node_types_build');
- entity_info_cache_clear();
- }
-
- * Sets the default values for a node type.
- *
- * The defaults are appropriate for a type defined through node_type_save(),
- * since 'custom' is TRUE for types defined in the user interface, and FALSE
- * for types defined by modules. (The 'module' flag prevents types from being
- * deleted through the user interface.) Also, the default for 'locked' is TRUE,
- * which prevents users from changing the machine name of the type.
- *
- * @param $info
- * (optional) An object or array containing values to override the defaults.
- * See node_type_save() for details on what the array elements mean. Defaults
- * to an empty array.
- *
- * @return
- * A node type object, with missing values in $info set to their defaults.
- */
- function node_type_set_defaults($info = array()) {
- $info = (array) $info;
- $new_type = $info + array(
- 'type' => '',
- 'name' => '',
- 'base' => 'node_content',
- 'module' => 'node',
- 'node_preview' => BACKDROP_OPTIONAL,
- 'description' => '',
- 'help' => '',
- 'modified' => FALSE,
- 'disabled' => FALSE,
- 'has_title' => TRUE,
- 'title_label' => 'Title',
- 'settings' => array(),
- );
- $new_type = (object) $new_type;
-
-
- if (empty($new_type->name)) {
- $new_type->is_new = TRUE;
- }
-
-
- if (!$new_type->has_title) {
- $new_type->title_label = '';
- }
- $new_type->orig_type = isset($info['type']) ? $info['type'] : '';
-
-
- $types = array(
- '_new' => $new_type
- );
- module_load_include('inc', 'node', 'node.types');
- foreach (module_implements('node_type_load') as $module) {
- $function = $module . '_node_type_load';
- $function($types);
- }
- $new_type = $types['_new'];
-
- return $new_type;
- }
-
- * Determines whether a node hook exists.
- *
- * @param Node|string $node
- * A node entity or a string containing the node type.
- * @param $hook
- * A string containing the name of the hook.
- *
- * @return
- * TRUE if the $hook exists in the node type of $node.
- */
- function node_hook($node, $hook) {
- $base = node_type_get_base($node);
- return module_hook($base, $hook);
- }
-
- * Invokes a node hook.
- *
- * @param Node|string $node
- * A node entity or a string containing the node type.
- * @param $hook
- * A string containing the name of the hook.
- * @param $a2, $a3, $a4
- * Arguments to pass on to the hook, after the $node argument.
- *
- * @return mixed
- * The returned value of the invoked 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));
- }
- }
-
- * Loads node entities from the database.
- *
- * This function should be used whenever you need to load more than one node
- * from the database. Nodes are loaded into memory and will not require database
- * access if loaded again during the same page request.
- *
- * @param array|false $nids
- * (optional) An array of node IDs or FALSE to load all the nodes. Using an
- * empty array (the default value), the function will return an empty array.
- * @param array $conditions
- * (deprecated) An associative array of conditions on the {node}
- * table, where the keys are the database fields and the values are the
- * values those fields must have. Instead, it is preferable to use
- * EntityFieldQuery to retrieve a list of entity IDs loadable by
- * this function.
- * @param bool $reset
- * (optional) Whether to reset the internal node_load() cache.
- *
- * @return Node[]
- * An array of node objects indexed by nid.
- *
- * @see entity_load()
- * @see EntityFieldQuery
- */
- function node_load_multiple($nids = array(), $conditions = array(), $reset = FALSE) {
- return entity_load('node', $nids, $conditions, $reset);
- }
-
- * Loads a node entity from the database.
- *
- * @param $nid
- * (optional) The node ID.
- * @param $vid
- * (optional) The revision ID.
- * @param $reset
- * (optional) Whether to reset the node_load_multiple() cache.
- *
- * @return Node|false
- * A fully-populated node entity, or FALSE if the node is not found.
- */
- 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;
- }
-
- * Prepares a node entity for editing.
- *
- * Fills in a few default values, and then invokes hook_prepare() on the node
- * type module, and hook_node_prepare() on all modules.
- *
- * @param Node $node
- * A node object.
- */
- function node_object_prepare(Node $node) {
-
- $node_tempstore_id = node_build_tempstore_id($node->type);
-
-
- $node_type = node_type_get_type($node->type);
-
- if (!isset($node->nid) || isset($node->is_new)) {
- if (!isset($node->status)) {
- $node->status = (int) $node_type->settings['status_default'];
- }
- if (!isset($node->promote)) {
- $node->promote = (int) ($node_type->settings['promote_enabled']) ? $node_type->settings['promote_default'] : 0;
- }
- if (!isset($node->sticky)) {
- $node->sticky = (int) ($node_type->settings['sticky_enabled']) ? $node_type->settings['sticky_default'] : 0;
- }
- 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 = $node_type->settings['revision_enabled'] ? $node_type->settings['revision_default'] : FALSE;
-
- node_invoke($node, 'prepare');
- module_invoke_all('node_prepare', $node);
- }
-
- * Performs validation checks on the given node.
- *
- * @see node_form_validate()
- */
- 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)) {
- $node_date = $node->date;
- if (is_array($node->date)) {
- $node_date = implode(' ', $node->date);
- }
- if (strtotime($node_date) === FALSE) {
- form_set_error('date', t('You have to specify a valid date.'));
- }
- }
-
-
- if ($node->status == NODE_SCHEDULED && !empty($node->scheduled)) {
- $node_scheduled = $node->scheduled;
- if (is_array($node->scheduled)) {
- $node_scheduled = implode(' ', $node->scheduled);
- }
-
- if (strtotime($node_scheduled) === FALSE) {
- form_set_error('scheduled', t('You have to specify a valid date.'));
- }
-
- else {
- $scheduled_date = new DateTime($node_scheduled, date_default_timezone_object());
- if ($scheduled_date && $scheduled_date->format('U') < REQUEST_TIME) {
- form_set_error('scheduled', t('Scheduled publish time cannot be in the past.'));
- }
- }
- }
-
-
-
-
-
- $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);
- }
- }
-
- * Prepares a node for saving by populating the author and creation date.
- */
- function node_submit($node) {
- global $user;
-
-
-
- if (isset($node->name)) {
- if ($account = user_load_by_name($node->name)) {
- $node->uid = $account->uid;
- }
- else {
- $node->uid = 0;
- }
- }
-
-
- if (!empty($node->revision)) {
- $node->revision_uid = $user->uid;
- }
-
-
-
- if (isset($node->date) && is_array($node->date)) {
- $node->date = $node->date['date'] . ' ' . $node->date['time'];
- }
- $date = new BackdropDateTime(!empty($node->date) && is_string($node->date) ? $node->date : 'now');
- $node->created = $date->format('U');
- $node->validated = TRUE;
-
- return $node;
- }
-
- * Saves a new or updated node.
- *
- * @param Node $node
- * The $node entity to be saved. If $node->nid is omitted (or $node->is_new
- * is TRUE), a new node will be added.
- *
- * @return int
- * Either SAVED_NEW or SAVED_UPDATED depending on the operation performed.
- */
- function node_save(Node $node) {
- return $node->save();
- }
-
- * Deletes a node.
- *
- * @param $nid
- * A node ID.
- */
- function node_delete($nid) {
- node_delete_multiple(array($nid));
- }
-
- * Deletes multiple nodes.
- *
- * @param $nids
- * An array of node IDs.
- *
- * @see hook_node_predelete()
- * @see hook_node_delete()
- */
- function node_delete_multiple($nids) {
- entity_delete_multiple('node', $nids);
- }
-
- * Deletes a node revision.
- *
- * @param $revision_id
- * The revision ID to delete.
- *
- * @return
- * TRUE if the revision deletion was successful.
- */
- function node_revision_delete($revision_id) {
- if ($revision = node_load(NULL, $revision_id)) {
-
- $node = node_load($revision->nid);
- if ($revision->isActiveRevision()) {
- 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;
- }
-
- * Generates an array for rendering the given node.
- *
- * @param Node $node
- * A node entity.
- * @param $view_mode
- * (optional) Display mode, e.g. 'full' or 'teaser'. Defaults to 'full'.
- * @param $langcode
- * (optional) A language code to use for rendering. Defaults to the global
- * content language of the current request.
- *
- * @return
- * An array as expected by backdrop_render().
- */
- function node_view(Node $node, $view_mode = 'full', $langcode = NULL) {
- return $node->view($view_mode, $langcode);
- }
-
- * Builds a structured array representing the node's content.
- *
- * The content built for the node (field values, comments, file attachments or
- * other node components) will vary depending on the $view_mode parameter.
- *
- * Backdrop core defines the following display modes for nodes, with the following
- * default use cases:
- * - full (default): node is being displayed on its own page (node/123)
- * - teaser: node is being displayed on the default home page listing, or on
- * taxonomy listing pages.
- * - rss: node displayed in an RSS feed.
- * If search.module is enabled:
- * - search_index: node is being indexed for search.
- * - search_result: node is being displayed as a search result.
- * If book.module is enabled:
- * - print: node is being displayed in print-friendly mode.
- * Contributed modules might define additional display modes, or use existing
- * display modes in additional contexts.
- *
- * @param Node $node
- * A node entity.
- * @param $view_mode
- * (optional) Display mode, e.g. 'full' or 'teaser'. Defaults to 'full'.
- * @param $langcode
- * (optional) A language code to use for rendering. Defaults to the global
- * content language of the current request.
- */
- function node_build_content(Node $node, $view_mode = 'full', $langcode = NULL) {
- $node->buildContent($view_mode, $langcode);
- }
-
- * Page callback: Generates an array which displays a node detail page.
- *
- * @param Node $node
- * A node entity.
- * @param $message
- * (optional) A flag which sets a page title relevant to the revision being
- * viewed.
- *
- * @return
- * A $page element suitable for use by backdrop_render().
- *
- * @see node_menu()
- */
- function node_show(Node $node, $message = FALSE) {
- if ($message) {
- backdrop_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, TRUE);
- backdrop_register_shutdown_function('node_tag_new');
-
- return $nodes;
- }
-
- * Checks whether the current page is the full page view of the passed-in node.
- *
- * @param Node $node
- * A node entity.
- *
- * @return
- * The ID of the node if this is a full page view, otherwise FALSE.
- */
- function node_is_page(Node $node) {
- $page_node = menu_get_object();
- return (!empty($page_node) ? $page_node->nid == $node->nid : FALSE);
- }
-
- * Implements hook_permission().
- */
- 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,
- 'warning' => t('Bypass all other node permissions.'),
- ),
- 'administer content types' => array(
- 'title' => t('Administer content types'),
- 'restrict access' => TRUE,
- 'warning' => t('Define custom content types and delete existing ones.'),
- ),
- 'administer nodes' => array(
- 'title' => t('Administer content'),
- 'restrict access' => TRUE,
- 'warning' => t('Edit or delete any content, which may cause irreversible data loss.'),
- ),
- '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 any unpublished content' => array(
- 'title' => t('View any 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'),
- ),
- 'view hidden paths' => array(
- 'title' => t('View hidden paths'),
- 'description' => t('View URL of content, overriding restriction on viewing content directly.'),
- ),
- );
-
-
- foreach (node_permissions_get_configured_types() as $type) {
- $perms += node_list_permissions($type);
- }
-
- return $perms;
- }
-
- * Implements hook_views_api().
- */
- function node_views_api() {
- return array(
- 'api' => '3.0',
- 'path' => backdrop_get_path('module', 'node') . '/views',
- );
- }
-
- * Gathers the rankings from the the hook_ranking implementations.
- *
- * @param SearchQuery|SelectQueryExtender $query
- * A query object that has been extended with the Search DB Extender.
- */
- function _node_rankings(SelectQueryExtender $query) {
- if ($ranking = module_invoke_all('ranking')) {
- $tables = &$query->getTables();
- $config = config('search.settings');
- foreach ($ranking as $rank => $values) {
- if ($node_rank = $config->get('node_rank_' . $rank)) {
-
- 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);
- }
- }
- }
- }
-
- * Implements hook_search_info().
- */
- function node_search_info() {
- return array(
- 'title' => 'Content',
- 'path' => 'node',
- );
- }
-
- * Implements hook_search_access().
- */
- function node_search_access() {
- return user_access('access content');
- }
-
- * Implements hook_search_reset().
- */
- function node_search_reset() {
- db_update('search_dataset')
- ->fields(array('reindex' => REQUEST_TIME))
- ->condition('type', 'node')
- ->execute();
- }
-
- * Implements hook_search_status().
- */
- function node_search_status() {
- $types = _node_search_get_types();
- $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) AND n.type IN (:types)", array(':types' => $types))->fetchField();
- return array('remaining' => $remaining, 'total' => $total);
- }
-
- * Implements hook_search_admin().
- */
- function node_search_admin() {
- $config = config('search.settings');
-
-
- $form['node_settings'] = array(
- '#type' => 'fieldset',
- '#title' => t('Content settings'),
- '#states' => array(
- 'visible' => array(
- '[name*="search_active_modules[node]"]' => array('checked' => TRUE)
- ),
- ),
- '#element_validate' => array('node_search_admin_validate'),
- );
- $form['node_settings']['node_types'] = array(
- '#title' => t('Enabled content types'),
- '#type' => 'checkboxes',
- '#default_value' => _node_search_get_types(),
- '#options' => node_type_get_names(),
- '#description' => t('Only enabled content types will be available in search results. Disabled content types will not be indexed in the future.'),
- );
-
- $form['node_settings']['factors'] = array(
- '#type' => 'item',
- '#title' => t('Content rankings'),
- '#theme' => 'node_search_factors',
- '#help' => '<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>',
- );
-
-
- $options = backdrop_map_assoc(range(0, 10));
- foreach (module_invoke_all('ranking') as $var => $values) {
- $form['node_settings']['factors']['node_rank_' . $var] = array(
- '#title' => $values['title'],
- '#type' => 'select',
- '#options' => $options,
- '#default_value' => $config->get('node_rank_' . $var),
- );
- }
-
-
- backdrop_sort($form['node_settings']['factors'], array('#default_value' => SORT_NUMERIC), SORT_DESC);
- return $form;
- }
-
- * Element validation callback for the search admin form.
- */
- function node_search_admin_validate($element, &$form_state) {
-
- $form_state['values']['node_types'] = array_keys(array_filter($form_state['values']['node_types']));
-
-
- if (empty($form_state['values']['node_types'])) {
- form_set_error('node_types', t('Please select at least one content type to search, or completely disable searching content.'));
- }
-
- elseif (count($form_state['values']['node_types']) === count(node_type_get_names())) {
- $form_state['values']['node_types'] = array();
- }
- }
-
- * Implements hook_search_execute().
- */
- function node_search_execute($keys = NULL, $conditions = NULL) {
-
- $query = db_select('search_index', 'i', array('target' => 'replica'))->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('langcode', 'n.langcode');
- 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 = backdrop_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),
- 'langcode' => $node->langcode,
- );
- }
- return $results;
- }
-
- * Implements hook_ranking().
- */
- 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'),
-
- 'score' => 'n.promote',
- ),
- );
-
-
- if ($node_cron_last = state_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;
- }
-
- * Implements hook_user_cancel().
- */
- 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;
- }
- }
-
- * Implements hook_user_predelete().
- */
- function node_user_predelete($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();
- }
-
- * Implements hook_user_update().
- */
- function node_user_update($account) {
- $orig = $account->original;
- if ($account->name != $orig->name || $account->picture != $orig->picture || $account->data != $orig->data) {
- $nids = db_select('node', 'n')
- ->fields('n', array('nid'))
- ->condition('uid', $account->uid)
- ->execute()
- ->fetchCol();
-
- if (!empty($nids)) {
-
-
- cache('entity_node')->deleteMultiple($nids);
- }
- }
- }
-
- * Access callback: Checks node revision access.
- *
- * @param Node $node
- * The node to check.
- * @param $op
- * (optional) The specific operation being checked. Defaults to 'view.'
- * @param object $account
- * (optional) A user object representing the user for whom the operation is
- * to be performed. Determines access for a user other than the current user.
- *
- * @return
- * TRUE if the operation may be performed, FALSE otherwise.
- *
- * @see node_menu()
- */
- function _node_revision_access(Node $node, $op = 'view', $account = NULL) {
- $access = &backdrop_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->isActiveRevision();
-
-
-
-
-
-
- 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];
- }
-
- * Access callback: Checks whether the user has permission to add a node.
- *
- * @return
- * TRUE if the user has permission, otherwise FALSE.
- *
- * @see node_menu()
- */
- 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;
- }
-
- * Implements hook_layout_context_info().
- */
- function node_layout_context_info() {
- $info['node'] = array(
- 'title' => t('Content (node)'),
-
- 'class' => 'EntityLayoutContext',
-
- 'menu paths' => array(
- 'node/%node',
- 'node/%node/view',
- 'node/%node/edit',
- ),
-
-
- 'path placeholder' => '%node',
-
-
- 'load callback' => 'node_load',
- );
- return $info;
- }
-
- * Implements hook_layout_load_by_router_item_alter().
- *
- * When creating node preview pages, the path will be of the form
- * node/preview/<type>/<id>, where <type> is the node type and <id> is the
- * tempstore ID of the node being previewed. But we want to display it using a
- * layout whose system path is node/%. So we choose those layouts and set the
- * context from the tempstore node.
- *
- * When viewing old node revisions, the path will be of the form
- * node/<nid>/revisions/<vid>/view, where <nid> is the node ID and <vid> is the
- * revision ID. As with previews, we want to display it using a layout whose
- * system path is node/%.
- */
- function node_layout_load_by_router_item_alter(&$layouts, $router_item) {
- $map = $router_item['map'];
-
-
- if (count($map) == 4 && $map[0] == 'node' && $map[1] == 'preview') {
-
-
- $path_is_preview = FALSE;
- foreach (node_type_get_types() as $type_obj) {
- if ($type_obj->type == $map[2]) {
- $path_is_preview = TRUE;
- break;
- }
- }
- if (!$path_is_preview) {
- return;
- }
- $tempstore_id = $map[3];
- $temp_node = node_get_node_tempstore($tempstore_id);
- if ($temp_node) {
- $node_layouts = layout_load_multiple_by_path('node/%', TRUE);
- if ($node_layouts) {
- $layouts += $node_layouts;
- foreach ($layouts as $layout) {
- foreach ($layout->getContexts() as $context) {
- if (isset($context->position)) {
- $context->setData($temp_node);
- }
- }
- }
- }
- }
- }
-
-
- if (count($map) == 5 && $map[0] == 'node' && $map[2] == 'revisions' && $map[4] == 'view') {
-
-
- $rev_node = $map[1];
- if ($rev_node) {
- $node_layouts = layout_load_multiple_by_path('node/%', TRUE);
- if ($node_layouts) {
- $layouts += $node_layouts;
- foreach ($layouts as $layout) {
- foreach ($layout->getContexts() as $context) {
- if (isset($context->position)) {
- $context->setData($rev_node);
- }
- }
- }
- }
- }
- }
-
- if (isset($layouts['admin_default'])) {
- $admin_default = $layouts['admin_default'];
- unset($layouts['admin_default']);
- $layouts['admin_default'] = $admin_default;
- }
- if (isset($layouts['default'])) {
- $default = $layouts['default'];
- unset($layouts['default']);
- $layouts['default'] = $default;
- }
- }
-
- * Implements hook_menu().
- */
- function node_menu() {
- $items['admin/content/node/delete'] = array(
- 'title' => 'Confirm content deletion',
- 'type' => MENU_VISIBLE_IN_BREADCRUMB,
- 'page callback' => 'backdrop_get_form',
- 'page arguments' => array('node_multiple_delete_confirm'),
- 'access arguments' => array('access content overview'),
- 'file' => 'node.admin.inc',
- );
-
- $items['admin/reports/status/rebuild'] = array(
- 'title' => 'Rebuild permissions',
- 'page callback' => 'backdrop_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, home page promotion, comment settings, etc.',
- 'page callback' => 'node_overview_types',
- 'access arguments' => array('administer content types'),
- 'file' => 'node.types.inc',
- );
- $items['admin/structure/types/list'] = array(
- 'title' => 'List content types',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
- $items['admin/structure/types/add'] = array(
- 'title' => 'Add content type',
- 'page callback' => 'backdrop_get_form',
- 'page arguments' => array('node_type_form'),
- 'access arguments' => array('administer content types'),
- 'type' => MENU_LOCAL_ACTION,
- 'file' => 'node.types.inc',
- );
- $items['admin/structure/types/manage/%node_type'] = array(
- 'title' => 'Configure content type',
- 'title callback' => 'node_type_page_title',
- 'title arguments' => array(4),
- 'page callback' => 'backdrop_get_form',
- 'page arguments' => array('node_type_form', 4),
- 'access arguments' => array('administer content types'),
- 'file' => 'node.types.inc',
- );
- $items['admin/structure/types/manage/%node_type/configure'] = array(
- 'title' => 'Configure',
- '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'),
- 'type' => MENU_VISIBLE_IN_BREADCRUMB,
- 'file' => 'node.types.inc',
- );
- $items['node'] = array(
- 'page callback' => 'node_page_default',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
- $items['node/add'] = array(
- 'title' => 'Add content',
- 'page callback' => 'node_add_page',
- 'access callback' => '_node_add_access',
- 'file' => 'node.pages.inc',
- 'menu_name' => 'management',
- 'weight' => -20,
- );
-
- $items['rss.xml'] = array(
- 'title' => 'RSS feed',
- 'page callback' => 'node_feed',
- 'access arguments' => array('access content'),
-
- 'delivery callback' => 'backdrop_deliver_html_page',
- '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/preview/' . $type_url_str . '/%'] = array(
- 'title' => $type->name,
- 'title callback' => 'check_plain',
- 'page callback' => 'node_preview',
- 'page arguments' => array(3, $type_url_str),
- 'access callback' => 'node_preview_access',
- 'access arguments' => array(3),
- 'description' => $type->description,
- 'type' => MENU_CALLBACK,
- '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' => 'backdrop_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' => 'backdrop_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' => 'backdrop_get_form',
- 'page arguments' => array('node_revision_delete_confirm', 1),
- 'access callback' => '_node_revision_access',
- 'access arguments' => array(1, 'delete'),
- 'file' => 'node.pages.inc',
- );
- $items['node/autocomplete'] = array(
- 'title' => 'Node autocomplete',
- 'page callback' => 'node_autocomplete',
- 'access callback' => 'user_access',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- 'file' => 'node.pages.inc',
- );
-
- return $items;
- }
-
- * Implements hook_menu().
- */
- function node_menu_alter(&$items) {
- if (isset($items['admin/content'])) {
- $items['admin/content']['icon'] = 'pencil-fill';
- }
- }
-
- * Access callback: Checks a user's permission for previewing a node.
- *
- * @param string $node_tempstore_id
- * The node_tempstore_id of the node being created or updated.
- *
- * @return bool
- * TRUE if the user has access to the preview, FALSE otherwise.
- *
- * @see node_menu()
- *
- * @since 1.13.0
- */
- function node_preview_access($node_tempstore_id) {
- $node = node_get_node_tempstore($node_tempstore_id);
- if (!empty($node) && (node_access('create', $node) || node_access('update', $node))) {
- return TRUE;
- }
- return FALSE;
- }
-
- * Implements hook_menu_local_tasks_alter().
- */
- 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,
- );
- }
- }
- }
-
- * Title callback: Provides the title for a node type edit form.
- *
- * @param $type
- * The node type object.
- *
- * @return string
- * An unsanitized string that is the title of the node type edit form.
- *
- * @see node_menu()
- */
- function node_type_page_title($type) {
- return $type->name;
- }
-
- * Title callback: Displays the node's title.
- *
- * @param Node $node
- * The node entity.
- *
- * @return
- * An unsanitized string that is the title of the node.
- *
- * @see node_menu()
- */
- function node_page_title(Node $node) {
- return $node->title;
- }
-
- * Finds the last time a node was changed.
- *
- * @param $nid
- * The ID of a node.
- *
- * @return
- * A unix timestamp indicating the last time the node was changed.
- */
- function node_last_changed($nid) {
- return db_query('SELECT changed FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetch()->changed;
- }
-
- * Returns a list of all the existing revision numbers for the node passed in.
- *
- * @param Node $node
- * The node entity.
- *
- * @return
- * An associative array keyed by node revision number.
- */
- function node_revision_list(Node $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;
- }
-
- * Implements hook_block_info().
- */
- function node_block_info() {
- $blocks['syndicate'] = array(
- 'info' => t('Syndicate'),
- 'description' => t('An RSS icon linking to available feeds.'),
- );
- $blocks['recent'] = array(
- 'info' => t('Recent content'),
- 'description' => t('A list of recently published content.'),
- );
- $blocks['content'] = array(
- 'info' => t('Existing content'),
- 'description' => t('Embed existing node content as a block onto other pages'),
- 'class' => 'NodeBlock',
- );
-
- return $blocks;
- }
-
- * Implements hook_block_view().
- */
- function node_block_view($delta = '', $settings = array()) {
-
- $block = array();
-
- switch ($delta) {
- case 'syndicate':
- if (backdrop_valid_path('rss.xml')) {
- $block['subject'] = t('Syndicate');
- $block['content'] = node_syndicate_content($settings);
- }
- break;
-
- case 'recent':
- if (user_access('access content')) {
- $settings += array(
- 'node_count' => 10,
- );
- $block['subject'] = t('Recent content');
- if ($nodes = node_get_recent($settings['node_count'])) {
- $block['content'] = array(
- '#theme' => 'node_recent_block',
- '#nodes' => $nodes,
- );
- }
- else {
- $block['content'] = t('No content available.');
- }
- }
- break;
-
- }
-
- return $block;
- }
-
- * Implements hook_block_configure().
- */
- function node_block_configure($delta = '', $settings = array()) {
- $form = array();
- if ($delta == 'recent') {
- $settings += array(
- 'node_count' => 10,
- );
- $form['node_count'] = array(
- '#type' => 'select',
- '#title' => t('Number of recent content items to display'),
- '#default_value' => $settings['node_count'],
- '#options' => backdrop_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)),
- );
- }
- if ($delta == 'syndicate') {
- $form['syndicate_settings'] = array(
- '#type' => 'radios',
- '#title' => t('Choose the linked feed'),
- '#default_value' => isset($settings['syndicate_settings']) ? $settings['syndicate_settings'] : 'promoted',
- '#options' => array(
- 'promoted' => t('Always show RSS link for promoted content'),
- 'page_content' => t('Show RSS link for the current page, if available'),
- ),
- );
- }
- return $form;
- }
-
- * Returns a themed RSS icon which links to a provided feed.
- *
- * @param array $settings
- * Block configuration settings.
- */
- function node_syndicate_content(array $settings) {
- if (isset($settings['syndicate_settings']) && $settings['syndicate_settings'] == 'page_content') {
- return backdrop_get_feeds();
- }
-
- return array(
- '#theme' => 'feed_icon',
- '#url' => 'rss.xml',
- '#title' => t('Subscribe to promoted content'),
- );
- }
-
- * Finds the most recently changed nodes that are available to the current user.
- *
- * @param $number
- * (optional) The maximum number of nodes to find. Defaults to 10.
- *
- * @return
- * An array of node entities or an empty array if there are no recent nodes
- * visible to the current user.
- */
- function node_get_recent($number = 10) {
- $query = db_select('node', 'n');
-
- if (!user_access('bypass node access') && !user_access('view any 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();
- if (user_access('view own unpublished content') && $own_unpublished) {
- $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();
- }
-
- * Page callback: Generates and prints an RSS feed.
- *
- * Generates an RSS feed from an array of node IDs, and prints it with an HTTP
- * header, with Content Type set to RSS/XML.
- *
- * @param $nids
- * (optional) An array of node IDs (nid). Defaults to FALSE so empty feeds can
- * be generated with passing an empty array, if no items are to be added
- * to the feed.
- * @param $channel
- * (optional) An associative array containing 'title', 'link', 'description',
- * and other keys, to be parsed by format_rss_channel() and
- * format_xml_elements(). A list of channel elements can be found at the
- * @link http://cyber.law.harvard.edu/rss/rss.html RSS 2.0 Specification. @endlink
- * The link should be an absolute URL.
- *
- * @see node_menu()
- *
- * @deprecated since 1.5.0
- */
- function node_feed($nids = FALSE, $channel = array()) {
- global $base_url, $language_content;
- $rss_config = config('system.core');
-
- 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, $rss_config->get('rss_limit'))
- ->addTag('node_access')
- ->execute()
- ->fetchCol();
- }
-
- $item_length = $rss_config->get('rss_viewmode');
- $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' => user_format_name($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 .= backdrop_render($build);
- }
-
- $items .= format_rss_item($node->title, $node->link, $item_text, $node->rss_elements);
- }
-
- $channel_defaults = array(
- 'version' => '2.0',
- 'title' => config_get_translated('system.core', 'site_name'),
- 'link' => $base_url,
- 'description' => $rss_config->get('rss_description'),
- 'language' => $language_content->langcode
- );
- $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 . "\" " . backdrop_attributes($namespaces) . ">\n";
- $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language'], $channel_extras);
- $output .= "</rss>\n";
-
- backdrop_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8');
- print $output;
- }
-
- * Constructs a backdrop_render() style array from an array of loaded nodes.
- *
- * @param $nodes
- * An array of nodes as returned by node_load_multiple().
- * @param $view_mode
- * (optional) Display mode, e.g. 'full' or 'teaser'. Defaults to 'teaser.'
- * @param $weight
- * (optional) Integer representing the weight of the first node in the list.
- * @param $langcode
- * (optional) A language code to use for rendering. Defaults to NULL which is
- * the global content language of the current request.
- *
- * @return
- * An array in the format expected by backdrop_render().
- */
- 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);
-
- 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++;
- }
-
-
- backdrop_sort($build['nodes'], array('#weight'));
- $build['nodes']['#sorted'] = TRUE;
-
- return $build;
- }
-
- * Menu callback; Generate a listing of promoted nodes.
- *
- * @return array
- * An array in the format expected by backdrop_render().
- *
- * @see node_menu()
- */
- function node_page_default() {
-
- $front = config_get('system.core', 'site_frontpage');
- if ($front != 'node') {
- backdrop_goto('<front>', array(), '301');
- }
- else {
- $site_config = config('system.core');
- $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($site_config->get('default_nodes_main'))
- ->addTag('node_access');
-
- $nids = $select->execute()->fetchCol();
-
- if (!empty($nids)) {
- $nodes = node_load_multiple($nids);
- $build = node_view_multiple($nodes);
-
-
- backdrop_add_feed('rss.xml', $site_config->getTranslated('site_name') . ' ' . t('RSS'));
- $build['pager'] = array(
- '#theme' => 'pager',
- '#weight' => 5,
- );
- backdrop_set_title('');
- }
- else {
- backdrop_set_title(t('Welcome to @site-name', array('@site-name' => $site_config->getTranslated('site_name'))), PASS_THROUGH);
-
- $default_message = '<p>' . t('No content has been promoted yet.') . '</p>';
- $default_links = array();
- if (_node_add_access()) {
- $default_links[] = l(t('Add 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;
- }
- }
-
- * Page callback: Displays a single node.
- *
- * @param Node $node
- * The node entity.
- *
- * @return
- * A page array suitable for use by backdrop_render().
- *
- * @see node_menu()
- */
- function node_page_view(Node $node) {
-
-
- $type = node_type_get_type($node);
- $bypass_hidden_path = user_access('view hidden paths');
- if ($type->settings['hidden_path'] && !$bypass_hidden_path) {
- backdrop_not_found();
- backdrop_exit();
- }
-
-
-
-
- backdrop_set_title($node->title);
-
- $uri = entity_uri('node', $node);
- $canonical_secure = config_get('system.core', 'canonical_secure') ? TRUE : FALSE;
- $uri_options = array('absolute' => TRUE, 'https' => $canonical_secure);
- backdrop_add_html_head_link(array('rel' => 'canonical', 'href' => url($uri['path'], array_merge($uri['options'], $uri_options))), TRUE);
-
-
- if ($type->settings['hidden_path']) {
- $message = t('Only people with the <em>View hidden paths</em> permission will be able to view this page. Everyone else will receive a "Page not found" error.');
- backdrop_set_message($message, 'info');
- }
-
- return node_show($node);
- }
-
- * Implements hook_update_index().
- */
- function node_update_index() {
- $limit = (int) config_get('search.settings', 'search_cron_limit');
-
-
- $enabled_types = _node_search_get_types();
- $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) AND n.type IN (:enabled_types) ORDER BY d.reindex ASC, n.nid ASC", 0, $limit, array(':enabled_types' => $enabled_types), array('target' => 'replica'));
- $nids = $result->fetchCol();
- if (!$nids) {
- return;
- }
-
- foreach (node_load_multiple($nids) as $node) {
- _node_index_node($node);
- }
- }
-
- * Indexes a single node.
- *
- * @param Node $node
- * The node to index.
- */
- function _node_index_node(Node $node) {
-
-
-
- state_set('node_cron_last', (int) $node->changed);
-
-
- $build = node_view($node, 'search_index');
- unset($build['#theme']);
- $node->rendered = backdrop_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);
- }
-
- * Get the list of node types that are enabled for indexing.
- *
- * @return array
- * An unindexed array of node type machine names.
- */
- function _node_search_get_types() {
- $node_types = config_get('search.settings', 'node_types');
-
- if (empty($node_types)) {
- $node_types = array_keys(node_type_get_names());
- }
- return $node_types;
- }
-
- * Implements hook_form_FORM_ID_alter().
- *
- * @see node_search_validate()
- */
- 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();
- $search_content_types = _node_search_get_types();
- foreach (node_type_get_types() as $type => $detail) {
- if (in_array($type, $search_content_types)) {
- if (!$detail->settings['hidden_path'] || user_access('view hidden paths') ) {
- $types[$type] = $detail->name;
- }
- }
- }
- $form['advanced']['type'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Only of the type(s)'),
- '#prefix' => '<div class="criterion">',
- '#suffix' => '</div>',
- '#options' => $types,
- );
- $form['advanced']['actions'] = array('#type' => 'actions');
- $form['advanced']['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Advanced search'),
- '#prefix' => '<div class="action">',
- '#suffix' => '</div>',
- '#weight' => 100,
- );
-
-
- $language_options = language_list(TRUE, TRUE);
- 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';
- }
- }
-
- * Form validation handler for node_form_search_form_alter().
- */
- 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, 'langcode', 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);
- }
- }
-
- * Implements hook_form_FORM_ID_alter().
- *
- * Alters the theme form to use the admin theme on node editing.
- *
- * @see node_form_system_themes_admin_form_submit()
- */
- function node_form_system_themes_admin_form_alter(&$form, &$form_state, $form_id) {
- $form['admin_theme']['node_admin_theme'] = array(
- '#type' => 'checkbox',
- '#title' => t('Use the administration theme when editing or creating content'),
- '#default_value' => config_get('system.core', 'node_admin_theme'),
- '#states' => array(
- 'visible' => array(
- array(
-
-
- ':input[name="admin_theme"]' => array('!value' => 0),
- ),
- ),
- ),
- );
- $form['#submit'][] = 'node_form_system_themes_admin_form_submit';
- }
-
- * Form submission handler for system_themes_admin_form().
- *
- * @see node_form_system_themes_admin_form_alter()
- */
- function node_form_system_themes_admin_form_submit($form, &$form_state) {
- config_set('system.core', 'node_admin_theme', $form_state['values']['node_admin_theme']);
-
-
- layout_reset_caches();
- }
-
- * @defgroup node_access Node access rights
- * @{
- * The node access system determines who can do what to which nodes.
- *
- * In determining access rights for a node, node_access() first checks whether
- * the user has the "bypass node access" permission. Such users have
- * unrestricted access to all nodes. user 1 will always pass this check.
- *
- * Next, all implementations of hook_node_access() will be called. Each
- * implementation may explicitly allow, explicitly deny, or ignore the access
- * request. If at least one module says to deny the request, it will be rejected.
- * If no modules deny the request and at least one says to allow it, the request
- * will be permitted.
- *
- * If all modules ignore the access request, then the node_access table is used
- * to determine access. All node access modules are queried using
- * hook_node_grants() to assemble a list of "grant IDs" for the user. This list
- * is compared against the table. If any row contains the node ID in question
- * (or 0, which stands for "all nodes"), one of the grant IDs returned, and a
- * value of TRUE for the operation in question, then access is granted. Note
- * that this table is a list of grants; any matching row is sufficient to
- * grant access to the node.
- *
- * In node listings (lists of nodes generated from a select query, such as the
- * default home page at path 'node', an RSS feed, a recent content block, etc.),
- * the process above is followed except that hook_node_access() is not called on
- * each node for performance reasons and for proper functioning of the pager
- * system. When adding a node listing to your module, be sure to use a dynamic
- * query created by db_select() and add a tag of "node_access". This will allow
- * modules dealing with node access to ensure only nodes to which the user has
- * access are retrieved, through the use of hook_query_TAG_alter(). Tagging a
- * query with "node_access" does not check the published/unpublished status of
- * nodes, so the base query is responsible for ensuring that unpublished nodes
- * are not displayed to inappropriate users.
- *
- * Note: Even a single module returning NODE_ACCESS_DENY from hook_node_access()
- * will block access to the node. Therefore, implementers should take care to
- * not deny access unless they really intend to. Unless a module wishes to
- * actively deny access it should return NODE_ACCESS_IGNORE (or return nothing)
- * to allow other modules or the node_access table to control access.
- *
- * To see how to write a node access module of your own, see
- * node_access_example.module.
- */
-
- * Access callback: Checks a user's permission for performing a node operation.
- *
- * @param string $op
- * The operation to be performed on the node. Possible values are:
- * - create
- * - view
- * - update
- * - delete
- * @param Node|string $node
- * The node entity on which the operation is to be performed, or the node type
- * (e.g., 'post') for the 'create' operation.
- * @param User $account
- * (optional) A user object representing the user for whom the operation is to
- * be performed. Determines access for a user other than the current user.
- *
- * @return bool
- * TRUE if the operation may be performed, FALSE otherwise.
- *
- * @see node_menu()
- */
- function node_access($op, $node, $account = NULL) {
- if ($op == 'create') {
-
- if (is_string($node)) {
- $bundle = $node;
- }
- else {
- $bundle = $node->bundle();
- }
- return Node::createAccess($bundle, $account);
- }
- elseif ($node instanceof Node) {
- return $node->access($op, $account);
- }
- return FALSE;
- }
-
- * Implements hook_node_access().
- *
- * @param Node|string $node
- * The loaded Node object.
- * @param string $op
- * The operation to be performed on the node. Possible values are:
- * - create
- * - view
- * - update
- * - delete
- * @param User $account
- * The User account for the person performing the operation.
- *
- * @return string
- */
- 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;
- }
-
- * Helper function to generate standard node permission list for a given type.
- *
- * @param $type
- * The machine-readable name of the node type.
- *
- * @return array
- * An array of permission names and descriptions.
- */
- 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;
- }
-
- * Returns an array of node types that should be managed by permissions.
- *
- * By default, this will include all node types in the system. To exclude a
- * specific node from getting permissions defined for it, set the
- * node_permissions_$type variable to 0. Core does not provide an interface for
- * doing so. However, contrib modules may exclude their own nodes in
- * hook_install(). Alternatively, contrib modules may configure all node types
- * at once, or decide to apply some other hook_node_access() implementation to
- * some or all node types.
- *
- * @return
- * An array of node types managed by this module.
- */
- function node_permissions_get_configured_types() {
-
- $configured_types = array();
-
- foreach (node_type_get_types() as $type => $info) {
- if ($info->settings['node_permissions']) {
- $configured_types[] = $type;
- }
- }
-
- return $configured_types;
- }
-
- * Fetches an array of permission IDs granted to the given user ID.
- *
- * The implementation here provides only the universal "all" grant. A node
- * access module should implement hook_node_grants() to provide a grant list for
- * the user.
- *
- * After the default grants have been loaded, we allow modules to alter the
- * grants array by reference. This hook allows for complex business logic to be
- * applied when integrating multiple node access modules.
- *
- * @param $op
- * The operation that the user is trying to perform.
- * @param $account
- * (optional) The user object for the user performing the operation. If
- * omitted, the current user is used.
- *
- * @return
- * An associative array in which the keys are realms, and the values are
- * arrays of grants for those realms.
- */
- function node_access_grants($op, $account = NULL) {
-
- if (!isset($account)) {
- $account = $GLOBALS['user'];
- }
-
-
- $grants = module_invoke_all('node_grants', $account, $op);
-
- backdrop_alter('node_grants', $grants, $account, $op);
-
- return array_merge(array('all' => array(0)), $grants);
- }
-
- * Determines whether the user has a global viewing grant for all nodes.
- *
- * Checks to see whether any module grants global 'view' access to a user
- * account; global 'view' access is encoded in the {node_access} table as a
- * grant with nid=0. If no node access modules are enabled, node.module defines
- * such a global 'view' access grant.
- *
- * This function is called when a node listing query is tagged with
- * 'node_access'; when this function returns TRUE, no node access joins are
- * added to the query.
- *
- * @param $account
- * (optional) The user object for the user whose access is being checked. If
- * omitted, the current user is used.
- *
- * @return
- * TRUE if 'view' access to all nodes is granted, FALSE otherwise.
- *
- * @see hook_node_grants()
- * @see _node_query_node_access_alter()
- */
- function node_access_view_all_nodes($account = NULL) {
- global $user;
- if (!$account) {
- $account = $user;
- }
-
-
- $access = &backdrop_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 = db_or();
- foreach (node_access_grants('view', $account) as $realm => $gids) {
- foreach ($gids as $gid) {
- $grants->condition(db_and()
- ->condition('gid', $gid)
- ->condition('realm', $realm)
- );
- }
- }
- if (count($grants) > 0 ) {
- $query->condition($grants);
- }
- $access[$account->uid] = $query
- ->execute()
- ->fetchField();
- }
-
- return $access[$account->uid];
- }
-
-
- * Implements hook_query_TAG_alter().
- *
- * This is the hook_query_alter() for queries tagged with 'node_access'. It adds
- * node access checks for the user account given by the 'account' meta-data (or
- * global $user if not provided), for an operation given by the 'op' meta-data
- * (or 'view' if not provided; other possible values are 'update' and 'delete').
- */
- function node_query_node_access_alter(QueryAlterableInterface $query) {
- _node_query_node_access_alter($query, 'node');
- if (module_exists('search')) {
- _node_search_query_alter($query);
- }
- }
-
- * Implements hook_query_TAG_alter().
- *
- * This function implements the same functionality as
- * node_query_node_access_alter() for the SQL field storage engine. Node access
- * conditions are added for field values belonging to nodes only.
- */
- function node_query_entity_field_access_alter(QueryAlterableInterface $query) {
- _node_query_node_access_alter($query, 'entity');
- }
-
- * Helper for node access functions.
- *
- * Queries tagged with 'node_access' that are not against the {node} table
- * should add the base table as metadata. For example:
- * @code
- * $query
- * ->addTag('node_access')
- * ->addMetaData('base_table', 'taxonomy_index');
- * @endcode
- *
- * Queries tagged with 'node_access' that are not against the {node} table
- * must add the base table as metadata. For example:
- * @code
- * $query
- * ->addTag('node_access')
- * ->addMetaData('base_table', 'taxonomy_index');
- * @endcode
- *
- * @param SelectQuery|QueryAlterableInterface $query
- * The query to which conditions will be added.
- * @param string $type
- * Either 'node' or 'entity' depending on what sort of query it is. See
- * node_query_node_access_alter() and node_query_entity_field_access_alter()
- * for more.
- *
- * @throws Exception
- * In the event that the query cannot be altered as expected.
- */
- 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;
- }
-
-
-
- if (!user_access('access content', $account)) {
- $query->range(0, 0);
- }
-
- $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 = backdrop_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 $node_alias => $tableinfo) {
- $table = $tableinfo['table'];
- if (!($table instanceof SelectQueryInterface) && $table == $base_table) {
-
- $subquery = db_select('node_access', 'na')
- ->fields('na', array('nid'));
-
- $grant_conditions = db_or();
-
-
- foreach ($grants as $realm => $gids) {
- foreach ($gids as $gid) {
- $grant_conditions->condition(db_and()
- ->condition('na.gid', $gid)
- ->condition('na.realm', $realm)
- );
- }
- }
-
-
- if (count($grant_conditions->conditions())) {
- $subquery->condition($grant_conditions);
- }
- $subquery->condition('na.grant_' . $op, 1, '>=');
- $field = 'nid';
-
- if ($type == 'entity') {
-
- $base_alias = $node_alias;
- $field = 'entity_id';
- }
- $subquery->where("$node_alias.$field = na.nid");
-
-
- if (isset($node_conditions)) {
- $node_conditions->exists($subquery);
- }
-
- else {
- $query->exists($subquery);
- }
- }
- }
-
- if (isset($node_conditions) && 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);
- }
-
- }
-
- * Exclude nodes from the search query in the special situations.
- *
- * - The node type is disabled in the search settings.
- * - The node type has hidden paths and the current user doesn't have permission to bypass the restriction.
- */
- function _node_search_query_alter(QueryAlterableInterface $query) {
- $search_table = FALSE;
- $node_type = FALSE;
-
- foreach ($query->getTables() as $alias => $table) {
- if ($table['table'] == 'search_index') {
- $search_table = $alias;
- }
- elseif ($table['table'] == 'node') {
- $node_type = $alias;
- }
- }
-
- if ($node_type && $search_table) {
- $enabled_types = _node_search_get_types();
- $all_types = node_type_get_types();
- $access_hidden_paths = user_access('view hidden paths');
-
- $excluded_content_types = array();
- foreach ($all_types as $type => $detail) {
- if (!$access_hidden_paths && $detail->settings['hidden_path']) {
- $excluded_content_types[] = $type;
- }
- elseif (!in_array($type, $enabled_types)) {
- $excluded_content_types[] = $type;
- }
- }
-
- if (!empty($excluded_content_types)) {
- $query->condition($node_type . '.type', array($excluded_content_types), 'NOT IN');
- }
- }
- }
-
- * Gets the list of node access grants and writes them to the database.
- *
- * This function is called when a node is saved, and can also be called by
- * modules if something other than a node save causes node access permissions to
- * change. It collects all node access grants for the node from
- * hook_node_access_records() implementations, allows these grants to be altered
- * via hook_node_access_records_alter() implementations, and saves the collected
- * and altered grants to the database.
- *
- * @param Node $node
- * The $node to acquire grants for.
- * @param $delete
- * (optional) Whether to delete existing node access records before inserting
- * new ones. Defaults to TRUE.
- */
- function node_access_acquire_grants(Node $node, $delete = TRUE) {
- $grants = module_invoke_all('node_access_records', $node);
-
- backdrop_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);
- }
- _node_access_write_grants($node, $grants, NULL, $delete);
- }
-
- * Writes a list of grants to the database, deleting any previously saved ones.
- *
- * If a realm is provided, it will only delete grants from that realm, but it
- * will always delete a grant from the 'all' realm. Modules that utilize
- * node_access() can use this function when doing mass updates due to widespread
- * permission changes.
- *
- * Note: Don't call this function directly from a contributed module. Call
- * node_access_acquire_grants() instead.
- *
- * @param Node $node
- * The node whose grants are being written. All that is necessary is that it
- * contains a nid.
- * @param $grants
- * A list of grants to write. Each grant is an array that must contain the
- * following keys: realm, gid, grant_view, grant_update, grant_delete.
- * The realm is specified by a particular module; the gid is as well, and
- * is a module-defined id to define grant privileges. each grant_* field
- * is a boolean value.
- * @param $realm
- * (optional) If provided, read/write grants for that realm only.
- * @param $delete
- * (optional) If false, does not delete records. This is only for optimization
- * purposes, and assumes the caller has already performed a mass delete of
- * some form. Defaults to TRUE.
- */
- function _node_access_write_grants(Node $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();
- }
- }
-
- * Toggles or reads the value of a flag for rebuilding the node access grants.
- *
- * When the flag is set, a message is displayed to users with 'access
- * administration pages' permission, pointing to the 'rebuild' confirm form.
- * This can be used as an alternative to direct node_access_rebuild calls,
- * allowing administrators to decide when they want to perform the actual
- * (possibly time consuming) rebuild.
- * When unsure if the current user is an administrator, node_access_rebuild()
- * should be used instead.
- *
- * @param $rebuild
- * (optional) The boolean value to be written.
- *
- * @return bool|NULL
- * The current value of the flag if no value was provided for $rebuild.
- *
- * @see node_access_rebuild()
- */
- function node_access_needs_rebuild($rebuild = NULL) {
- if (!isset($rebuild)) {
- return state_get('node_access_needs_rebuild', FALSE);
- }
- elseif ($rebuild) {
- state_set('node_access_needs_rebuild', TRUE);
- }
- else {
- state_del('node_access_needs_rebuild');
- }
- }
-
- * Rebuilds the node access database.
- *
- * This rebuild is occasionally needed by modules that make system-wide changes
- * to access levels. When the rebuild is required by an admin-triggered action
- * (e.g module settings form), calling node_access_needs_rebuild(TRUE) instead
- * of node_access_rebuild() lets the user perform his changes and actually
- * rebuild only once he is done.
- *
- * Note: As of Drupal 6, node access modules are not required to (and actually
- * should not) call node_access_rebuild() in hook_enable/disable anymore.
- *
- * @param $batch_mode
- * (optional) Set to TRUE to process in 'batch' mode, spawning processing over
- * several HTTP requests (thus avoiding the risk of PHP timeout if the site
- * has a large number of nodes). hook_update_N() and any form submit handler
- * are safe contexts to use the 'batch mode'. Less decidable cases (such as
- * calls from hook_user(), hook_taxonomy(), etc.) might consider using the
- * non-batch mode.
- * @see 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 {
-
- backdrop_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)) {
- backdrop_set_message(t('Content permissions have been rebuilt.'));
- node_access_needs_rebuild(FALSE);
- cache_clear_all();
- }
- }
-
- * Performs batch operation for node_access_rebuild().
- *
- * This is a multistep operation: we go through all nodes by packs of 20. The
- * batch processing engine interrupts processing and sends progress feedback
- * after 1 second execution time.
- *
- * @param array $context
- * An array of contextual key/value information for rebuild batch process.
- */
- 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'];
- }
- }
-
- * Performs post-processing for node_access_rebuild().
- *
- * @param bool $success
- * A boolean indicating whether the re-build process has completed.
- * @param array $results
- * An array of results information.
- * @param array $operations
- * An array of function calls (not used in this function).
- */
- function _node_access_rebuild_batch_finished($success, $results, $operations) {
- if ($success) {
- backdrop_set_message(t('The content access permissions have been rebuilt.'));
- node_access_needs_rebuild(FALSE);
- }
- else {
- backdrop_set_message(t('The content access permissions have not been properly rebuilt.'), 'error');
- }
- cache_clear_all();
- }
-
- * @} End of "defgroup node_access".
- */
-
-
- * @defgroup node_content Hook implementations for user-created content types
- * @{
- * Functions that implement hooks for user-created content types.
- */
-
- * Implements hook_form().
- */
- function node_content_form(Node $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;
- }
-
- * @} End of "defgroup node_content".
- */
-
- * Implements hook_forms().
- *
- * All node forms share the same form handler.
- */
- 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;
- }
-
- * Implements hook_action_info().
- */
- function node_action_info() {
- return array(
- 'node_publish_action' => array(
- 'type' => 'node',
- 'label' => t('Publish content'),
- 'callback' => 'node_publish_action',
- 'file' => 'node.actions.inc'
- ),
- 'node_unpublish_action' => array(
- 'type' => 'node',
- 'label' => t('Unpublish content'),
- 'callback' => 'node_unpublish_action',
- 'file' => 'node.actions.inc',
- ),
- 'node_make_sticky_action' => array(
- 'type' => 'node',
- 'label' => t('Make content sticky'),
- 'callback' => 'node_make_sticky_action',
- 'file' => 'node.actions.inc',
- ),
- 'node_make_unsticky_action' => array(
- 'type' => 'node',
- 'label' => t('Make content unsticky'),
- 'callback' => 'node_make_unsticky_action',
- 'file' => 'node.actions.inc',
- ),
- 'node_promote_action' => array(
- 'type' => 'node',
- 'label' => t('Promote content'),
- 'callback' => 'node_promote_action',
- 'file' => 'node.actions.inc',
- ),
- 'node_unpromote_action' => array(
- 'type' => 'node',
- 'label' => t('Remove promotion'),
- 'callback' => 'node_unpromote_action',
- 'file' => 'node.actions.inc',
- ),
- 'node_delete_action' => array(
- 'type' => 'node',
- 'label' => t('Delete content'),
- 'callback' => 'node_delete_action',
- 'file' => 'node.actions.inc',
- ),
- );
- }
-
- * Implements hook_requirements().
- */
- function node_requirements($phase) {
- $requirements = array();
- if ($phase === 'runtime') {
- $needs_rebuild = node_access_needs_rebuild();
- $grant_count = db_query('SELECT COUNT(*) FROM {node_access}')->fetchField();
-
-
-
-
-
- if ($needs_rebuild) {
- $value = t('Access permissions need to be rebuilt.');
- }
- elseif ($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');
- }
- $value .= ' (' . l(t('Rebuild permissions'), 'admin/reports/status/rebuild') . ')';
-
- if ($needs_rebuild) {
- $description = t('Node access permissions need to be rebuilt.');
- $severity = REQUIREMENT_ERROR;
- }
- else {
- $description = t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache.');
- $severity = REQUIREMENT_OK;
- }
-
-
- $description .= ' ' . t('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,
- 'severity' => $severity
- );
- }
- return $requirements;
- }
-
- * Implements hook_modules_enabled().
- */
- function node_modules_enabled($modules) {
-
-
- if (!node_access_needs_rebuild() && array_intersect($modules, module_implements('node_grants'))) {
- node_access_needs_rebuild(TRUE);
- }
-
-
-
- node_type_cache_reset();
-
-
-
- $node_types = node_type_get_types();
- foreach ($node_types as $type) {
- if (in_array($type->module, $modules)) {
- $type->disabled = FALSE;
- node_type_save($type);
- }
- }
- }
-
- * Implements hook_modules_disabled().
- */
- function node_modules_disabled($modules) {
-
-
- foreach ($modules as $module) {
-
-
-
- if (!node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
- node_access_needs_rebuild(TRUE);
- }
- }
-
-
-
- if (node_access_needs_rebuild() && count(module_implements('node_grants')) == 0) {
- node_access_rebuild();
- }
-
-
-
- $node_types = node_type_get_types();
- foreach ($node_types as $type) {
- if (in_array($type->module, $modules)) {
- $type->disabled = TRUE;
- node_type_save($type);
- }
- }
- }
-
- * Implements hook_autoload_info().
- */
- function node_autoload_info() {
- return array(
- 'Node' => 'node.entity.inc',
- 'NodeStorageController' => 'node.entity.inc',
-
- 'NodeBlock' => 'node.block.inc',
-
-
- 'views_handler_argument_node_created_fulldate' => 'views/views_handler_argument_dates_various.inc',
- 'views_handler_argument_node_created_year' => 'views/views_handler_argument_dates_various.inc',
- 'views_handler_argument_node_created_year_month' => 'views/views_handler_argument_dates_various.inc',
- 'views_handler_argument_node_created_month' => 'views/views_handler_argument_dates_various.inc',
- 'views_handler_argument_node_created_day' => 'views/views_handler_argument_dates_various.inc',
- 'views_handler_argument_node_created_week' => 'views/views_handler_argument_dates_various.inc',
- 'views_handler_argument_node_language' => 'views/views_handler_argument_node_language.inc',
- 'views_handler_argument_node_nid' => 'views/views_handler_argument_node_nid.inc',
- 'views_handler_argument_node_type' => 'views/views_handler_argument_node_type.inc',
- 'views_handler_argument_node_vid' => 'views/views_handler_argument_node_vid.inc',
- 'views_handler_argument_node_uid_revision' => 'views/views_handler_argument_node_uid_revision.inc',
- 'views_handler_field_history_user_timestamp' => 'views/views_handler_field_history_user_timestamp.inc',
- 'views_handler_field_node' => 'views/views_handler_field_node.inc',
- 'views_handler_field_node_link' => 'views/views_handler_field_node_link.inc',
- 'views_handler_field_node_link_delete' => 'views/views_handler_field_node_link_delete.inc',
- 'views_handler_field_node_link_edit' => 'views/views_handler_field_node_link_edit.inc',
- 'views_handler_field_node_revision' => 'views/views_handler_field_node_revision.inc',
- 'views_handler_field_node_revision_link' => 'views/views_handler_field_node_revision_link.inc',
- 'views_handler_field_node_revision_link_delete' => 'views/views_handler_field_node_revision_link_delete.inc',
- 'views_handler_field_node_revision_link_revert' => 'views/views_handler_field_node_revision_link_revert.inc',
- 'views_handler_field_node_path' => 'views/views_handler_field_node_path.inc',
- 'views_handler_field_node_type' => 'views/views_handler_field_node_type.inc',
- 'views_handler_filter_history_user_timestamp' => 'views/views_handler_filter_history_user_timestamp.inc',
- 'views_handler_filter_node_access' => 'views/views_handler_filter_node_access.inc',
- 'views_handler_filter_node_hidden_path' => 'views/views_handler_filter_node_hidden_path.inc',
- 'views_handler_filter_node_status' => 'views/views_handler_filter_node_status.inc',
- 'views_handler_filter_node_type' => 'views/views_handler_filter_node_type.inc',
- 'views_handler_filter_node_uid_revision' => 'views/views_handler_filter_node_uid_revision.inc',
- 'views_plugin_argument_default_node' => 'views/views_plugin_argument_default_node.inc',
- 'views_plugin_argument_validate_node' => 'views/views_plugin_argument_validate_node.inc',
- 'views_plugin_row_node_rss' => 'views/views_plugin_row_node_rss.inc',
- 'views_plugin_row_node_view' => 'views/views_plugin_row_node_view.inc',
- );
- }
-
- * Implements hook_config_info().
- */
- function node_config_info() {
- $prefixes['node.type'] = array(
- 'name_key' => 'type',
- 'label_key' => 'name',
- 'group' => t('Content types'),
- );
- return $prefixes;
- }
-
- * Implements hook_config_create_validate().
- */
- function node_config_create_validate(Config $staging_config, $all_changes) {
- $config_name = $staging_config->getName();
-
-
- if (strpos($config_name, 'field.instance.node.') === 0) {
- list($node_type, $field_name) = explode('.', str_replace('field.instance.node.', '', $config_name));
-
-
- $type_exists = (bool) node_type_get_type($node_type);
- $type_created = $all_changes['node.type.' . $node_type];
- if (!$type_exists && !$type_created) {
- throw new ConfigValidateException(t('The field "@name" cannot be added because the node type "@type" does not exist.', array('@name' => $field_name, '@type' => $node_type)));
- }
- }
- }
-
- * Implements hook_config_delete_validate().
- */
- function node_config_delete_validate(Config $active_config, $all_changes) {
- $config_name = $active_config->getName();
-
-
- if (strpos($config_name, 'node.type.') === 0) {
-
- $node_type = explode('.', $config_name);
- if (node_type_has_content($node_type[2])) {
- throw new ConfigValidateException(t('The content type "@content_type" cannot be deleted with active content associated to it. Delete the content manually, then retry the import.', array('@content_type' => $node_type[2])));
- }
- }
- }
-
- * Determine whether a node type has any data.
- *
- * @param $node_type
- * Name of bundle to check for content.
- * @return
- * TRUE if the bundle has content associated to it; FALSE otherwise.
- */
- function node_type_has_content($node_type) {
- $query = new EntityFieldQuery();
- $query = $query->entityCondition('entity_type', 'node')
- ->entityCondition('bundle', $node_type)
- ->range(0, 1)
- ->count()
-
-
-
- ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
-
- return (bool) $query
- ->execute() || (bool) $query
- ->age(FIELD_LOAD_REVISION)
- ->execute();
- }
-
- * Implements hook_file_download_access().
- */
- function node_file_download_access($field, $entity_type, $entity) {
- if ($entity_type == 'node') {
- return node_access('view', $entity);
- }
- }
-
- * Implements hook_language_delete().
- */
- function node_language_delete($language) {
-
- db_update('node')
- ->fields(array('langcode' => ''))
- ->condition('langcode', $language->langcode)
- ->execute();
- }
-
- * Get a node from the tempstore.
- *
- * @param string $node_tempstore_id
- * The tempstore ID of the node item to load.
- *
- * @return Node|FALSE
- * A fully-populated node entity, or FALSE if the node is not found.
- *
- * @since 1.11.0
- */
- function node_get_node_tempstore($node_tempstore_id) {
- $caches = &backdrop_static(__FUNCTION__, array());
- if (!isset($caches[$node_tempstore_id])) {
-
- $item = tempstore_get('node_tempstore', $node_tempstore_id);
- $caches[$node_tempstore_id] = $item;
- }
-
- return $caches[$node_tempstore_id];
- }
-
- * Store changes to a node or menu item in the temporary store.
- *
- * @param Node $item
- * The node item to save into tempstore.
- * @param string $node_tempstore_id
- * The tempstore ID of the node being saved to the object cache.
- *
- * @since 1.11.0
- */
- function node_set_node_tempstore($item, $node_tempstore_id) {
- $item->locked = array(
- 'uid' => $GLOBALS['user']->uid,
- 'updated' => REQUEST_TIME,
- );
-
- tempstore_set('node_tempstore', $node_tempstore_id, $item, REQUEST_TIME + 86400);
- }
-
- * Remove an item from the object cache.
- *
- * @param string $node_tempstore_id
- * The tempstore ID of the node to be deleted from the object cache.
- *
- * @since 1.11.0
- */
- function node_clear_node_tempstore($node_tempstore_id) {
- tempstore_clear('node_tempstore', $node_tempstore_id);
- }
-
- * Load a node from the tempstore.
- *
- * @param int $node_tempstore_id
- * The ID of a tempstore object.
- *
- * @return Node|false
- * A fully-populated node entity, or FALSE if the node is not found.
- *
- * @since 1.11.0
- */
- function node_tempstore_load($node_tempstore_id) {
- return node_get_node_tempstore($node_tempstore_id);
- }
-
- * Build tempstore ID.
- *
- * @return string $node_tempstore_id
- * A unique string, or the current tempstore ID if set in the URL.
- *
- * @since 1.11.0
- */
- function node_build_tempstore_id() {
- if (isset($_GET['node_tempstore_id'])) {
- $node_tempstore_id = $_GET['node_tempstore_id'];
- }
- else {
- $uuid = new Uuid();
- $node_tempstore_id = $uuid->generate();
- }
- return $node_tempstore_id;
- }