Verified Commit 78133af8 authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #3415582 by nico.b, larowlan, Matt B: Unhandled exception when trying to...

Issue #3415582 by nico.b, larowlan, Matt B: Unhandled exception when trying to register a duplicate username with different case

(cherry picked from commit ce9ec037)
parent 59284ed7
Loading
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ public function validate($items, Constraint $constraint) {
      // If our entity duplicates field values in any other entity, the query
      // will return all field values that belong to those entities. Narrow
      // down to only the specific duplicate values.
      $duplicate_values = array_intersect($item_values, $other_entity_values);
      $duplicate_values = $this->caseInsensitiveArrayIntersect($item_values, $other_entity_values);

      foreach ($duplicate_values as $delta => $dupe) {
        $violation = $this->context
@@ -112,6 +112,26 @@ public function validate($items, Constraint $constraint) {
    }
  }

  /**
   * Perform a case-insensitive array intersection, but keep original capitalization.
   *
   * @param array $orig_values
   *   The original values to be returned.
   * @param array $comp_values
   *   The values to intersect $orig_values with.
   *
   * @return array
   *   Elements of $orig_values contained in $comp_values when ignoring capitalization.
   */
  private function caseInsensitiveArrayIntersect(array $orig_values, array $comp_values): array {
    $lowercase_comp_values = array_map('strtolower', $comp_values);
    $intersect_map = array_map(fn (string $x) => in_array(strtolower($x), $lowercase_comp_values, TRUE) ? $x : NULL, $orig_values);

    return array_filter($intersect_map, function ($x) {
      return $x !== NULL;
    });
  }

  /**
   * Get an array of duplicate field values.
   *
+38 −0
Original line number Diff line number Diff line
@@ -288,4 +288,42 @@ public function testValidationMultiple() {

  }

  /**
   * Tests the UniqueField validation constraint validator with regards to case-insensitivity.
   *
   * Case 5. Try to create another entity with existing value for unique field with different capitalization.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   *
   * @covers ::validate
   */
  public function testValidationCaseInsensitive(): void {
    // Create entity with two values for the testing field.
    $definition = [
      'id' => (int) rand(0, getrandmax()),
      'user_id' => 0,
      'field_test_text' => [
        'text1',
        'text2',
      ],
    ];
    $entity = EntityTestUniqueConstraint::create($definition);
    $entity->save();

    // Create another entity with two values for the testing field, one identical
    // to other value, but with different capitalization which should still trigger a validation error.
    $definition = [
      'id' => (int) rand(0, getrandmax()),
      'user_id' => 0,
      'field_test_text' => [
        'Text1',
        'text3',
      ],
    ];
    $entity = EntityTestUniqueConstraint::create($definition);
    $violations = $entity->validate();
    $this->assertCount(1, $violations);
    $this->assertEquals('field_test_text.0', $violations[0]->getPropertyPath());
  }

}