.../Drupal/Core/Entity/EntityAccessControlHandler.php | 6 ++++++ .../rest/src/Plugin/rest/resource/EntityResource.php | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php b/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php index 1530693..805c0f2 100644 --- a/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php +++ b/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php @@ -350,6 +350,12 @@ public function fieldAccess($operation, FieldDefinitionInterface $field_definiti * The access result. */ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) { + if ($operation === 'edit') { + $access = $field_definition->isReadOnly() ? AccessResult::forbidden() : AccessResult::allowed(); + $access->addCacheableDependency($field_definition); + return $access; + } + return AccessResult::allowed(); } diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php index 4a15079..72f49fa 100644 --- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php +++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php @@ -213,16 +213,19 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity foreach ($entity->_restSubmittedFields as $field_name) { $field = $entity->get($field_name); - // It is not possible to set the language to NULL as it is automatically - // re-initialized. As it must not be empty, skip it if it is. - if (isset($entity_keys['langcode']) && $field_name === $entity_keys['langcode'] && $field->isEmpty()) { + // Allow sending read-only fields, as long as their value is unchanged. In + // other words: discard this value, don't set it on the entity. Since no + // validation error is thrown, that's equivalent to allowing this value to + // be sent. + // This should not be necessary, but due to a design flaw in the Entity + // Field API: the validation logic can only use the pre-update values, not + // the post-update values. + // @see \Drupal\Core\Entity\EntityAccessControlHandlerInterface::fieldAccess() + if ($field->getFieldDefinition()->isReadOnly() && $original_entity->get($field_name)->getValue() === $entity->get($field_name)->getValue()) { continue; } - // Allow sending read-only fields, as long as their value is unchanged. - elseif ($field->getFieldDefinition()->isReadOnly() && $original_entity->get($field_name)->getValue() === $entity->get($field_name)->getValue()) { - continue; - } - elseif (!$original_entity->get($field_name)->access('edit')) { + + if (!$original_entity->get($field_name)->access('edit')) { throw new AccessDeniedHttpException("Access denied on updating field '$field_name'."); } $original_entity->set($field_name, $field->getValue());