Skip to content
Snippets Groups Projects
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
Branches
Tags
18 merge requests!8506Draft: Issue #3456536 by ibrahim tameme,!5646Issue #3350972 by nod_: [random test failure]...,!5600Issue #3350972 by nod_: [random test failure]...,!5343Issue #3305066 by quietone, Rename RedirectLeadingSlashesSubscriber,!3603#ISSUE 3346218 Add a different message on edit comment,!3555Issue #2473873: Views entity operations lack cacheability support, resulting in incorrect dropbuttons,!3494Issue #3327018 by Spokje, longwave, xjm, mondrake: Update PHPStan to 1.9.3 and...,!3410Issue #3340128: UserLoginForm::submitForm has some dead code,!3389Issue #3325184 by Spokje, andypost, xjm, smustgrave: $this->configFactory is...,!3381Issue #3332363: Refactor Claro's menus-and-lists stylesheet,!3307Issue #3326193: CKEditor 5 can grow past the viewport when there is a lot of content,!3236Issue #3332419: Refactor Claro's messages stylesheet,!3231Draft: Issue #3049525 by longwave, fougere, larowlan, kim.pepper, AaronBauman, Wim...,!3212Issue #3294003: Refactor Claro's entity-meta stylesheet,!3194Issue #3330981: Fix PHPStan L1 error "Relying on entity queries to check access by default is deprecated...",!3143Issue #3313342: [PHP 8.1] Deprecated function: strpos(): Passing null to parameter #1 LayoutBuilderUiCacheContext.php on line 28,!2972Issue #1845004: Replace custom password hashing library with PHP 5.5 password_hash(),!2296Issue #3100732: Allow specifying `meta` data on JSON:API objects
<?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();
}
}
......@@ -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());
......
......@@ -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().
......
......@@ -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]];
}
}
......@@ -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().
......
<?php
namespace Drupal\Tests\Core\Field;
use Drupal\Core\Field\InternalViolation;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\Validator\ConstraintViolationInterface;
/**
* @coversDefaultClass \Drupal\Core\Field\InternalViolation
* @group legacy
*/
class InternalViolationTest extends UnitTestCase {
/**
* @covers ::__get
* @covers ::__set
*/
public function testSetGetDynamicProperties() {
$violation = new InternalViolation($this->prophesize(ConstraintViolationInterface::class)->reveal());
$this->expectDeprecation('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');
$this->expectDeprecation('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');
$violation->foo = 'bar';
$this->assertSame('bar', $violation->foo);
}
/**
* @covers ::__get
* @covers ::__set
*/
public function testSetGetArrayPropertyPath() {
$violation = new InternalViolation($this->prophesize(ConstraintViolationInterface::class)->reveal());
$this->expectDeprecation('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');
$violation->arrayPropertyPath = ['bar'];
$this->assertSame(['bar'], $violation->arrayPropertyPath);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment