Commit 190032b7 authored by effulgentsia's avatar effulgentsia

Issue #2072945 by Berdir, plach, effulgentsia, Schnitzel, andypost, Wim Leers:...

Issue #2072945 by Berdir, plach, effulgentsia, Schnitzel, andypost, Wim Leers: Remove the $langcode parameter in EntityAccessControllerInterface::access() and friends
parent 1672445a
......@@ -593,7 +593,7 @@ public function access($operation, AccountInterface $account = NULL, $return_as_
}
return $this->entityManager()
->getAccessControlHandler($this->entityTypeId)
->access($this, $operation, $this->activeLangcode, $account, $return_as_object);
->access($this, $operation, $account, $return_as_object);
}
/**
......
......@@ -313,7 +313,7 @@ public function access($operation, AccountInterface $account = NULL, $return_as_
}
return $this->entityManager()
->getAccessControlHandler($this->entityTypeId)
->access($this, $operation, LanguageInterface::LANGCODE_DEFAULT, $account, $return_as_object);
->access($this, $operation, $account, $return_as_object);
}
/**
......
......@@ -53,8 +53,9 @@ public function __construct(EntityTypeInterface $entity_type) {
/**
* {@inheritdoc}
*/
public function access(EntityInterface $entity, $operation, $langcode = LanguageInterface::LANGCODE_DEFAULT, AccountInterface $account = NULL, $return_as_object = FALSE) {
public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
$account = $this->prepareUser($account);
$langcode = $entity->language()->getId();
if (($return = $this->getCache($entity->uuid(), $operation, $langcode, $account)) !== NULL) {
// Cache hit, no work necessary.
......@@ -71,8 +72,8 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
// - No modules say to deny access.
// - At least one module says to grant access.
$access = array_merge(
$this->moduleHandler()->invokeAll('entity_access', array($entity, $operation, $account, $langcode)),
$this->moduleHandler()->invokeAll($entity->getEntityTypeId() . '_access', array($entity, $operation, $account, $langcode))
$this->moduleHandler()->invokeAll('entity_access', [$entity, $operation, $account]),
$this->moduleHandler()->invokeAll($entity->getEntityTypeId() . '_access', [$entity, $operation, $account])
);
$return = $this->processAccessHookResults($access);
......@@ -80,7 +81,7 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
// Also execute the default access check except when the access result is
// already forbidden, as in that case, it can not be anything else.
if (!$return->isForbidden()) {
$return = $return->orIf($this->checkAccess($entity, $operation, $langcode, $account));
$return = $return->orIf($this->checkAccess($entity, $operation, $account));
}
$result = $this->setCache($return, $entity->uuid(), $operation, $langcode, $account);
return $return_as_object ? $result : $result->isAllowed();
......@@ -124,15 +125,13 @@ protected function processAccessHookResults(array $access) {
* The entity for which to check access.
* @param string $operation
* The entity operation. Usually one of 'view', 'update' or 'delete'.
* @param string $langcode
* The language code for which to check access.
* @param \Drupal\Core\Session\AccountInterface $account
* The user for which to check access.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation == 'delete' && $entity->isNew()) {
return AccessResult::forbidden()->cacheUntilEntityChanges($entity);
}
......
......@@ -29,9 +29,6 @@ interface EntityAccessControlHandlerInterface {
* @param string $operation
* The operation access should be checked for.
* Usually one of "view", "update" or "delete".
* @param string $langcode
* (optional) The language code for which to check access. Defaults to
* LanguageInterface::LANGCODE_DEFAULT.
* @param \Drupal\Core\Session\AccountInterface $account
* (optional) The user session for which to check access, or NULL to check
* access for the current user. Defaults to NULL.
......@@ -45,7 +42,7 @@ interface EntityAccessControlHandlerInterface {
* returned, i.e. TRUE means access is explicitly allowed, FALSE means
* access is either explicitly forbidden or "no opinion".
*/
public function access(EntityInterface $entity, $operation, $langcode = LanguageInterface::LANGCODE_DEFAULT, AccountInterface $account = NULL, $return_as_object = FALSE);
public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE);
/**
* Checks access to create an entity.
......
......@@ -522,8 +522,6 @@
* The operation that is to be performed on $entity.
* @param \Drupal\Core\Session\AccountInterface $account
* The account trying to access the entity.
* @param string $langcode
* The code of the language $entity is accessed in.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result. The final result is calculated by using
......@@ -541,7 +539,7 @@
*
* @ingroup entity_api
*/
function hook_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account, $langcode) {
function hook_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
// No opinion.
return AccessResult::neutral();
}
......@@ -555,8 +553,6 @@ function hook_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operat
* The operation that is to be performed on $entity.
* @param \Drupal\Core\Session\AccountInterface $account
* The account trying to access the entity.
* @param string $langcode
* The code of the language $entity is accessed in.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result. hook_entity_access() has detailed documentation.
......@@ -567,7 +563,7 @@ function hook_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operat
*
* @ingroup entity_api
*/
function hook_ENTITY_TYPE_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account, $langcode) {
function hook_ENTITY_TYPE_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
// No opinion.
return AccessResult::neutral();
}
......
......@@ -22,7 +22,7 @@ class FeedAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
switch ($operation) {
case 'view':
return AccessResult::allowedIfHasPermission($account, 'access news feeds');
......
......@@ -193,8 +193,6 @@ function hook_block_build_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\
* The operation to be performed, e.g., 'view', 'create', 'delete', 'update'.
* @param \Drupal\Core\Session\AccountInterface $account
* The user object to perform the access check operation on.
* @param string $langcode
* The language code to perform the access check operation on.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result. If all implementations of this hook return
......@@ -206,7 +204,7 @@ function hook_block_build_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\
* @see \Drupal\block\BlockAccessControlHandler::checkAccess()
* @ingroup block_api
*/
function hook_block_access(\Drupal\block\Entity\Block $block, $operation, \Drupal\Core\Session\AccountInterface $account, $langcode) {
function hook_block_access(\Drupal\block\Entity\Block $block, $operation, \Drupal\Core\Session\AccountInterface $account) {
// Example code that would prevent displaying the 'Powered by Drupal' block in
// a region different than the footer.
if ($operation == 'view' && $block->getPluginId() == 'system_powered_by_block') {
......
......@@ -88,10 +88,10 @@ public function __construct(EntityTypeInterface $entity_type, ExecutableManagerI
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\block\BlockInterface $entity */
if ($operation != 'view') {
return parent::checkAccess($entity, $operation, $langcode, $account);
return parent::checkAccess($entity, $operation, $account);
}
// Don't grant access to disabled blocks.
......
......@@ -22,11 +22,11 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation === 'view') {
return AccessResult::allowed();
}
return parent::checkAccess($entity, $operation, $langcode, $account);
return parent::checkAccess($entity, $operation, $account);
}
}
......@@ -24,7 +24,7 @@ class CommentAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\comment\CommentInterface|\Drupal\user\EntityOwnerInterface $entity */
$comment_admin = $account->hasPermission('administer comments');
......
......@@ -22,7 +22,7 @@ class ConfigTestAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
public function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
public function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
return AccessResult::allowed();
}
......
......@@ -22,7 +22,7 @@ class ContactFormAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation == 'view') {
// Do not allow access personal form via site-wide route.
return AccessResult::allowedIf($account->hasPermission('access site-wide contact form') && $entity->id() !== 'personal')->cachePerPermissions();
......@@ -33,7 +33,7 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
return AccessResult::allowedIf($account->hasPermission('administer contact forms') && $entity->id() !== 'personal')->cachePerPermissions();
}
return parent::checkAccess($entity, $operation, $langcode, $account);
return parent::checkAccess($entity, $operation, $account);
}
}
......@@ -22,7 +22,7 @@ class FieldConfigAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation == 'delete') {
$field_storage_entity = $entity->getFieldStorageDefinition();
if ($field_storage_entity->isLocked()) {
......
......@@ -21,7 +21,7 @@ class FileAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\file\FileInterface $entity */
if ($operation == 'download' || $operation == 'view') {
if (\Drupal::service('file_system')->uriScheme($entity->getFileUri()) === 'public') {
......
......@@ -19,9 +19,9 @@ class FileTestAccessControlHandler extends FileAccessControlHandler implements F
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
\Drupal::state()->set('file_access_formatter_check', TRUE);
return parent::checkAccess($entity, $operation, $langcode, $account);
return parent::checkAccess($entity, $operation, $account);
}
}
......@@ -22,7 +22,7 @@ class FilterFormatAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $filter_format, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $filter_format, $operation, AccountInterface $account) {
/** @var \Drupal\filter\FilterFormatInterface $filter_format */
// All users are allowed to use the fallback filter.
......@@ -47,7 +47,7 @@ protected function checkAccess(EntityInterface $filter_format, $operation, $lang
}
if (in_array($operation, array('disable', 'update'))) {
return parent::checkAccess($filter_format, $operation, $langcode, $account);
return parent::checkAccess($filter_format, $operation, $account);
}
// No opinion.
......
......@@ -22,18 +22,18 @@ class LanguageAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
public function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
switch ($operation) {
case 'update':
/* @var \Drupal\Core\Language\LanguageInterface $entity */
return AccessResult::allowedIf(!$entity->isLocked())->cacheUntilEntityChanges($entity)
->andIf(parent::checkAccess($entity, $operation, $langcode, $account));
->andIf(parent::checkAccess($entity, $operation, $account));
case 'delete':
/* @var \Drupal\Core\Language\LanguageInterface $entity */
return AccessResult::allowedIf(!$entity->isLocked())->cacheUntilEntityChanges($entity)
->andIf(AccessResult::allowedIf(!$entity->isDefault())->cacheUntilEntityChanges($entity))
->andIf(parent::checkAccess($entity, $operation, $langcode, $account));
->andIf(parent::checkAccess($entity, $operation, $account));
default:
// No opinion.
......
......@@ -51,7 +51,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
switch ($operation) {
case 'view':
// There is no direct viewing of a menu link, but still for purposes of
......
......@@ -319,15 +319,13 @@ function hook_node_grants_alter(&$grants, \Drupal\Core\Session\AccountInterface
* - "view"
* @param \Drupal\Core\Session\AccountInterface $account
* The user object to perform the access check operation on.
* @param string $langcode
* The language code to perform the access check operation on.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*
* @ingroup node_access
*/
function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account, $langcode) {
function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
$type = $node->bundle();
switch ($op) {
......
......@@ -92,15 +92,11 @@ public function access(Route $route, AccountInterface $account, $node_revision =
* performed.
* @param string $op
* (optional) The specific operation being checked. Defaults to 'view.'
* @param string|null $langcode
* (optional) Language code for the variant of the node. Different language
* variants might have different permissions associated. If NULL, the
* original langcode of the node is used. Defaults to NULL.
*
* @return bool
* TRUE if the operation may be performed, FALSE otherwise.
*/
public function checkAccess(NodeInterface $node, AccountInterface $account, $op = 'view', $langcode = NULL) {
public function checkAccess(NodeInterface $node, AccountInterface $account, $op = 'view') {
$map = array(
'view' => 'view all revisions',
'update' => 'revert all revisions',
......@@ -119,13 +115,9 @@ public function checkAccess(NodeInterface $node, AccountInterface $account, $op
return FALSE;
}
// If no language code was provided, default to the node revision's langcode.
if (empty($langcode)) {
$langcode = $node->language()->getId();
}
// Statically cache access by revision ID, language code, user account ID,
// and operation.
$langcode = $node->language()->getId();
$cid = $node->getRevisionId() . ':' . $langcode . ':' . $account->id() . ':' . $op;
if (!isset($this->access[$cid])) {
......@@ -149,7 +141,7 @@ public function checkAccess(NodeInterface $node, AccountInterface $account, $op
else {
// First check the access to the default revision and finally, if the
// node passed in is not the default revision then access to that, too.
$this->access[$cid] = $this->nodeAccess->access($this->nodeStorage->load($node->id()), $op, $langcode, $account) && ($node->isDefaultRevision() || $this->nodeAccess->access($node, $op, $langcode, $account));
$this->access[$cid] = $this->nodeAccess->access($this->nodeStorage->load($node->id()), $op, $account) && ($node->isDefaultRevision() || $this->nodeAccess->access($node, $op, $account));
}
}
......
......@@ -181,30 +181,9 @@ public function access($operation = 'view', AccountInterface $account = NULL, $r
return \Drupal::entityManager()
->getAccessControlHandler($this->entityTypeId)
->access($this, $operation, $this->prepareLangcode(), $account, $return_as_object);
->access($this, $operation, $account, $return_as_object);
}
/**
* {@inheritdoc}
*/
public function prepareLangcode() {
$langcode = $this->language()->getId();
// If the Language module is enabled, try to use the language from content
// negotiation.
if (\Drupal::moduleHandler()->moduleExists('language')) {
// Load languages the node exists in.
$node_translations = $this->getTranslationLanguages();
// Load the language from content negotiation.
$content_negotiation_langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
// If there is a translation available, use it.
if (isset($node_translations[$content_negotiation_langcode])) {
$langcode = $content_negotiation_langcode;
}
}
return $langcode;
}
/**
* {@inheritdoc}
*/
......
......@@ -60,7 +60,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
/**
* {@inheritdoc}
*/
public function access(EntityInterface $entity, $operation, $langcode = LanguageInterface::LANGCODE_DEFAULT, AccountInterface $account = NULL, $return_as_object = FALSE) {
public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
$account = $this->prepareUser($account);
if ($account->hasPermission('bypass node access')) {
......@@ -71,7 +71,7 @@ public function access(EntityInterface $entity, $operation, $langcode = Language
$result = AccessResult::forbidden()->cachePerPermissions();
return $return_as_object ? $result : $result->isAllowed();
}
$result = parent::access($entity, $operation, $langcode, $account, TRUE)->cachePerPermissions();
$result = parent::access($entity, $operation, $account, TRUE)->cachePerPermissions();
return $return_as_object ? $result : $result->isAllowed();
}
......@@ -97,14 +97,12 @@ public function createAccess($entity_bundle = NULL, AccountInterface $account =
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $node, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $node, $operation, AccountInterface $account) {
/** @var \Drupal\node\NodeInterface $node */
/** @var \Drupal\node\NodeInterface $translation */
$translation = $node->hasTranslation($langcode) ? $node->getTranslation($langcode) : $node;
// Fetch information from the node object if possible.
$status = $translation->isPublished();
$uid = $translation->getOwnerId();
$status = $node->isPublished();
$uid = $node->getOwnerId();
// Check if authors can view their own unpublished nodes.
if ($operation === 'view' && !$status && $account->hasPermission('view own unpublished content') && $account->isAuthenticated() && $account->id() == $uid) {
......@@ -112,7 +110,7 @@ protected function checkAccess(EntityInterface $node, $operation, $langcode, Acc
}
// Evaluate node grants.
return $this->grantStorage->access($node, $operation, $langcode, $account);
return $this->grantStorage->access($node, $operation, $account);
}
/**
......
......@@ -67,14 +67,14 @@ public function __construct(Connection $database, ModuleHandlerInterface $module
/**
* {@inheritdoc}
*/
public function access(NodeInterface $node, $operation, $langcode, AccountInterface $account) {
public function access(NodeInterface $node, $operation, AccountInterface $account) {
// If no module implements the hook or the node does not have an id there is
// no point in querying the database for access grants.
if (!$this->moduleHandler->getImplementations('node_grants') || !$node->id()) {
// Return the equivalent of the default grant, defined by
// self::writeDefault().
if ($operation === 'view') {
return AccessResult::allowedIf($node->getTranslation($langcode)->isPublished())->cacheUntilEntityChanges($node);
return AccessResult::allowedIf($node->isPublished())->cacheUntilEntityChanges($node);
}
else {
return AccessResult::neutral();
......@@ -89,7 +89,7 @@ public function access(NodeInterface $node, $operation, $langcode, AccountInterf
// Check for grants for this node and the correct langcode.
$nids = $query->andConditionGroup()
->condition('nid', $node->id())
->condition('langcode', $langcode);
->condition('langcode', $node->language()->getId());
// If the node is published, also take the default grant into account. The
// default is saved with a node ID of 0.
$status = $node->isPublished();
......
......@@ -102,8 +102,6 @@ public function writeDefault();
* @param string $operation
* The entity operation. Usually one of 'view', 'edit', 'create' or
* 'delete'.
* @param string $langcode
* The language code for which to check access.
* @param \Drupal\Core\Session\AccountInterface $account
* The user for which to check access.
*
......@@ -115,7 +113,7 @@ public function writeDefault();
* @see hook_node_access_records()
* @see \Drupal\node\NodeGrantDatabaseStorageInterface::writeDefault()
*/
public function access(NodeInterface $node, $operation, $langcode, AccountInterface $account);
public function access(NodeInterface $node, $operation, AccountInterface $account);
/**
* Counts available node grants.
......
......@@ -160,12 +160,4 @@ public function getRevisionAuthor();
*/
public function setRevisionAuthorId($uid);
/**
* Prepares the langcode for a node.
*
* @return string
* The langcode for this node.
*/
public function prepareLangcode();
}
......@@ -22,7 +22,7 @@ class NodeTypeAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
switch ($operation) {
case 'view':
return AccessResult::allowedIfHasPermission($account, 'access content');
......@@ -33,12 +33,12 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
return AccessResult::forbidden()->cacheUntilEntityChanges($entity);
}
else {
return parent::checkAccess($entity, $operation, $langcode, $account)->cacheUntilEntityChanges($entity);
return parent::checkAccess($entity, $operation, $account)->cacheUntilEntityChanges($entity);
}
break;
default:
return parent::checkAccess($entity, $operation, $langcode, $account);
return parent::checkAccess($entity, $operation, $account);
break;
}
}
......
......@@ -30,21 +30,21 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase {
/**
* A set of nodes to use in testing.
*
* @var array
* @var \Drupal\node\NodeInterface[]
*/
protected $nodes = array();
/**
* A normal authenticated user.
*
* @var \Drupal\user\Entity\UserInterface.
* @var \Drupal\user\UserInterface.
*/
protected $webUser;
/**
* User 1.
*
* @var \Drupal\user\Entity\UserInterface.
* @var \Drupal\user\UserInterface.
*/
protected $adminUser;
......@@ -200,78 +200,58 @@ function testNodeAccessLanguageAwareCombination() {
$expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE);
$expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE);
// When the node and both translations are public, access should only be
// denied when a translation that does not exist is requested.
// When the node and both translations are public, access should always be
// granted.
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public'], $this->webUser);
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_public'], $this->webUser, 'en');
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public']->getTranslation('hu'), $this->webUser);
$this->assertNodeAccess($expected_node_access, $this->nodes['public_both_public']->getTranslation('ca'), $this->webUser);
// If the node is marked private but both existing translations are not,
// access should still be granted, because the grants are additive.
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public'], $this->webUser);
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_public'], $this->webUser, 'en');
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public']->getTranslation('hu'), $this->webUser);
$this->assertNodeAccess($expected_node_access, $this->nodes['private_both_public']->getTranslation('ca'), $this->webUser);
// If the node is marked private, but a existing translation is public,
// access should only be granted for the public translation. For a
// translation that does not exist yet (English translation), the access is
// denied. With the Hungarian translation marked as private, but the Catalan
// translation public, the access is granted.
// access should only be granted for the public translation. With the
// Hungarian translation marked as private, but the Catalan translation
// public, the access is granted.
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private'], $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access, $this->nodes['public_hu_private'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private'], $this->webUser, 'en');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_hu_private']->getTranslation('hu'), $this->webUser);
$this->assertNodeAccess($expected_node_access, $this->nodes['public_hu_private']->getTranslation('ca'), $this->webUser);
// With the Catalan translation marked as private, but the node public,
// access is granted for the existing Hungarian translation, but not for the
// Catalan nor the English ones.
// Catalan.
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private'], $this->webUser);
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_ca_private'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_ca_private'], $this->webUser, 'en');
$this->assertNodeAccess($expected_node_access, $this->nodes['public_ca_private']->getTranslation('hu'), $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_ca_private']->getTranslation('ca'), $this->webUser);
// With both translations marked as private, but the node public, access
// should be denied in all cases.
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private'], $this->webUser, 'en');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private']->getTranslation('hu'), $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_both_private']->getTranslation('ca'), $this->webUser);
// If the node and both its existing translations are private, access should
// be denied in all cases.
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private'], $this->webUser, 'en');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private']->getTranslation('hu'), $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_both_private']->getTranslation('ca'), $this->webUser);
// No access for all languages as the language aware node access module
// denies access.
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_private'], $this->webUser, 'en');
// Access only for request with no language defined.
$this->assertNodeAccess($expected_node_access, $this->nodes['public_no_language_public'], $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_public'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_public'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['public_no_language_public'], $this->webUser, 'en');
// No access for all languages as both node access modules deny access.
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_private'], $this->webUser, 'en');
// No access for all languages as the non language aware node access module
// denies access.
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser);
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser, 'ca');
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['private_no_language_public'], $this->webUser, 'en');
// Query the node table with the node access tag in several languages.
......
......@@ -29,7 +29,7 @@ class NodeAccessLanguageAwareTest extends NodeTestBase {
/**
* A set of nodes to use in testing.
*
* @var array
* @var \Drupal\node\NodeInterface[]
*/
protected $nodes = array();
......@@ -157,60 +157,42 @@ function testNodeAccessLanguageAware() {
$expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE);
// When both Hungarian and Catalan are marked as public, access to the
// Hungarian translation should be granted when no language is specified or
// Hungarian translation should be granted with the default entity object or
// when the Hungarian translation is specified explicitly.
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public'], $this->webUser);
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public'], $this->webUser, 'hu');
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public']->getTranslation('hu'), $this->webUser);
// Access to the Catalan translation should also be granted.
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public'], $this->webUser, 'ca');
// There is no English translation, so a request to access the English
// translation is denied.
$this->assertNodeAccess($expected_node_access_no_access, $this->nodes['both_public'], $this->webUser, 'en');
$this->assertNodeAccess($expected_node_access, $this->nodes['both_public']->getTranslation('ca'), $this->webUser);