Loading core/modules/node/src/NodeAccessControlHandler.php +11 −1 Changes for core/modules/node/src/NodeAccessControlHandler.php: 11 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ namespace Drupal\node; use Drupal\Core\Access\AccessResult; use Drupal\Core\Cache\RefinableCacheableDependencyInterface; use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\FieldDefinitionInterface; Loading Loading @@ -104,7 +105,16 @@ protected function checkAccess(EntityInterface $node, $operation, AccountInterfa } // Evaluate node grants. return $this->grantStorage->access($node, $operation, $account); $access_result = $this->grantStorage->access($node, $operation, $account); if ($operation === 'view' && $access_result instanceof RefinableCacheableDependencyInterface) { // Node variations can affect the access to the node. For instance, the // access result cache varies on the node's published status. Only the // 'view' node grant can currently be cached. The 'update' and 'delete' // grants are already marked as uncacheable in the node grant storage. // @see \Drupal\node\NodeGrantDatabaseStorage::access() $access_result->addCacheableDependency($node); } return $access_result; } /** Loading core/modules/node/src/NodeGrantDatabaseStorage.php +1 −1 Changes for core/modules/node/src/NodeGrantDatabaseStorage.php: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public function access(NodeInterface $node, $operation, AccountInterface $accoun // Return the equivalent of the default grant, defined by // self::writeDefault(). if ($operation === 'view') { return AccessResult::allowedIf($node->isPublished())->addCacheableDependency($node); return AccessResult::allowedIf($node->isPublished()); } else { return AccessResult::neutral(); Loading core/modules/node/tests/src/Functional/NodeAccessCacheabilityWithNodeGrants.php 0 → 100644 +66 −0 Changes for core/modules/node/tests/src/Functional/NodeAccessCacheabilityWithNodeGrants.php: 66 added lines, 0 removed lines. Original line number Diff line number Diff line <?php namespace Drupal\Tests\node\Functional; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\node\Entity\NodeType; use Drupal\Tests\BrowserTestBase; use Drupal\Tests\field\Traits\EntityReferenceTestTrait; /** * Tests node view access cacheability with node grants. * * @group node */ class NodeAccessCacheabilityWithNodeGrants extends BrowserTestBase { use EntityReferenceTestTrait; /** * {@inheritdoc} */ protected static $modules = ['node', 'node_test']; /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * Tests node view access cacheability with node grants. */ public function testAccessCacheabilityWithNodeGrants() { NodeType::create(['type' => 'page'])->save(); $this->createEntityReferenceField('node', 'page', 'ref', 'Ref', 'node'); EntityViewDisplay::create([ 'targetEntityType' => 'node', 'bundle' => 'page', 'mode' => 'default', 'status' => TRUE, ])->setComponent('ref', ['type' => 'entity_reference_label']) ->save(); // Check that at least one module implements hook_node_grants() as this test // only tests this case. // @see \node_test_node_grants() $node_grants_implementations = \Drupal::moduleHandler()->getImplementations('node_grants'); $this->assertNotEmpty($node_grants_implementations); // Create an unpublished node. $referenced = $this->createNode(['status' => FALSE]); // Create a node referencing $referenced. $node = $this->createNode(['ref' => $referenced]); // Check that the referenced entity link doesn't show on the host entity. $this->drupalGet($node->toUrl()); $this->assertSession()->linkNotExists($referenced->label()); // Publish the referenced node. $referenced->setPublished()->save(); // Check that the referenced entity link shows on the host entity. $this->getSession()->reload(); $this->assertSession()->linkExists($referenced->label()); } } Loading
core/modules/node/src/NodeAccessControlHandler.php +11 −1 Changes for core/modules/node/src/NodeAccessControlHandler.php: 11 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ namespace Drupal\node; use Drupal\Core\Access\AccessResult; use Drupal\Core\Cache\RefinableCacheableDependencyInterface; use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\FieldDefinitionInterface; Loading Loading @@ -104,7 +105,16 @@ protected function checkAccess(EntityInterface $node, $operation, AccountInterfa } // Evaluate node grants. return $this->grantStorage->access($node, $operation, $account); $access_result = $this->grantStorage->access($node, $operation, $account); if ($operation === 'view' && $access_result instanceof RefinableCacheableDependencyInterface) { // Node variations can affect the access to the node. For instance, the // access result cache varies on the node's published status. Only the // 'view' node grant can currently be cached. The 'update' and 'delete' // grants are already marked as uncacheable in the node grant storage. // @see \Drupal\node\NodeGrantDatabaseStorage::access() $access_result->addCacheableDependency($node); } return $access_result; } /** Loading
core/modules/node/src/NodeGrantDatabaseStorage.php +1 −1 Changes for core/modules/node/src/NodeGrantDatabaseStorage.php: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public function access(NodeInterface $node, $operation, AccountInterface $accoun // Return the equivalent of the default grant, defined by // self::writeDefault(). if ($operation === 'view') { return AccessResult::allowedIf($node->isPublished())->addCacheableDependency($node); return AccessResult::allowedIf($node->isPublished()); } else { return AccessResult::neutral(); Loading
core/modules/node/tests/src/Functional/NodeAccessCacheabilityWithNodeGrants.php 0 → 100644 +66 −0 Changes for core/modules/node/tests/src/Functional/NodeAccessCacheabilityWithNodeGrants.php: 66 added lines, 0 removed lines. Original line number Diff line number Diff line <?php namespace Drupal\Tests\node\Functional; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\node\Entity\NodeType; use Drupal\Tests\BrowserTestBase; use Drupal\Tests\field\Traits\EntityReferenceTestTrait; /** * Tests node view access cacheability with node grants. * * @group node */ class NodeAccessCacheabilityWithNodeGrants extends BrowserTestBase { use EntityReferenceTestTrait; /** * {@inheritdoc} */ protected static $modules = ['node', 'node_test']; /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * Tests node view access cacheability with node grants. */ public function testAccessCacheabilityWithNodeGrants() { NodeType::create(['type' => 'page'])->save(); $this->createEntityReferenceField('node', 'page', 'ref', 'Ref', 'node'); EntityViewDisplay::create([ 'targetEntityType' => 'node', 'bundle' => 'page', 'mode' => 'default', 'status' => TRUE, ])->setComponent('ref', ['type' => 'entity_reference_label']) ->save(); // Check that at least one module implements hook_node_grants() as this test // only tests this case. // @see \node_test_node_grants() $node_grants_implementations = \Drupal::moduleHandler()->getImplementations('node_grants'); $this->assertNotEmpty($node_grants_implementations); // Create an unpublished node. $referenced = $this->createNode(['status' => FALSE]); // Create a node referencing $referenced. $node = $this->createNode(['ref' => $referenced]); // Check that the referenced entity link doesn't show on the host entity. $this->drupalGet($node->toUrl()); $this->assertSession()->linkNotExists($referenced->label()); // Publish the referenced node. $referenced->setPublished()->save(); // Check that the referenced entity link shows on the host entity. $this->getSession()->reload(); $this->assertSession()->linkExists($referenced->label()); } }