Commit 28748628 authored by alexpott's avatar alexpott

Issue #2380615 by dawehner, swentel, larowlan: Result of book_node_load()...

Issue #2380615 by dawehner, swentel, larowlan: Result of book_node_load() should not vary depending on user permissions
parent 9917b07b
......@@ -238,6 +238,10 @@ function book_node_load($nodes) {
function book_node_view(array &$build, EntityInterface $node, EntityViewDisplayInterface $display, $view_mode) {
if ($view_mode == 'full') {
if (!empty($node->book['bid']) && empty($node->in_preview)) {
$book_node = Node::load($node->book['bid']);
if (!$book_node->access()) {
return;
}
$book_navigation = array( '#theme' => 'book_navigation', '#book_link' => $node->book);
$build['book_navigation'] = array(
'#markup' => drupal_render($book_navigation),
......
......@@ -695,7 +695,7 @@ public function loadBookLink($nid, $translate = TRUE) {
* {@inheritdoc}
*/
public function loadBookLinks($nids, $translate = TRUE) {
$result = $this->bookOutlineStorage->loadMultiple($nids);
$result = $this->bookOutlineStorage->loadMultiple($nids, $translate);
$links = array();
foreach ($result as $link) {
if ($translate) {
......
......@@ -57,6 +57,12 @@ public function getActiveTrailIds($bid, $link);
/**
* Loads a single book entry.
*
* The entries of a book entry is documented in
* \Drupal\book\BookOutlineStorageInterface::loadMultiple.
*
* If $translate is TRUE, it also checks access ('access' key) and
* loads the title from the node itself.
*
* @param int $nid
* The node ID of the book.
* @param bool $translate
......@@ -64,12 +70,20 @@ public function getActiveTrailIds($bid, $link);
*
* @return array
* The book data of that node.
*
* @see \Drupal\book\BookOutlineStorageInterface::loadMultiple
*/
public function loadBookLink($nid, $translate = TRUE);
/**
* Loads multiple book entries.
*
* The entries of a book entry is documented in
* \Drupal\book\BookOutlineStorageInterface::loadMultiple.
*
* If $translate is TRUE, it also checks access ('access' key) and
* loads the title from the node itself.
*
* @param int[] $nids
* An array of nids to load.
*
......@@ -78,6 +92,8 @@ public function loadBookLink($nid, $translate = TRUE);
*
* @return array[]
* The book data of each node keyed by NID.
*
* @see \Drupal\book\BookOutlineStorageInterface::loadMultiple
*/
public function loadBookLinks($nids, $translate = TRUE);
......
......@@ -47,12 +47,16 @@ public function hasBooks() {
/**
* {@inheritdoc}
*/
public function loadMultiple($nids) {
public function loadMultiple($nids, $access = TRUE) {
$query = $this->connection->select('book', 'b', array('fetch' => \PDO::FETCH_ASSOC));
$query->fields('b');
$query->condition('b.nid', $nids);
$query->addTag('node_access');
$query->addMetaData('base_table', 'book');
if ($access) {
$query->addTag('node_access');
$query->addMetaData('base_table', 'book');
}
return $query->execute();
}
......
......@@ -31,13 +31,23 @@ public function hasBooks();
/**
* Loads books.
*
* Each book entry consists of the following keys:
* - bid: The node ID of the main book.
* - nid: The node ID of the book entry itself.
* - pid: The parent node ID of the book.
* - has_children: A boolean to indicate whether the book has children.
* - weight: The weight of the book entry to order siblings.
* - depth: The depth in the menu hierarchy the entry is placed into.
*
* @param array $nids
* An array of node IDs.
* @param bool $access
* Whether access checking should be taken into account.
*
* @return array
* Array of loaded book items.
*/
public function loadMultiple($nids);
public function loadMultiple($nids, $access = TRUE);
/**
* Gets child relative depth.
......
......@@ -52,6 +52,13 @@ class BookTest extends WebTestBase {
*/
protected $adminUser;
/**
* A user without the 'node test view' permission.
*
* @var \Drupal\user\UserInterface
*/
protected $webUserWithoutNodeAccess;
protected function setUp() {
parent::setUp();
......@@ -61,6 +68,7 @@ protected function setUp() {
// Create users.
$this->bookAuthor = $this->drupalCreateUser(array('create new books', 'create book content', 'edit own book content', 'add content to books'));
$this->webUser = $this->drupalCreateUser(array('access printer-friendly version', 'node test view'));
$this->webUserWithoutNodeAccess = $this->drupalCreateUser(array('access printer-friendly version'));
$this->adminUser = $this->drupalCreateUser(array('create new books', 'create book content', 'edit own book content', 'add content to books', 'administer blocks', 'administer permissions', 'administer book outlines', 'node test view', 'administer content types', 'administer site configuration'));
}
......@@ -660,4 +668,35 @@ public function testAdminBookListing() {
$this->assertText($this->book->label(), 'The book title is displayed on the administrative book listing page.');
}
/**
* Ensure the loaded book in hook_node_load() does not depend on the user.
*/
public function testHookNodeLoadAccess() {
\Drupal::service('module_installer')->install(['node_access_test']);
// Ensure that the loaded book in hook_node_load() does NOT depend on the
// current user.
$this->drupalLogin($this->bookAuthor);
$this->book = $this->createBookNode('new');
// Reset any internal static caching.
$node_storage = \Drupal::entityManager()->getStorage('node');
$node_storage->resetCache();
// Login as user without access to the book node, so no 'node test view'
// permission.
// @see node_access_test_node_grants().
$this->drupalLogin($this->webUserWithoutNodeAccess);
$book_node = $node_storage->load($this->book->id());
$this->assertTrue(!empty($book_node->book));
$this->assertEqual($book_node->book['bid'], $this->book->id());
// Reset the internal cache to retrigger the hook_node_load() call.
$node_storage->resetCache();
$this->drupalLogin($this->webUser);
$book_node = $node_storage->load($this->book->id());
$this->assertTrue(!empty($book_node->book));
$this->assertEqual($book_node->book['bid'], $this->book->id());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment