Created
February 26, 2015 10:09
-
-
Save albe/adfb00e4c7f10ebf5379 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Classes/TYPO3/Flow/Reflection/ObjectAccess.php | 47 ++++++++++++++++++++++++++ | |
1 file changed, 47 insertions(+) | |
diff --git a/Classes/TYPO3/Flow/Reflection/ObjectAccess.php b/Classes/TYPO3/Flow/Reflection/ObjectAccess.php | |
index 014e2f3..0c84937 100644 | |
--- a/Classes/TYPO3/Flow/Reflection/ObjectAccess.php | |
+++ b/Classes/TYPO3/Flow/Reflection/ObjectAccess.php | |
@@ -206,6 +206,7 @@ class ObjectAccess { | |
* 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 property value is a collection and add/remove methods exist, call them. | |
* - 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 | |
@@ -239,6 +240,30 @@ class ObjectAccess { | |
} else { | |
$subject->$propertyName = $propertyValue; | |
} | |
+ } elseif ((is_array($propertyValue) || $propertyValue instanceof \Traversable) && | |
+ is_callable(array($subject, $addMethodName = self::buildAdderMethodName($propertyName))) && | |
+ is_callable(array($subject, $removeMethodName = self::buildRemoverMethodName($propertyName)))) { | |
+ $itemsToAdd = is_array($propertyValue) ? $propertyValue : iterator_to_array($propertyValue); | |
+ $itemsToRemove = array(); | |
+ $currentValue = self::getProperty($subject, $propertyName); | |
+ if (is_array($currentValue) || $currentValue instanceof \Traversable) { | |
+ foreach ($currentValue as $currentItem) { | |
+ foreach ($itemsToAdd as $key => $newItem) { | |
+ if ($currentItem === $newItem) { | |
+ unset($itemsToAdd[$key]); | |
+ // Continue to next $currentItem | |
+ continue 2; | |
+ } | |
+ } | |
+ $itemsToRemove[] = $currentItem; | |
+ } | |
+ } | |
+ foreach ($itemsToRemove as $item) { | |
+ $subject->$removeMethodName($item); | |
+ } | |
+ foreach ($itemsToAdd as $item) { | |
+ $subject->$addMethodName($item); | |
+ } | |
} elseif (is_callable(array($subject, $setterMethodName = self::buildSetterMethodName($propertyName)))) { | |
$subject->$setterMethodName($propertyValue); | |
} elseif ($subject instanceof \ArrayAccess) { | |
@@ -413,4 +438,26 @@ class ObjectAccess { | |
static public function buildSetterMethodName($propertyName) { | |
return 'set' . ucfirst($propertyName); | |
} | |
+ | |
+ /** | |
+ * Build the remover method name for a given property by singularizing the name | |
+ * and capitalizing the first letter of the property, then prepending it with "remove". | |
+ * | |
+ * @param string $propertyName Name of the property | |
+ * @return string Name of the remover method name | |
+ */ | |
+ static public function buildRemoverMethodName($propertyName) { | |
+ return 'remove' . ucfirst(\Doctrine\Common\Inflector\Inflector::singularize($propertyName)); | |
+ } | |
+ | |
+ /** | |
+ * Build the adder method name for a given property by singularizing the name | |
+ * and capitalizing the first letter of the property, then prepending it with "add". | |
+ * | |
+ * @param string $propertyName Name of the property | |
+ * @return string Name of the adder method name | |
+ */ | |
+ static public function buildAdderMethodName($propertyName) { | |
+ return 'add' . ucfirst(\Doctrine\Common\Inflector\Inflector::singularize($propertyName)); | |
+ } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment