/**
  * Creates a new violation path from a string.
  *
  * @param string $violationPath The property path of a {@link ConstraintViolation}
  *                              object.
  */
 public function __construct($violationPath)
 {
     $path = new PropertyPath($violationPath);
     $elements = $path->getElements();
     $data = false;
     for ($i = 0, $l = count($elements); $i < $l; ++$i) {
         if (!$data) {
             // The element "data" has not yet been passed
             if ('children' === $elements[$i] && $path->isProperty($i)) {
                 // Skip element "children"
                 ++$i;
                 // Next element must exist and must be an index
                 // Otherwise consider this the end of the path
                 if ($i >= $l || !$path->isIndex($i)) {
                     break;
                 }
                 // All the following index items (regardless if .children is
                 // explicitly used) are children and grand-children
                 for (; $i < $l && $path->isIndex($i); ++$i) {
                     $this->elements[] = $elements[$i];
                     $this->isIndex[] = true;
                     $this->mapsForm[] = true;
                 }
                 // Rewind the pointer as the last element above didn't match
                 // (even if the pointer was moved forward)
                 --$i;
             } elseif ('data' === $elements[$i] && $path->isProperty($i)) {
                 // Skip element "data"
                 ++$i;
                 // End of path
                 if ($i >= $l) {
                     break;
                 }
                 $this->elements[] = $elements[$i];
                 $this->isIndex[] = $path->isIndex($i);
                 $this->mapsForm[] = false;
                 $data = true;
             } else {
                 // Neither "children" nor "data" property found
                 // Consider this the end of the path
                 break;
             }
         } else {
             // Already after the "data" element
             // Pick everything as is
             $this->elements[] = $elements[$i];
             $this->isIndex[] = $path->isIndex($i);
             $this->mapsForm[] = false;
         }
     }
     $this->length = count($this->elements);
     $this->buildString();
 }
 /**
  * Creates a new violation path from a string.
  *
  * @param string $violationPath The property path of a {@link ConstraintViolation}
  *                              object.
  */
 public function __construct($violationPath)
 {
     $path = new PropertyPath($violationPath);
     $elements = $path->getElements();
     $data = false;
     for ($i = 0, $l = count($elements); $i < $l; ++$i) {
         if (!$data) {
             // The element "data" has not yet been passed
             if ('children' === $elements[$i] && $path->isProperty($i)) {
                 // Skip element "children"
                 ++$i;
                 // Next element must exist and must be an index
                 // Otherwise consider this the end of the path
                 if ($i >= $l || !$path->isIndex($i)) {
                     break;
                 }
                 $this->elements[] = $elements[$i];
                 $this->isIndex[] = true;
                 $this->mapsForm[] = true;
             } elseif ('data' === $elements[$i] && $path->isProperty($i)) {
                 // Skip element "data"
                 ++$i;
                 // End of path
                 if ($i >= $l) {
                     break;
                 }
                 $this->elements[] = $elements[$i];
                 $this->isIndex[] = $path->isIndex($i);
                 $this->mapsForm[] = false;
                 $data = true;
             } else {
                 // Neither "children" nor "data" property found
                 // Consider this the end of the path
                 break;
             }
         } else {
             // Already after the "data" element
             // Pick everything as is
             $this->elements[] = $elements[$i];
             $this->isIndex[] = $path->isIndex($i);
             $this->mapsForm[] = false;
         }
     }
     $this->length = count($this->elements);
     $this->buildString();
 }
 /**
  * @expectedException \OutOfBoundsException
  */
 public function testIsIndexDoesNotAcceptNegativeIndices()
 {
     $propertyPath = new PropertyPath('grandpa.parent[child]');
     $propertyPath->isIndex(-1);
 }
 /**
  * @dataProvider provideCustomDataErrorTests
  */
 public function testCustomDataErrorMapping($target, $mapFrom, $mapTo, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath)
 {
     $violation = $this->getConstraintViolation($violationPath);
     $parent = $this->getForm('parent', null, null, array($mapFrom => $mapTo));
     $child = $this->getForm($childName, $childPath);
     $grandChild = $this->getForm($grandChildName, $grandChildPath);
     $parent->add($child);
     $child->add($grandChild);
     // Add a field mapped to the first element of $mapFrom
     // to try to distract the algorithm
     // Only add it if we expect the error to come up on a different
     // level than LEVEL_0, because in this case the error would
     // (correctly) be mapped to the distraction field
     if ($target !== self::LEVEL_0) {
         $mapFromPath = new PropertyPath($mapFrom);
         $mapFromPrefix = $mapFromPath->isIndex(0) ? '[' . $mapFromPath->getElement(0) . ']' : $mapFromPath->getElement(0);
         $distraction = $this->getForm('distraction', $mapFromPrefix);
         $parent->add($distraction);
     }
     $this->mapper->mapViolation($violation, $parent);
     if ($target !== self::LEVEL_0) {
         $this->assertCount(0, $distraction->getErrors(), 'distraction should not have an error, but has one');
     }
     if (self::LEVEL_0 === $target) {
         $this->assertEquals(array($this->getFormError($violation)), $parent->getErrors(), $parent->getName() . ' should have an error, but has none');
         $this->assertCount(0, $child->getErrors(), $childName . ' should not have an error, but has one');
         $this->assertCount(0, $grandChild->getErrors(), $grandChildName . ' should not have an error, but has one');
     } elseif (self::LEVEL_1 === $target) {
         $this->assertCount(0, $parent->getErrors(), $parent->getName() . ' should not have an error, but has one');
         $this->assertEquals(array($this->getFormError($violation)), $child->getErrors(), $childName . ' should have an error, but has none');
         $this->assertCount(0, $grandChild->getErrors(), $grandChildName . ' should not have an error, but has one');
     } else {
         $this->assertCount(0, $parent->getErrors(), $parent->getName() . ' should not have an error, but has one');
         $this->assertCount(0, $child->getErrors(), $childName . ' should not have an error, but has one');
         $this->assertEquals(array($this->getFormError($violation)), $grandChild->getErrors(), $grandChildName . ' should have an error, but has none');
     }
 }
 /**
  * Replaces a sub-path by a different (sub-) path.
  *
  * @param integer                      $offset     The offset at which to replace.
  * @param integer                      $length     The length of the piece to replace.
  * @param PropertyPathInterface|string $path       The path to insert.
  * @param integer                      $pathOffset The offset where the inserted piece
  *                                                 starts in $path.
  * @param integer                      $pathLength The length of the inserted piece.
  *                                                 If 0, the full path is inserted.
  *
  * @throws OutOfBoundsException If the offset is invalid
  */
 public function replace($offset, $length, $path, $pathOffset = 0, $pathLength = 0)
 {
     if (is_string($path)) {
         $path = new PropertyPath($path);
     }
     if ($offset < 0 && abs($offset) <= $this->getLength()) {
         $offset = $this->getLength() + $offset;
     } elseif (!isset($this->elements[$offset])) {
         throw new OutOfBoundsException('The offset ' . $offset . ' is not within the property path');
     }
     if (0 === $pathLength) {
         $pathLength = $path->getLength() - $pathOffset;
     }
     $this->resize($offset, $length, $pathLength);
     for ($i = 0; $i < $pathLength; ++$i) {
         $this->elements[$offset + $i] = $path->getElement($pathOffset + $i);
         $this->isIndex[$offset + $i] = $path->isIndex($pathOffset + $i);
     }
 }
Beispiel #6
0
 /**
  * @param $path
  * @param $haystack
  * @return bool
  */
 private function valueExist($path, array $haystack)
 {
     $propertyPath = new PropertyPath($path);
     $length = $propertyPath->getLength();
     $valueExist = true;
     for ($i = 0; $i < $length; ++$i) {
         $property = $propertyPath->getElement($i);
         $isIndex = $propertyPath->isIndex($i);
         $propertyExist = $this->arrayPropertyExists($property, $haystack);
         if ($isIndex && !$propertyExist) {
             $valueExist = false;
             break;
         }
     }
     unset($propertyPath);
     return $valueExist;
 }