To reproduce (with uid=1)
- install drupal 8.1.2 (or 8.1.x-dev, or 8.2.x-dev)
- enable Book module
- place "Book navigation" block to "Sidebar first" region
- set "Show block only on book pages" on block configuration interface
- create an Article and add it as a book (on "Book Outline" fieldgroup select "Create a new book")
- save as published - it is OK
- edit created article and unpublish it (save as unpublished)
- you will got an 500 error, with message:
Recoverable fatal error: Argument 1 passed to Drupal\book\BookManager::bookTreeOutput() must be of the type array, null given, called in .../core/modules/book/src/Plugin/Block/BookNavigationBlock.php on line 168 and defined in Drupal\book\BookManager->bookTreeOutput() (line 501 of .../core/modules/book/src/BookManager.php)

So if you have "Show block only on book pages" with unpublished parent book item, you get this fatal error and you have to disable book navigation block to view/edit this node.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

szato created an issue. See original summary.

szato’s picture

szato’s picture

Issue summary: View changes
szato’s picture

Issue summary: View changes
catch’s picture

dagmar’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 2: fatal_error_in_book-2743183-2.patch, failed testing.

szato’s picture

Status: Needs work » Needs review

Retest passed.

dawehner’s picture

Issue tags: +Needs tests

Let's ensure we add the test coverage to ensure to not break it again.

xjm’s picture

Priority: Critical » Major

@catch, @effulgentsia, @Cottser, @alexpott, and I discussed this issue today and agreed to handle it as a major issue per https://www.drupal.org/core/issue-priority#major-bug per these points specifically:

  • Interfere with normal site visitors' use of the site (for example, content in the wrong language, or validation errors for regular form submissions), even if there is a workaround.
  • Trigger a PHP error through the user interface, but only under rare circumstances or affecting only a small percentage of all users, even if there is a workaround.
  • Render one feature unusable with no workaround.

This issue fits in those categories. If, however, it is possible for the site to end up in a completely unrecoverable state, then this issue should be repromoted to critical. Thanks!

dawehner’s picture

Status: Needs review » Needs work

Needs work because we need some tests :(

@szato
Feel free to ping me, if you need some help with that.

szato’s picture

Assigned: Unassigned » szato
ressa’s picture

I just got hit by this one... does it look like the patch will make it into the next 8.1 release, or will we have to wait for Drupal 8.2?

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

szato’s picture

Status: Needs work » Needs review
FileSize
2.28 KB

Core patch and new test added.

szato’s picture

dawehner’s picture

+++ b/core/modules/book/src/Tests/BookTest.php
@@ -752,4 +752,32 @@ public function testHookNodeLoadAccess() {
+
+    $this->drupalLogout();

Note: We don't need to logout at the end here, the site is destroyed afterwords anyway ... Let's skip that.

szato’s picture

@dawehner thank you for your review.
$this->drupalLogout(); removed from my testBookNavigationBlockOnUnpublishedBook()

gnuget’s picture

Status: Needs review » Needs work

Hi @szato.

Thanks for your patch, A few nits:

  1. +++ b/core/modules/book/src/Tests/BookTest.php
    @@ -752,4 +752,30 @@ public function testHookNodeLoadAccess() {
    +  /**
    +   * Tests the book navigation block when book is unpublished.
    +   *
    +   * There was a fatal error with "Show block only on book pages" block mode:
    +   * @see https://www.drupal.org/node/2743183
    +   */
    

    It is not necessary pointing to a specific issue (unless there is a TODO there), you just need to describe what you are testing.

  2. +++ b/core/modules/book/src/Tests/BookTest.php
    @@ -752,4 +752,30 @@ public function testHookNodeLoadAccess() {
    +    $administratorUser = $this->drupalCreateUser(array('edit any book content', 'administer blocks', 'administer nodes', 'bypass node access'));
    

    There is already an adminUser check: $this->adminUser in that class.

  3. +++ b/core/modules/book/src/Tests/BookTest.php
    @@ -752,4 +752,30 @@ public function testHookNodeLoadAccess() {
    +    $edit = [];
    

    We are mixing the old array syntax with the short syntax, usually in new methods we use the short syntax.

    So, can you please change all the array() to []?

  4. I think this is not the best approach to fix this, with this patch if the top node of the book is unpublished we hide the entire Book Navigation block but if we are a user with the right permission (like an admin or if the node belongs to the user) we should be able to see this block even if the node is unpublished. I talked with Catch via IRC and he thinks to your approach is correct, so ignore this last point :-) Thanks!
nielsvandermolen’s picture

Adding a condition for published nodes also fixes the issue for me on 8.1.x.

ribel’s picture

I have tested patch applied by @nielsvandermolen in #20, and it fixes the issue on 8.1.x.

szato’s picture

@gnuget thank you for your review.

  1. Removed the link to the issue.
  2. Defined $this->adminUser don't have permission to manage unpublished nodes, because of that I created $administartorUser with needed permissions. I didn't want to mix the 'normal' admin user in the test with my 'superuser'. So I created $administratorUser only in that method.
  3. Changed to short format.
  4. This issue is about to avoid the fatal error. I agree, the perfect solution would be to show navigation block with unpublished nodes for users with right permissions, but I think it should be an another issue ('feature request').

Modified patch added (+ typo fix, + removed unneeded permission).

szato’s picture

Status: Needs work » Needs review
szato’s picture

Hi @nielsvandermolen,

your patch (navigation_block_8.1.x-2743183-20.patch) is matching to 8.2.x-dev too and also fix the issue. After applying to the core, the newly created testBookNavigationBlockOnUnpublishedBook() passes too ;)

gnuget’s picture

Version: 8.2.x-dev » 8.3.x-dev
Status: Needs review » Reviewed & tested by the community

looks good to me.

Thanks!

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
Issue tags: -Needs tests +Needs subsystem maintainer review

This error occurs because \Drupal\book\BookManager::doBookTreeCheckAccess() will set a tree to [] if the access is false.

One of the key parts of how we check book access is in \Drupal\book\BookManager::bookTreeCheckAccess()

      // @todo This should be actually filtering on the desired node status
      //   field language and just fall back to the default language.
      $nids = \Drupal::entityQuery('node')
        ->condition('nid', $nids, 'IN')
        ->condition('status', 1)
        ->execute();

So an alternative and perhaps better fix for this is to add something similar to the query in \Drupal\book\Plugin\Block\BookNavigationBlock::build(). What I'm saying is change:

$nid = $query->condition('nid', $node->book['bid'], '=')->execute();

to

$nid = $query
  ->condition('nid', $node->book['bid'], '=')
  ->condition('status', 1)
  ->execute();

Because whilst this query does access checks, block navigation always only display published content (never unpublished). Whether or not the users can view unpublished nodes is irrelevant. The advantage of doing the fix this way is that when this occurs we'll do way less because we wouldn't ever call the book tree building code.

The fix in #22 will work and maybe the sub-system maintainer will feel it is a better approach but I think it is worth considering the change outlined above.

In reviewing the patch I ran the test without the fix and it fails as expected - nice work on the test.

szato’s picture

FileSize
2.25 KB

Hi @alexpott, thank you for your review.
I guess you didn't notice @nielsvandermolen's solution: navigation_block_8.1.x-2743183-20.patch. He did what you suggested (+ he used: ->condition('status', NODE_PUBLISHED)).

I agree, filtering published books is a better solution, so I merged his patch and my testBookNavigationBlockOnUnpublishedBook().

I hope we have the final patch for this issue :)

nielsvandermolen’s picture

Version: 8.3.x-dev » 8.2.x-dev
Status: Needs review » Reviewed & tested by the community

Works well and I think we all can agree on this solution. It seems the patch can still go in the 8.2.x branch because it is not a new feature.

gnuget’s picture

Version: 8.2.x-dev » 8.3.x-dev

All the fixes land first on 8.3.x and then we can backported them to 8.2.

But Yes I agree this should be on 8.2 as well.

Thanks!

alexpott’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs subsystem maintainer review

Committed and pushed bcee34d to 8.3.x and 63b661d to 8.2.x. Thanks!

Eligible for 8.2.x because this is a straight up bug-fix with no new methods or possibly breaking changes. I spoke to @pwolanin about this change - he want to rewrite book module :) - he seemed okay with the change.

  • alexpott committed bcee34d on 8.3.x
    Issue #2743183 by szato, nielsvandermolen: Fatal error in Book...

  • alexpott committed 63b661d on 8.2.x
    Issue #2743183 by szato, nielsvandermolen: Fatal error in Book...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.