diff --git a/node_access_example/node_access_example.install b/node_access_example/node_access_example.install index 7b15c75..90e220b 100644 --- a/node_access_example/node_access_example.install +++ b/node_access_example/node_access_example.install @@ -1,28 +1,36 @@ 'field_example_private', 'entity_type' => 'node', 'type' => 'boolean', - )); + ]); $field_storage->save(); $field_storage->enable(); - $field = FieldConfig::create(array( + $field = FieldConfig::create([ 'field_name' => 'field_example_private', 'entity_type' => 'node', 'bundle' => 'article', 'label' => 'Example private', - 'settings' => array( + 'settings' => [ 'on_label' => 'Private', 'off_label' => 'Private', - ), - 'default_value' => array(array('value' => 0)), - )); + ], + 'default_value' => [['value' => 0]], + ]); $field->save(); // @TODO Make the field not hidden types/manage/article/form-display. diff --git a/node_access_example/node_access_example.module b/node_access_example/node_access_example.module index f2cb679..62d23ec 100644 --- a/node_access_example/node_access_example.module +++ b/node_access_example/node_access_example.module @@ -5,6 +5,8 @@ * Module file illustrating API-based node access. */ +use Drupal\Core\Session\AccountInterface; +use Drupal\node\NodeInterface; use Drupal\Core\Access\AccessResult; /** @@ -98,7 +100,7 @@ use Drupal\Core\Access\AccessResult; * * @see hook_node_access() */ -function node_access_example_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) { +function node_access_example_node_access(NodeInterface $node, $op, AccountInterface $account) { // If $node is a string, the node has not yet been created. We don't care // about that case. // (Is this still a thing?) @@ -106,7 +108,7 @@ function node_access_example_node_access(\Drupal\node\NodeInterface $node, $op, return AccessResult::neutral(); } if (($op == 'view' || $op == 'update') && $account->getAccountName() === 'foobar' && ($node->hasField('field_example_private') && (int) $node->field_example_private->value === 1)) { - drupal_set_message(t('Access to node @nid allowed because the user name (@name) is specifically allowed', array('@nid' => $node->id(), '@name' => $account->getAccountName()))); + drupal_set_message(t('Access to node @nid allowed because the user name (@name) is specifically allowed', ['@nid' => $node->id(), '@name' => $account->getAccountName()])); return AccessResult::allowed()->cachePerUser(); } return AccessResult::neutral(); @@ -154,20 +156,20 @@ define('NODE_ACCESS_EXAMPLE_GRANT_ALL', 23); * @see node_access_example_permission() * @see node_access_example_node_access_records() */ -function node_access_example_node_grants(\Drupal\Core\Session\AccountInterface $account, $op) { - $grants = array(); +function node_access_example_node_grants(AccountInterface $account, $op) { + $grants = []; // First grant a grant to the author for own content. // Do not grant to anonymous user else all anonymous users would be author. if ($account->id() > 0) { - $grants['node_access_example_author'] = array($account->id()); + $grants['node_access_example_author'] = [$account->id()]; } // Then, if "access any private content" is allowed to the account, // grant view, update, or delete as necessary. if ($op == 'view' && $account->hasPermission('access any private content')) { - $grants['node_access_example_view'] = array(NODE_ACCESS_EXAMPLE_GRANT_ALL); + $grants['node_access_example_view'] = [NODE_ACCESS_EXAMPLE_GRANT_ALL]; } if (($op == 'update' || $op == 'delete') && $account->hasPermission('edit any private content')) { - $grants['node_access_example_edit'] = array(NODE_ACCESS_EXAMPLE_GRANT_ALL); + $grants['node_access_example_edit'] = [NODE_ACCESS_EXAMPLE_GRANT_ALL]; } return $grants; } @@ -209,14 +211,13 @@ function node_access_example_node_grants(\Drupal\Core\Session\AccountInterface $ * * @see node_access_example_node_grants() */ -function node_access_example_node_access_records(\Drupal\node\NodeInterface $node) { +function node_access_example_node_access_records(NodeInterface $node) { // We only care about the node if it has been marked private. If not, it is // treated just like any other node and we completely ignore it. - // We cast the value of the field, because it returns as a string or an int // depending on the situation. if ($node->hasField('field_example_private') && (int) $node->field_example_private->value === 1) { - $grants = array(); + $grants = []; $grants[] = [ 'realm' => 'node_access_example_view', 'gid' => NODE_ACCESS_EXAMPLE_GRANT_ALL, diff --git a/node_access_example/src/Controller/NodeAccessExampleController.php b/node_access_example/src/Controller/NodeAccessExampleController.php index 5b2a42c..f45a8bd 100644 --- a/node_access_example/src/Controller/NodeAccessExampleController.php +++ b/node_access_example/src/Controller/NodeAccessExampleController.php @@ -17,10 +17,10 @@ class NodeAccessExampleController extends ControllerBase { '#markup' => $this->t('This example shows how a module can use the Drupal node access system to allow access to specific nodes. You will need to look at the code and then experiment with it by creating nodes, marking them private, and accessing them as various users.') . '', ]; $content['count'] = [ - '#markup' => $this->t('There are currently @num private nodes in the system @num_personal are yours.', array('@num' => $this->privateNodeCount(FALSE), '@num_personal' => $this->ownPrivateNodeCount())) . '', + '#markup' => $this->t('There are currently @num private nodes in the system @num_personal are yours.', ['@num' => $this->privateNodeCount(FALSE), '@num_personal' => $this->ownPrivateNodeCount()]) . '', ]; $content['owner'] = [ - '#markup' => $this->t('You have access to @num private nodes.', array('@num' => $this->privateNodeCount())) . '', + '#markup' => $this->t('You have access to @num private nodes.', ['@num' => $this->privateNodeCount()]) . '', ]; $content['list'] = [ '#type' => 'table', @@ -64,7 +64,7 @@ class NodeAccessExampleController extends ControllerBase { $nids = $query->execute(); $nodes = node_load_multiple($nids); - $results = array(); + $results = []; foreach ($nodes as $node) { $results[] = [ $node->id(), diff --git a/node_access_example/tests/src/Functional/NodeAccessExampleTest.php b/node_access_example/tests/src/Functional/NodeAccessExampleTest.php index 0bf2195..fa6140f 100644 --- a/node_access_example/tests/src/Functional/NodeAccessExampleTest.php +++ b/node_access_example/tests/src/Functional/NodeAccessExampleTest.php @@ -20,7 +20,7 @@ class NodeAccessExampleTest extends BrowserTestBase { * * @var array */ - public static $modules = array('node', 'search', 'node_access_example',); + public static $modules = ['node', 'search', 'node_access_example']; /** * The installation profile to use with this test. @@ -45,11 +45,11 @@ class NodeAccessExampleTest extends BrowserTestBase { protected function setUp() { parent::setUp(); - $permissions = array( + $permissions = [ 'administer content types', 'administer node fields', 'administer node form display', - ); + ]; $this->administratorAccount = $this->drupalCreateUser($permissions); $this->drupalLogin($this->administratorAccount); @@ -59,7 +59,7 @@ class NodeAccessExampleTest extends BrowserTestBase { $edit['fields[field_example_private][type]'] = 'boolean_checkbox'; $this->drupalPostForm('/admin/structure/types/manage/article/form-display', $edit, t('Save')); - $this->assertText(t('Your settings have been saved.')); + $this->assertSession()->pageTextContains(t('Your settings have been saved.')); } /** @@ -68,7 +68,7 @@ class NodeAccessExampleTest extends BrowserTestBase { public function testNodeAccessExample() { // Test that our page loads. $this->drupalGet('/examples/node-access-example'); - $this->assertResponse(200, 'Description page exists.'); + $this->assertSession()->statusCodeEquals(200); } /** @@ -96,17 +96,18 @@ class NodeAccessExampleTest extends BrowserTestBase { * - Test listings of nodes with 'node_access' tag on database search. */ public function testNodeAccessBasic() { + $web_assert = $this->assertSession(); $num_simple_users = 3; - $simple_users = array(); + $simple_users = []; // Nodes keyed by uid and nid: $nodes[$uid][$nid] = $is_private;. - $nodes_by_user = array(); + $nodes_by_user = []; // Titles keyed by nid. - $titles = array(); + $titles = []; // Array of nids marked private. - $private_nodes = array(); + $private_nodes = []; for ($i = 0; $i < $num_simple_users; $i++) { $simple_users[$i] = $this->drupalCreateUser([ 'administer content types', @@ -117,40 +118,42 @@ class NodeAccessExampleTest extends BrowserTestBase { } foreach ($simple_users as $web_user) { $this->drupalLogin($web_user); - foreach (array(0 => 'Public', 1 => 'Private') as $is_private => $type) { - $edit['title[0][value]'] = t('@private_public Article created by @user', array('@private_public' => $type, '@user' => $web_user->name)); + foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) { + $edit['title[0][value]'] = t('@private_public Article created by @user', ['@private_public' => $type, '@user' => $web_user->getUsername()]); if ($is_private) { $edit['field_example_private[value]'] = TRUE; $edit['body[0][value]'] = 'private node'; + $this->drupalPostForm('node/add/article', $edit, t('Save')); } else { $edit['body[0][value]'] = 'public node'; + $this->drupalPostForm('node/add/article', $edit, t('Save')); } - $this->drupalPostForm('node/add/article', $edit, t('Save')); - $this->assertText(t('Article @title has been created', array('@title' => $edit['body[0][value]']))); + $web_assert->pageTextContains(t('Article @title has been created', ['@title' => $edit['title[0][value]']])); $db = \Drupal::database(); $nid = $db->select('node_field_data', 'n'); - $nid->field('n', array('nid')) - ->condition('title', $edit['title']['0']['value']) - ->execute() - ->fetchField(); - $this->assertText(t('New node @nid was created and private=@private', array('@nid' => $nid, '@private' => $is_private))); - $private_status = $db->select('node__field_example_private','p'); - $private_status->fields('p', array('field_example_private_value')) - ->condition('entity_id', $nid) - ->exectute() - ->fetchField(); - $this->assertTrue($is_private == $private_status, 'Node was properly set to private or not private in node_access_example table.'); + $nid->fields('n', ['nid']) + ->condition('title', $edit['title[0][value]']) + ->execute() + ->fetchField(); + + $private_status = $db->select('node__field_example_private', 'p'); + $private_status->fields('p', ['field_example_private_value']) + ->condition('entity_id', $nid) + ->execute() + ->fetchField(); + + static::assertEquals($is_private, $private_status, 'Node was properly set to private or not private in node_access_example table.'); if ($is_private) { $private_nodes[] = $nid; } $titles[$nid] = $edit['title[0][value]']; $uid = \Drupal::currentUser()->id(); - $nodes_by_user[$uid][$nid] = $is_private; + $nodes_by_user[$uid][$nid][$is_private] = $is_private; } } // Build the search index. -// $this->cronRun(); + $this->drupalGet('cron/' . \Drupal::state()->get('system.cron_key')); foreach ($simple_users as $web_user) { $this->drupalLogin($web_user); // Check to see that we find the number of search results expected. @@ -158,12 +161,12 @@ class NodeAccessExampleTest extends BrowserTestBase { // Check own nodes to see that all are readable. foreach (array_keys($nodes_by_user) as $uid) { // All of this user's nodes should be readable to same. - $uid = \Drupal::currentUser()->id(); - if ($uid == $uid) { + $currentUserId = \Drupal::currentUser()->id(); + if ($uid == $currentUserId) { foreach ($nodes_by_user[$uid] as $nid => $is_private) { $this->drupalGet('node/' . $nid); - $this->assertResponse(200); - $this->assertTitle($titles[$nid] . ' | Drupal', 'Correct title for node found'); + $web_assert->statusCodeEquals(200); + $web_assert->titleEquals($titles[$nid] . ' | Drupal'); } } else { @@ -171,19 +174,9 @@ class NodeAccessExampleTest extends BrowserTestBase { // but we should be able to read non-private nodes. foreach ($nodes_by_user[$uid] as $nid => $is_private) { $this->drupalGet('node/' . $nid); - $this->assertResponse( - $is_private ? 403 : 200, - format_string('Node @nid by user @uid should get a @response for this user (@web_user_uid)', - array( - '@nid' => $nid, - '@uid' => $uid, - '@response' => $is_private ? 403 : 200, - '@web_user_uid' => $uid, - ) - ) - ); + $web_assert->statusCodeEquals($is_private ? 403 : 200); if (!$is_private) { - $this->assertTitle($titles[$nid] . ' | Drupal', 'Correct title for node was found'); + $web_assert->titleEquals($titles[$nid] . ' | Drupal'); } } } @@ -192,9 +185,9 @@ class NodeAccessExampleTest extends BrowserTestBase { // Check to see that the correct nodes are shown on examples/node_access. $this->drupalGet('examples/node-access-example'); $accessible = $this->xpath("//tr[contains(@class,'accessible')]"); - $this->assertEqual(count($accessible), 1, 'One private item accessible'); + $this->assertCount(1, $accessible, 'One private item accessible'); foreach ($accessible as $row) { - $this->assertEqual($row->td[2], $uid, 'Accessible row owned by this user'); + static::assertEquals($row->td[2], $uid, 'Accessible row owned by this user'); } } @@ -207,7 +200,8 @@ class NodeAccessExampleTest extends BrowserTestBase { if (($node) === FALSE) { continue; } - $this->checkNodeAccess($nid, FALSE, FALSE, FALSE); + $this->drupalGet('node/' . $nid); + $this->assertSession()->statusCodeEquals(403); } // Test that private nodes that don't have author are not accessible. @@ -216,12 +210,13 @@ class NodeAccessExampleTest extends BrowserTestBase { continue; } $original_uid = $node->getOwnerId(); - // Change node author to anonymus. + // Change node author to anonymous. $node->setOwnerId(0); $node->save(); $node = Node::load($nid); - $this->assertEqual($node->getOwnerId(), 0); - $this->checkNodeAccess($nid, FALSE, FALSE, FALSE); + static::assertEquals($node->getOwnerId(), 0); + $this->drupalGet('node/' . $nid); + $this->assertSession()->statusCodeEquals(403); // Change node to original author. $node->setOwnerId($original_uid); $node->save(); @@ -244,7 +239,7 @@ class NodeAccessExampleTest extends BrowserTestBase { foreach ($nodes_by_user as $uid => $private_status) { foreach ($private_status as $nid => $is_private) { $this->drupalGet('node/' . $nid); - $this->assertResponse(200); + $web_assert->statusCodeEquals(200); } } @@ -252,7 +247,7 @@ class NodeAccessExampleTest extends BrowserTestBase { // This user should be able to see all 3 of them. $this->drupalGet('examples/node-access-example'); $accessible = $this->xpath("//tr[contains(@class,'accessible')]"); - $this->assertEqual(count($accessible), 3); + $this->assertCount('3', $accessible); // Test that a user named 'foobar' can edit any private node due to // node_access_example_node_access(). Note that this user will not be @@ -269,9 +264,9 @@ class NodeAccessExampleTest extends BrowserTestBase { ); // Update the name of the user to 'foobar'. db_update('users_field_data') - ->fields(array( + ->fields([ 'name' => 'foobar', - )) + ]) ->condition('uid', $edit_user->uid) ->execute(); @@ -280,10 +275,10 @@ class NodeAccessExampleTest extends BrowserTestBase { // Try to edit each of the private nodes. foreach ($private_nodes as $nid) { - $body = $this->randomName(); + $body = $this->randomMachineName(); $edit['body][0][value]'] = $body; $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published')); - $this->assertText($this->t('has been updated'), 'Node was updated by "foobar" user'); + $web_assert->pageTextContains(t('has been updated')); } // Test that a privileged user can edit and delete private content. @@ -299,10 +294,10 @@ class NodeAccessExampleTest extends BrowserTestBase { $body = $this->randomMachineName(16); $edit = ['body[0][value]' => $body]; $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published')); - $this->assertText($this->t('has been updated')); - $this->drupalPostForm('node/' . $nid . '/edit', array(), t('Delete')); - $this->drupalPostForm(NULL, array(), t('Delete')); - $this->assertText($this->t('has been deleted')); + $web_assert->pageTextContains(t('has been updated')); + $this->drupalPostForm('node/' . $nid . '/edit', [], t('Delete')); + $this->drupalPostForm(NULL, [], t('Delete')); + $web_assert->pageTextContains(t('has been deleted')); } } @@ -321,60 +316,7 @@ class NodeAccessExampleTest extends BrowserTestBase { $edit['keys'] = $search_query; $this->drupalPostForm('search/node', $edit, t('Search')); $search_results = $this->xpath("//ol[contains(@class, 'search-results')]/li"); - $this->assertEqual(count($search_results), $expected_result_count, 'Found the expected number of search results'); - } - - /** - * Helper function. - * - * Test if there is access to an $url. - * - * @param bool $grant - * Access to the $url. - * @param string $url - * Url to make the get call. - * - * @return bool - * Get response - */ - protected function checkResponse($grant, $url) { - $this->drupalGet($url); - if ($grant) { - $response = $this->assertResponse(200); - } - else { - $response = $this->assertResponse(403); - } - return $response; - } - - /** - * Helper function. - * - * Test if a node with the id $nid has expected access grants. - * - * @param int $nid - * Node that will be checked. - * - * @return bool - * Checker ran succesfully - */ - protected function checkNodeAccess($nid, $grant_view, $grant_update, $grant_delete) { - // Test if node can be viewed. - if (!$this->checkResponse($grant_view, 'node/' . $nid)) { - return FALSE; - } - - // Test if private node can be edited. - if (!$this->checkResponse($grant_update, 'node/' . $nid . '/edit')) { - return FALSE; - } - - // Test if private node can be deleted. - if (!$this->checkResponse($grant_delete, 'node/' . $nid . '/delete')) { - return FALSE; - } - return TRUE; + $this->assertCount($expected_result_count, $search_results, 'Found the expected number of search results'); } }