use Drupal\Component\Plugin\DependentPluginInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
+use Drupal\Core\Access\AccessResultReasonInterface;
use Drupal\Core\Cache\CacheableResponseInterface;
use Drupal\Core\Config\Entity\ConfigEntityType;
use Drupal\Core\Entity\EntityTypeManagerInterface;
}
// Overwrite the received fields.
+ // @todo Remove $changed_fields in https://www.drupal.org/project/drupal/issues/2862574.
+ $changed_fields = [];
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
continue;
}
if ($this->checkPatchFieldAccess($original_entity->get($field_name), $field)) {
+ $changed_fields[] = $field_name;
$original_entity->set($field_name, $field->getValue());
}
}
+ // If no fields are changed, we can send a response immediately!
+ if (empty($changed_fields)) {
+ return new ModifiedResourceResponse($original_entity, 200);
+ }
+
// Validate the received data before saving.
- $this->validate($original_entity);
+ $this->validate($original_entity, $changed_fields);
try {
$original_entity->save();
$this->logger->notice('Updated entity %type with ID %id.', ['%type' => $original_entity->getEntityTypeId(), '%id' => $original_entity->id()]);
* @internal
*/
protected function checkPatchFieldAccess(FieldItemListInterface $original_field, FieldItemListInterface $received_field) {
- // If the user is allowed to edit the field, it is always safe to set the
- // received value. We may be setting an unchanged value, but that is ok.
- if ($original_field->access('edit')) {
- return TRUE;
- }
-
// The user might not have access to edit the field, but still needs to
// submit the current field value as part of the PATCH request. For
// example, the entity keys required by denormalizers. Therefore, if the
return FALSE;
}
+ // If the user is allowed to edit the field, it is always safe to set the
+ // received value. We may be setting an unchanged value, but that is ok.
+ $field_edit_access = $original_field->access('edit', NULL, TRUE);
+ if ($field_edit_access->isAllowed()) {
+ return TRUE;
+ }
+
// It's helpful and safe to let the user know when they are not allowed to
// update a field.
$field_name = $received_field->getName();
- throw new AccessDeniedHttpException("Access denied on updating field '$field_name'.");
+ $error_message = "Access denied on updating field '$field_name'.";
+ if ($field_edit_access instanceof AccessResultReasonInterface) {
+ $reason = $field_edit_access->getReason();
+ if ($reason) {
+ $error_message .= ' ' . $reason;
+ }
+ }
+ throw new AccessDeniedHttpException($error_message);
}
/**