Problem/Motivation
After updating drupal/book to 3.0.3, a block using the Book visibility condition can trigger a fatal error when it is evaluated on a route with a normal node that is not a Book-enabled bundle.
The condition plugin calls getBook() unconditionally:
web/modules/contrib/book/src/Plugin/Condition/Book.php
$node = $this->getContextValue('node');
$book = $node->getBook();
But getBook() only exists on nodes using the Book bundle class (Drupal\book\Entity\Node\Book), not on a normal core Drupal\node\Entity\Node.
That means a block with Book visibility configured can WSOD on unrelated node routes.
Error
Error: Call to undefined method Drupal\node\Entity\Node::getBook() in Drupal\book\Plugin\Condition\Book->evaluate()
Steps to reproduce
- Enable book.
- Configure Book so only one content type is Book-enabled.
- Place a block with the Book visibility condition enabled.
- Visit a route with a node from a non-Book content type, for example /node/123.
- The block visibility condition is evaluated and the page fatals.
Expected result
The Book visibility condition should return FALSE for nodes that are not Book-enabled.
Actual result
The condition fatals because it assumes all routed node entities implement getBook().
Why this is a bug
The Book module already distinguishes between Book-enabled node bundles and normal node bundles using BookInterface / the Book bundle class. The visibility condition should do the same. A block visibility condition should fail closed, not take down the page.
Proposed fix
Guard evaluate() with an interface check before calling getBook():
if (!$node instanceof BookInterface) {
return FALSE;
}
Issue fork book-3586802
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
aaronpinero commentedI used the plain diff of the merge request to patch the module and this fixed the error for me.
Comment #5
smustgrave commentedFine with this change, thanks!