X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=web%2Fcore%2Flib%2FDrupal%2FCore%2FEntity%2FPlugin%2FValidation%2FConstraint%2FValidReferenceConstraintValidator.php;fp=web%2Fcore%2Flib%2FDrupal%2FCore%2FEntity%2FPlugin%2FValidation%2FConstraint%2FValidReferenceConstraintValidator.php;h=aef9fb0018dd0fb8fae6bee66376a76d5e3f4e11;hp=40c73700195ce3533b0ee7c5054c5905c5986965;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hpb=aea91e65e895364e460983b890e295aa5d5540a5 diff --git a/web/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php b/web/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php index 40c737001..aef9fb001 100644 --- a/web/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php +++ b/web/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/ValidReferenceConstraintValidator.php @@ -91,8 +91,10 @@ class ValidReferenceConstraintValidator extends ConstraintValidator implements C return; } + $entity = !empty($value->getParent()) ? $value->getEntity() : NULL; + /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler * */ - $handler = $this->selectionManager->getSelectionHandler($value->getFieldDefinition()); + $handler = $this->selectionManager->getSelectionHandler($value->getFieldDefinition(), $entity); $target_type_id = $value->getFieldDefinition()->getSetting('target_type'); // Add violations on deltas with a new entity that is not valid. @@ -119,16 +121,29 @@ class ValidReferenceConstraintValidator extends ConstraintValidator implements C // Add violations on deltas with a target_id that is not valid. if ($target_ids) { + // Get a list of pre-existing references. + $previously_referenced_ids = []; + if ($value->getParent() && ($entity = $value->getEntity()) && !$entity->isNew()) { + $existing_entity = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id()); + foreach ($existing_entity->{$value->getFieldDefinition()->getName()}->getValue() as $item) { + $previously_referenced_ids[$item['target_id']] = $item['target_id']; + } + } + $valid_target_ids = $handler->validateReferenceableEntities($target_ids); if ($invalid_target_ids = array_diff($target_ids, $valid_target_ids)) { // For accuracy of the error message, differentiate non-referenceable // and non-existent entities. - $target_type = $this->entityTypeManager->getDefinition($target_type_id); - $existing_ids = $this->entityTypeManager->getStorage($target_type_id)->getQuery() - ->condition($target_type->getKey('id'), $invalid_target_ids, 'IN') - ->execute(); + $existing_entities = $this->entityTypeManager->getStorage($target_type_id)->loadMultiple($invalid_target_ids); foreach ($invalid_target_ids as $delta => $target_id) { - $message = in_array($target_id, $existing_ids) ? $constraint->message : $constraint->nonExistingMessage; + // Check if any of the invalid existing references are simply not + // accessible by the user, in which case they need to be excluded from + // validation + if (isset($previously_referenced_ids[$target_id]) && isset($existing_entities[$target_id]) && !$existing_entities[$target_id]->access('view')) { + continue; + } + + $message = isset($existing_entities[$target_id]) ? $constraint->message : $constraint->nonExistingMessage; $this->context->buildViolation($message) ->setParameter('%type', $target_type_id) ->setParameter('%id', $target_id)