/** * Set a property for a given object. * Tries to set the property the following ways: * - if target is an array, set value * - if super cow powers should be used, set value through reflection * - if public setter method exists, call it. * - if public property exists, set it directly. * - if the target object is an instance of ArrayAccess, it sets the property * on it without checking if it existed. * - else, return FALSE * * @param mixed $subject The target object or array * @param string|integer $propertyName Name or index of the property to set * @param mixed $propertyValue Value of the property * @param boolean $forceDirectAccess directly access property using reflection(!) * @return boolean TRUE if the property could be set, FALSE otherwise * @throws \InvalidArgumentException in case $object was not an object or $propertyName was not a string */ public static function setProperty(&$subject, $propertyName, $propertyValue, $forceDirectAccess = FALSE) { if (is_array($subject)) { $subject[$propertyName] = $propertyValue; return TRUE; } if (!is_object($subject)) { throw new \InvalidArgumentException('subject must be an object or array, ' . gettype($subject) . ' given.', 1237301368); } if (!is_string($propertyName) && !is_integer($propertyName)) { throw new \InvalidArgumentException('Given property name/index is not of type string or integer.', 1231178878); } if ($forceDirectAccess === TRUE) { if (property_exists(get_class($subject), $propertyName)) { $propertyReflection = new \TYPO3\Flow\Reflection\PropertyReflection(get_class($subject), $propertyName); $propertyReflection->setValue($subject, $propertyValue); } else { $subject->{$propertyName} = $propertyValue; } } elseif (is_callable(array($subject, $setterMethodName = self::buildSetterMethodName($propertyName)))) { $subject->{$setterMethodName}($propertyValue); } elseif ($subject instanceof \ArrayAccess) { $subject[$propertyName] = $propertyValue; } elseif (array_key_exists($propertyName, get_object_vars($subject))) { $subject->{$propertyName} = $propertyValue; } else { return FALSE; } return TRUE; }
/** * @test */ public function setValueEvenSetsValueOfAPublicProperty() { $reflectionProperty = new \TYPO3\Flow\Reflection\PropertyReflection(__CLASS__, 'publicProperty'); $reflectionProperty->setValue($this, 'modified'); $this->assertEquals('modified', $this->publicProperty, 'ReflectionProperty->setValue() did not successfully set the value of a public property.'); }