diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php index 4a067ab40df919c0e3e98c8f5c6976e20971b6a7..9719fc0340113a4d8f688f5b1810f44be37fb92a 100644 --- a/core/modules/node/node.api.php +++ b/core/modules/node/node.api.php @@ -596,6 +596,8 @@ function hook_node_load($nodes, $types) { * - "view" * @param object $account * The user object to perform the access check operation on. + * @param object $langcode + * The language code to perform the access check operation on. * * @return integer * - NODE_ACCESS_ALLOW: if the operation is to be allowed. @@ -604,7 +606,7 @@ function hook_node_load($nodes, $types) { * * @ingroup node_access */ -function hook_node_access($node, $op, $account) { +function hook_node_access($node, $op, $account, $langcode) { $type = is_string($node) ? $node : $node->type; $configured_types = node_permissions_get_configured_types(); diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 70663a7c4189317616c413f2b7f6cbd418a11d82..319f4220734a451e59972c09442b19a0ff0100b1 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -2879,13 +2879,21 @@ function node_form_system_themes_admin_form_submit($form, &$form_state) { * @param $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. + * @param $langcode + * (optional) Language code for the variant of the node. Different language + * variants might have different permissions associated. If NULL, the + * original langcode of the node is used. * * @return * TRUE if the operation may be performed, FALSE otherwise. * * @see node_menu() + * + * @todo + * Add langcode support to node_access schema / queries. + * http://drupal.org/node/1658846 */ -function node_access($op, $node, $account = NULL) { +function node_access($op, $node, $account = NULL, $langcode = NULL) { $rights = &drupal_static(__FUNCTION__, array()); if (!$node || !in_array($op, array('view', 'update', 'delete', 'create'), TRUE)) { @@ -2903,18 +2911,25 @@ function node_access($op, $node, $account = NULL) { $cid = is_object($node) ? $node->nid : $node; + // If no language code was provided, default to the node's langcode or + // to an empty langcode if a node type was requested. The latter is purely + // for caching purposes. + if (empty($langcode)) { + $langcode = is_object($node) ? $node->langcode : ''; + } + // If we've already checked access for this node, user and op, return from // cache. - if (isset($rights[$account->uid][$cid][$op])) { - return $rights[$account->uid][$cid][$op]; + if (isset($rights[$account->uid][$cid][$langcode][$op])) { + return $rights[$account->uid][$cid][$langcode][$op]; } if (user_access('bypass node access', $account)) { - $rights[$account->uid][$cid][$op] = TRUE; + $rights[$account->uid][$cid][$langcode][$op] = TRUE; return TRUE; } if (!user_access('access content', $account)) { - $rights[$account->uid][$cid][$op] = FALSE; + $rights[$account->uid][$cid][$langcode][$op] = FALSE; return FALSE; } @@ -2923,19 +2938,19 @@ function node_access($op, $node, $account = NULL) { // - At least one module says to grant access. // If no module specified either allow or deny, we fall back to the // node_access table. - $access = module_invoke_all('node_access', $node, $op, $account); + $access = module_invoke_all('node_access', $node, $op, $account, $langcode); if (in_array(NODE_ACCESS_DENY, $access, TRUE)) { - $rights[$account->uid][$cid][$op] = FALSE; + $rights[$account->uid][$cid][$langcode][$op] = FALSE; return FALSE; } elseif (in_array(NODE_ACCESS_ALLOW, $access, TRUE)) { - $rights[$account->uid][$cid][$op] = TRUE; + $rights[$account->uid][$cid][$langcode][$op] = TRUE; return TRUE; } // Check if authors can view their own unpublished nodes. - if ($op == 'view' && !$node->status && user_access('view own unpublished content', $account) && $account->uid == $node->uid && $account->uid != 0) { - $rights[$account->uid][$cid][$op] = TRUE; + if ($op == 'view' && !$node->get('status', $langcode) && user_access('view own unpublished content', $account) && $account->uid == $node->get('uid', $langcode) && $account->uid != 0) { + $rights[$account->uid][$cid][$langcode][$op] = TRUE; return TRUE; } @@ -2968,13 +2983,13 @@ function node_access($op, $node, $account = NULL) { $result = (bool) $query ->execute() ->fetchField(); - $rights[$account->uid][$cid][$op] = $result; + $rights[$account->uid][$cid][$langcode][$op] = $result; return $result; } - elseif (is_object($node) && $op == 'view' && $node->status) { + elseif (is_object($node) && $op == 'view' && $node->get('status', $langcode)) { // If no modules implement hook_node_grants(), the default behavior is to // allow all users to view published nodes, so reflect that here. - $rights[$account->uid][$cid][$op] = TRUE; + $rights[$account->uid][$cid][$langcode][$op] = TRUE; return TRUE; } } diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/modules/node_access_test/node_access_test.module index b6c6127406dcf3f862a324b97d8949c18d72d3f3..5d557cc2a71ff6bbf2bc9070230e42ccb19c0ce9 100644 --- a/core/modules/node/tests/modules/node_access_test/node_access_test.module +++ b/core/modules/node/tests/modules/node_access_test/node_access_test.module @@ -231,3 +231,14 @@ function _node_access_test_node_write(Node $node) { ->execute(); } } + +/** + * Implements hook_node_access(). + */ +function node_access_test_node_access($node, $op, $account, $langcode) { + if (variable_get('node_access_test_secret_catalan', 0) && $langcode == 'ca') { + // Make all Catalan content secret. + return NODE_ACCESS_DENY; + } + return NODE_ACCESS_IGNORE; +}