public function testValidPropertyPath() { $path = new PropertyPath('reference.traversable[index].property'); $this->assertEquals('reference', $path->getCurrent()); $this->assertTrue($path->hasNext()); $this->assertTrue($path->isProperty()); $this->assertFalse($path->isIndex()); $path->next(); $this->assertEquals('traversable', $path->getCurrent()); $this->assertTrue($path->hasNext()); $this->assertTrue($path->isProperty()); $this->assertFalse($path->isIndex()); $path->next(); $this->assertEquals('index', $path->getCurrent()); $this->assertTrue($path->hasNext()); $this->assertFalse($path->isProperty()); $this->assertTrue($path->isIndex()); $path->next(); $this->assertEquals('property', $path->getCurrent()); $this->assertFalse($path->hasNext()); $this->assertTrue($path->isProperty()); $this->assertFalse($path->isIndex()); }
protected function updateProperty(&$objectOrArray, PropertyPath $propertyPath) { if (is_object($objectOrArray) && $propertyPath->isIndex()) { if (!$objectOrArray instanceof \ArrayAccess) { throw new InvalidPropertyException(sprintf('Index "%s" cannot be modified in object of type "%s" because it doesn\'t implement \\ArrayAccess', $propertyPath->getCurrent(), get_class($objectOrArray))); } $objectOrArray[$propertyPath->getCurrent()] = $this->getData(); } else { if (is_object($objectOrArray)) { $reflClass = new \ReflectionClass($objectOrArray); $setter = 'set' . ucfirst($propertyPath->getCurrent()); $property = $propertyPath->getCurrent(); if ($reflClass->hasMethod($setter)) { if (!$reflClass->getMethod($setter)->isPublic()) { throw new PropertyAccessDeniedException(sprintf('Method "%s()" is not public in class "%s"', $setter, $reflClass->getName())); } $objectOrArray->{$setter}($this->getData()); } else { if ($reflClass->hasProperty($property)) { if (!$reflClass->getProperty($property)->isPublic()) { throw new PropertyAccessDeniedException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "set%s()"?', $property, $reflClass->getName(), ucfirst($property))); } $objectOrArray->{$property} = $this->getData(); } else { throw new InvalidPropertyException(sprintf('Neither element "%s" nor method "%s()" exists in class "%s"', $property, $setter, $reflClass->getName())); } } } else { $objectOrArray[$propertyPath->getCurrent()] = $this->getData(); } } }