ReferenceAccessConstraintValidator.php 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. <?php
  2. namespace Drupal\Core\Entity\Plugin\Validation\Constraint;
  3. use Symfony\Component\Validator\Constraint;
  4. use Symfony\Component\Validator\ConstraintValidator;
  5. /**
  6. * Checks if the current user has access to newly referenced entities.
  7. */
  8. class ReferenceAccessConstraintValidator extends ConstraintValidator {
  9. /**
  10. * {@inheritdoc}
  11. */
  12. public function validate($value, Constraint $constraint) {
  13. /* @var \Drupal\Core\Field\FieldItemInterface $value */
  14. if (!isset($value)) {
  15. return;
  16. }
  17. $id = $value->target_id;
  18. // '0' or NULL are considered valid empty references.
  19. if (empty($id)) {
  20. return;
  21. }
  22. /* @var \Drupal\Core\Entity\FieldableEntityInterface $referenced_entity */
  23. $referenced_entity = $value->entity;
  24. if ($referenced_entity) {
  25. $entity = $value->getEntity();
  26. $check_permission = TRUE;
  27. if (!$entity->isNew()) {
  28. $existing_entity = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
  29. $referenced_entities = $existing_entity->{$value->getFieldDefinition()->getName()}->referencedEntities();
  30. // Check permission if we are not already referencing the entity.
  31. foreach ($referenced_entities as $ref) {
  32. if (isset($referenced_entities[$ref->id()])) {
  33. $check_permission = FALSE;
  34. break;
  35. }
  36. }
  37. }
  38. // We check that the current user had access to view any newly added
  39. // referenced entity.
  40. if ($check_permission && !$referenced_entity->access('view')) {
  41. $type = $value->getFieldDefinition()->getSetting('target_type');
  42. $this->context->addViolation($constraint->message, ['%type' => $type, '%id' => $id]);
  43. }
  44. }
  45. }
  46. }