Pull merge.
[yaffs-website] / web / core / lib / Drupal / Core / Entity / EntityAccessControlHandler.php
index 3b16d1cddbc30021f65a7e433f4132a13bfe899b..0a2bb193be8d8f49ee59971ca197da34698faa72 100644 (file)
@@ -66,7 +66,19 @@ class EntityAccessControlHandler extends EntityHandlerBase implements EntityAcce
       $operation = 'view';
     }
 
-    if (($return = $this->getCache($entity->uuid(), $operation, $langcode, $account)) !== NULL) {
+    // If an entity does not have a UUID, either from not being set or from not
+    // having them, use the 'entity type:ID' pattern as the cache $cid.
+    $cid = $entity->uuid() ?: $entity->getEntityTypeId() . ':' . $entity->id();
+
+    // If the entity is revisionable, then append the revision ID to allow
+    // individual revisions to have specific access control and be cached
+    // separately.
+    if ($entity instanceof RevisionableInterface) {
+      /** @var $entity \Drupal\Core\Entity\RevisionableInterface */
+      $cid .= ':' . $entity->getRevisionId();
+    }
+
+    if (($return = $this->getCache($cid, $operation, $langcode, $account)) !== NULL) {
       // Cache hit, no work necessary.
       return $return_as_object ? $return : $return->isAllowed();
     }
@@ -92,7 +104,7 @@ class EntityAccessControlHandler extends EntityHandlerBase implements EntityAcce
     if (!$return->isForbidden()) {
       $return = $return->orIf($this->checkAccess($entity, $operation, $account));
     }
-    $result = $this->setCache($return, $entity->uuid(), $operation, $langcode, $account);
+    $result = $this->setCache($return, $cid, $operation, $langcode, $account);
     return $return_as_object ? $result : $result->isAllowed();
   }
 
@@ -146,7 +158,7 @@ class EntityAccessControlHandler extends EntityHandlerBase implements EntityAcce
       return AccessResult::forbidden()->addCacheableDependency($entity);
     }
     if ($admin_permission = $this->entityType->getAdminPermission()) {
-      return AccessResult::allowedIfHasPermission($account, $this->entityType->getAdminPermission());
+      return AccessResult::allowedIfHasPermission($account, $admin_permission);
     }
     else {
       // No opinion.
@@ -304,14 +316,18 @@ class EntityAccessControlHandler extends EntityHandlerBase implements EntityAcce
     $default = $items ? $items->defaultAccess($operation, $account) : AccessResult::allowed();
 
     // Explicitly disallow changing the entity ID and entity UUID.
-    if ($operation === 'edit') {
+    $entity = $items ? $items->getEntity() : NULL;
+    if ($operation === 'edit' && $entity) {
       if ($field_definition->getName() === $this->entityType->getKey('id')) {
-        return $return_as_object ? AccessResult::forbidden('The entity ID cannot be changed') : FALSE;
+        // String IDs can be set when creating the entity.
+        if (!($entity->isNew() && $field_definition->getType() === 'string')) {
+          return $return_as_object ? AccessResult::forbidden('The entity ID cannot be changed.')->addCacheableDependency($entity) : FALSE;
+        }
       }
       elseif ($field_definition->getName() === $this->entityType->getKey('uuid')) {
         // UUIDs can be set when creating an entity.
-        if ($items && ($entity = $items->getEntity()) && !$entity->isNew()) {
-          return $return_as_object ? AccessResult::forbidden('The entity UUID cannot be changed')->addCacheableDependency($entity) : FALSE;
+        if (!$entity->isNew()) {
+          return $return_as_object ? AccessResult::forbidden('The entity UUID cannot be changed.')->addCacheableDependency($entity) : FALSE;
         }
       }
     }