diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php index 77b96d6..8fa68b0 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php @@ -29,6 +29,16 @@ class NodeAccessLanguageTest extends NodeTestBase { } } + /** + * Asserts node_access_grants correctly returns permission IDs + */ + function assertNodeAccessGrants($ops, $node, $account, $langcode = NULL) { + foreach ($ops as $op => $result) { + $msg = t("node_access returns @result with operation '@op', language code @langcode.", array('@result' => $result ? 'true' : 'false', '@op' => $op, '@langcode' => !empty($langcode) ? "'$langcode'" : 'empty')); + $this->assertEqual($result, node_access_grants($op, $account), $msg); + } + } + function setUp() { parent::setUp(array('language', 'node_access_test')); // Clear permissions for authenticated users. @@ -77,4 +87,44 @@ class NodeAccessLanguageTest extends NodeTestBase { // Tests that Catalan is not accessible anymore. $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE), $node, $web_user, 'ca'); } + /** + * Runs tests for node_access_grants function with multiple languages. + */ + function testNodeAccessGrants() { + // Add Hungarian and Catalan. + $language = (object) array( + 'langcode' => 'hu', + ); + language_save($language); + $language = (object) array( + 'langcode' => 'ca', + ); + language_save($language); + + // Tests the default access provided for a published Hungarian node. + $web_user = $this->drupalCreateUser(array('access content')); + $node = $this->drupalCreateNode(array('body' => array('hu' => array(array())), 'langcode' => 'hu')); + $this->assertTrue($node->langcode == 'hu', t('Node created as Hungarian.')); + $expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE); + $this->assertNodeAccessGrants($expected_node_access, $node, $web_user); + + // Tests that Hungarian provided specifically results in the same. + $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'hu'); + + // There is no specific Catalan version of this node and Croatian is not + // even set up on the system in this scenario, so these languages will not + // play a role in the node's permissions. + $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'ca'); + $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'hr'); + + // Reset the node access cache and turn on our test node_access() code. + drupal_static_reset('node_access'); + variable_set('node_access_test_secret_catalan', 1); + + // Tests that Hungarian is still accessible. + $this->assertNodeAccessGrants($expected_node_access, $node, $web_user, 'hu'); + + // Tests that Catalan is not accessible anymore. + $this->assertNodeAccessGrants(array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE), $node, $web_user, 'ca'); + } } diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php index 9719fc0..3dac85f 100644 --- a/core/modules/node/node.api.php +++ b/core/modules/node/node.api.php @@ -233,10 +233,13 @@ function hook_node_grants($account, $op) { * of this gid within this realm can edit this node. * - 'grant_delete': If set to 1 a user that has been identified as a member * of this gid within this realm can delete this node. + * - 'langcode': Optional key. The language code of the grant version. This + * value is set automatically from the $node parameter during database + * storage. * * - * When an implementation is interested in a node but want to deny access to - * everyone, it may return a "deny all" grant: + * When an implementation is interested in a node in Catalan language, but want + * to deny access to everyone, it may return a "deny all" grant: * * @code * $grants[] = array( @@ -246,6 +249,7 @@ function hook_node_grants($account, $op) { * 'grant_update' => 0, * 'grant_delete' => 0, * 'priority' => 1, + * 'langcode' => 'ca' * ); * @endcode * @@ -269,7 +273,7 @@ function hook_node_access_records(Drupal\node\Node $node) { // treated just like any other node and we completely ignore it. if ($node->private) { $grants = array(); - // Only published nodes should be viewable to all users. If we allow access + // Only published Catalan nodes should be viewable to all users. If we allow access // blindly here, then all users could view an unpublished node. if ($node->status) { $grants[] = array( @@ -278,6 +282,7 @@ function hook_node_access_records(Drupal\node\Node $node) { 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, + 'langcode' => 'ca' ); } // For the example_author array, the GID is equivalent to a UID, which @@ -290,6 +295,7 @@ function hook_node_access_records(Drupal\node\Node $node) { 'grant_view' => 1, 'grant_update' => 1, 'grant_delete' => 1, + 'langcode' => 'ca' ); return $grants; diff --git a/core/modules/node/node.install b/core/modules/node/node.install index 7382320..157a3ed 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -141,6 +141,13 @@ function node_schema() { 'not null' => TRUE, 'default' => 0, ), + 'langcode' => array( + 'description' => 'The {language}.langcode of this node.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), 'gid' => array( 'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.", 'type' => 'int', @@ -568,6 +575,21 @@ function node_update_8003() { } /** + * Add language.langcode field to node_access table. + */ +function node_update_8004() { + // Add the langcode field. + $langcode_field = array( + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The {language}.langcode of this node.', + ); + db_add_field('node_access', 'langcode', $langcode_field); +} + +/** * @} End of "addtogroup updates-7.x-to-8.x" * The next series of updates should start at 9000. */ diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 3db5bbd..6cf1ee8 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -3426,7 +3426,9 @@ function node_access_acquire_grants(Node $node, $delete = TRUE) { * 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. + * following keys: realm, gid, grant_view, grant_update, grant_delete and + * langcode is an optional key which is set automatically from $node + * parameter. * 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. @@ -3448,7 +3450,7 @@ function _node_access_write_grants(Node $node, $grants, $realm = NULL, $delete = // Only perform work when node_access modules are active. if (!empty($grants) && count(module_implements('node_grants'))) { - $query = db_insert('node_access')->fields(array('nid', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete')); + $query = db_insert('node_access')->fields(array('nid', 'langcode', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete')); foreach ($grants as $grant) { if ($realm && $realm != $grant['realm']) { continue; @@ -3456,6 +3458,9 @@ function _node_access_write_grants(Node $node, $grants, $realm = NULL, $delete = // Only write grants; denies are implicit. if ($grant['grant_view'] || $grant['grant_update'] || $grant['grant_delete']) { $grant['nid'] = $node->nid; + if (!isset($grant['langcode'])) { + $grant['langcode'] = $node->langcode; + } $query->values($grant); } }