From b56502f023ad6c551801ed76da9ba510e1030950 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Thu, 9 Feb 2012 16:41:15 +0100 Subject: [PATCH] [Form] Added getParent() to PropertyPath --- .../Component/Form/Util/PropertyPath.php | 43 +++++++++++++++++-- .../Tests/Component/Form/PropertyPathTest.php | 21 +++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Form/Util/PropertyPath.php b/src/Symfony/Component/Form/Util/PropertyPath.php index 96fa57f202..f29aa3d515 100644 --- a/src/Symfony/Component/Form/Util/PropertyPath.php +++ b/src/Symfony/Component/Form/Util/PropertyPath.php @@ -27,26 +27,32 @@ class PropertyPath implements \IteratorAggregate * The elements of the property path * @var array */ - protected $elements = array(); + private $elements = array(); /** * The number of elements in the property path * @var integer */ - protected $length; + private $length; /** * Contains a Boolean for each property in $elements denoting whether this * element is an index. It is a property otherwise. * @var array */ - protected $isIndex = array(); + private $isIndex = array(); /** * String representation of the path * @var string */ - protected $string; + private $string; + + /** + * Positions where the individual elements start in the string representation + * @var array + */ + private $positions; /** * Parses the given property path @@ -67,6 +73,8 @@ class PropertyPath implements \IteratorAggregate $pattern = '/^(([^\.\[]+)|\[([^\]]+)\])(.*)/'; while (preg_match($pattern, $remaining, $matches)) { + $this->positions[] = $position; + if ('' !== $matches[2]) { $this->elements[] = $matches[2]; $this->isIndex[] = false; @@ -102,6 +110,33 @@ class PropertyPath implements \IteratorAggregate return $this->string; } + /** + * Returns the parent property path. + * + * The parent property path is the one that contains the same items as + * this one except for the last one. + * + * If this property path only contains one item, null is returned. + * + * @return PropertyPath The parent path or null. + */ + public function getParent() + { + if ($this->length <= 1) { + return null; + } + + $parent = clone $this; + + --$parent->length; + $parent->string = substr($parent->string, 0, $parent->positions[$parent->length]); + array_pop($parent->elements); + array_pop($parent->isIndex); + array_pop($parent->positions); + + return $parent; + } + /** * Returns a new iterator for this path * diff --git a/tests/Symfony/Tests/Component/Form/PropertyPathTest.php b/tests/Symfony/Tests/Component/Form/PropertyPathTest.php index 8ddc83eea1..76b7f69b41 100644 --- a/tests/Symfony/Tests/Component/Form/PropertyPathTest.php +++ b/tests/Symfony/Tests/Component/Form/PropertyPathTest.php @@ -391,4 +391,25 @@ class PropertyPathTest extends \PHPUnit_Framework_TestCase new PropertyPath(null); } + + public function testGetParent_dot() + { + $propertyPath = new PropertyPath('grandpa.parent.child'); + + $this->assertEquals(new PropertyPath('grandpa.parent'), $propertyPath->getParent()); + } + + public function testGetParent_index() + { + $propertyPath = new PropertyPath('grandpa.parent[child]'); + + $this->assertEquals(new PropertyPath('grandpa.parent'), $propertyPath->getParent()); + } + + public function testGetParent_noParent() + { + $propertyPath = new PropertyPath('path'); + + $this->assertNull($propertyPath->getParent()); + } }