Commit 31cc3a60 authored by catch's avatar catch
Browse files

Issue #3298731 by alexpott, andypost, catch, longwave, Berdir, bbrala, Wim...

Issue #3298731 by alexpott, andypost, catch, longwave, Berdir, bbrala, Wim Leers: Using ConstraintViolation::$arrayPropertyPath bugs on PHP 8.2

(cherry picked from commit a8f48db6)
parent ee6aacd2
Loading
Loading
Loading
Loading
+133 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Core\Field;

use Symfony\Component\Validator\ConstraintViolationInterface;

/**
 * Wraps a violation to allow arrayPropertyPath to be deprecated.
 *
 * @internal
 *   A BC shim for PHP 8.2.
 */
final class InternalViolation implements ConstraintViolationInterface {

  /**
   * The array property path.
   *
   * @var array
   */
  private $arrayPropertyPath;

  /**
   * The violation being wrapped.
   *
   * @var \Symfony\Component\Validator\ConstraintViolationInterface
   */
  private $violation;

  /**
   * An array of dynamic properties.
   *
   * @var array
   */
  private $properties = [];

  /**
   * Constructs a InternalViolation object.
   *
   * @param \Symfony\Component\Validator\ConstraintViolationInterface $violation
   *   The violation to wrap.
   */
  public function __construct(ConstraintViolationInterface $violation) {
    $this->violation = $violation;
  }

  /**
   * {@inheritdoc}
   */
  public function __get(string $name) {
    if ($name === 'arrayPropertyPath') {
      @trigger_error('Accessing the arrayPropertyPath property is deprecated in drupal:9.5.0 and is removed from drupal:11.0.0. Use \Symfony\Component\Validator\ConstraintViolationInterface::getPropertyPath() instead. See https://www.drupal.org/node/3307919', E_USER_DEPRECATED);
      return $this->arrayPropertyPath;
    }
    @trigger_error('Accessing dynamic properties on violations is deprecated in drupal:9.5.0 and is removed from drupal:11.0.0. See https://www.drupal.org/node/3307919', E_USER_DEPRECATED);
    return $this->properties[$name] ?? NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function __set(string $name, $value): void {
    if ($name === 'arrayPropertyPath') {
      $this->arrayPropertyPath = $value;
      return;
    }
    @trigger_error('Setting dynamic properties on violations is deprecated in drupal:9.5.0 and is removed from drupal:11.0.0. See https://www.drupal.org/node/3307919', E_USER_DEPRECATED);
    $this->properties[$name] = $value;
  }

  /**
   * {@inheritdoc}
   */
  public function __toString(): string {
    return (string) $this->violation;
  }

  /**
   * {@inheritdoc}
   */
  public function getMessage(): string|\Stringable {
    return $this->violation->getMessage();
  }

  /**
   * {@inheritdoc}
   */
  public function getMessageTemplate(): string {
    return $this->violation->getMessageTemplate();
  }

  /**
   * {@inheritdoc}
   */
  public function getParameters(): array {
    return $this->violation->getParameters();
  }

  /**
   * {@inheritdoc}
   */
  public function getPlural(): ?int {
    return $this->violation->getPlural();
  }

  /**
   * {@inheritdoc}
   */
  public function getRoot(): mixed {
    return $this->violation->getRoot();
  }

  /**
   * {@inheritdoc}
   */
  public function getPropertyPath(): string {
    return $this->violation->getPropertyPath();
  }

  /**
   * {@inheritdoc}
   */
  public function getInvalidValue(): mixed {
    return $this->violation->getInvalidValue();
  }

  /**
   * {@inheritdoc}
   */
  public function getCode(): ?string {
    return $this->violation->getCode();
  }

}
+2 −1
Original line number Diff line number Diff line
@@ -439,6 +439,7 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis

        $violations_by_delta = $item_list_violations = [];
        foreach ($violations as $violation) {
          $violation = new InternalViolation($violation);
          // Separate violations by delta.
          $property_path = explode('.', $violation->getPropertyPath());
          $delta = array_shift($property_path);
@@ -449,6 +450,7 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis
          else {
            $item_list_violations[] = $violation;
          }
          // @todo Remove BC layer https://www.drupal.org/i/3307859 on PHP 8.2.
          $violation->arrayPropertyPath = $property_path;
        }

@@ -465,7 +467,6 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis
            $delta_element = $element[$original_delta];
          }
          foreach ($delta_violations as $violation) {
            // @todo: Pass $violation->arrayPropertyPath as property path.
            $error_element = $this->errorElement($delta_element, $violation, $form, $form_state);
            if ($error_element !== FALSE) {
              $form_state->setError($error_element, $violation->getMessage());
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
   * {@inheritdoc}
   */
  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
    if ($violation->arrayPropertyPath == ['format'] && isset($element['format']['#access']) && !$element['format']['#access']) {
    if (isset($element['format']['#access']) && !$element['format']['#access'] && preg_match('/^[0-9]*\.format$/', $violation->getPropertyPath())) {
      // Ignore validation errors for formats if formats may not be changed,
      // such as when existing formats become invalid.
      // See \Drupal\filter\Element\TextFormat::processFormat().
+2 −1
Original line number Diff line number Diff line
@@ -100,7 +100,8 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
   */
  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
    $element = parent::errorElement($element, $violation, $form, $form_state);
    return ($element === FALSE) ? FALSE : $element[$violation->arrayPropertyPath[0]];
    $property_path_array = explode('.', $violation->getPropertyPath());
    return ($element === FALSE) ? FALSE : $element[$property_path_array[1]];
  }

}
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
   * {@inheritdoc}
   */
  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
    if ($violation->arrayPropertyPath == ['format'] && isset($element['format']['#access']) && !$element['format']['#access']) {
    if (isset($element['format']['#access']) && !$element['format']['#access'] && preg_match('/^[0-9]*\.format$/', $violation->getPropertyPath())) {
      // Ignore validation errors for formats that may not be changed,
      // such as when existing formats become invalid.
      // See \Drupal\filter\Element\TextFormat::processFormat().
Loading