Added parameter reflection backport!
authorSebastian Kurfürst <sebastian@typo3.org>
Thu, 26 Mar 2009 15:21:44 +0000 (15:21 +0000)
committerSebastian Kurfürst <sebastian@typo3.org>
Thu, 26 Mar 2009 15:21:44 +0000 (15:21 +0000)
typo3/sysext/extbase/Classes/Reflection/ClassReflection.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Reflection/DocCommentParser.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Reflection/Exception.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Reflection/MethodReflection.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Reflection/ObjectAccess.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Reflection/ParameterReflection.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Reflection/PropertyReflection.php [new file with mode: 0644]

diff --git a/typo3/sysext/extbase/Classes/Reflection/ClassReflection.php b/typo3/sysext/extbase/Classes/Reflection/ClassReflection.php
new file mode 100644 (file)
index 0000000..efb2c7f
--- /dev/null
@@ -0,0 +1,210 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 framework.                            *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: ClassReflection.php 1811 2009-01-28 12:04:49Z robert $
+ */
+
+/**
+ * Extended version of the ReflectionClass
+ *
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: ClassReflection.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_ExtBase_Reflection_ClassReflection extends ReflectionClass {
+
+       /**
+        * @var Tx_ExtBase_Reflection_DocCommentParser Holds an instance of the doc comment parser for this class
+        */
+       protected $docCommentParser;
+
+       /**
+        * The constructor - initializes the class Tx_ExtBase_Reflection_reflector
+        *
+        * @param  string $className: Name of the class Tx_ExtBase_Reflection_to reflect
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function __construct($className) {
+               parent::__construct($className);
+       }
+
+       /**
+        * Replacement for the original getMethods() method which makes sure
+        * that Tx_ExtBase_Reflection_MethodReflection objects are returned instead of the
+        * orginal ReflectionMethod instances.
+        *
+        * @param  long $filter: A filter mask
+        * @return Tx_ExtBase_Reflection_MethodReflection Method reflection objects of the methods in this class
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getMethods($filter = NULL) {
+               $extendedMethods = array();
+
+               $methods = ($filter === NULL ? parent::getMethods() : parent::getMethods($filter));
+               foreach ($methods as $method) {
+                       $extendedMethods[] = new Tx_ExtBase_Reflection_MethodReflection($this->getName(), $method->getName());
+               }
+               return $extendedMethods;
+       }
+
+       /**
+        * Replacement for the original getMethod() method which makes sure
+        * that Tx_ExtBase_Reflection_MethodReflection objects are returned instead of the
+        * orginal ReflectionMethod instances.
+        *
+        * @return Tx_ExtBase_Reflection_MethodReflection Method reflection object of the named method
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getMethod($name) {
+               $parentMethod = parent::getMethod($name);
+               if (!is_object($parentMethod)) return $parentMethod;
+               return new Tx_ExtBase_Reflection_MethodReflection($this->getName(), $parentMethod->getName());
+       }
+
+       /**
+        * Replacement for the original getConstructor() method which makes sure
+        * that Tx_ExtBase_Reflection_MethodReflection objects are returned instead of the
+        * orginal ReflectionMethod instances.
+        *
+        * @return Tx_ExtBase_Reflection_MethodReflection Method reflection object of the constructor method
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getConstructor() {
+               $parentConstructor = parent::getConstructor();
+               if (!is_object($parentConstructor)) return $parentConstructor;
+               return new Tx_ExtBase_Reflection_MethodReflection($this->getName(), $parentConstructor->getName());
+       }
+
+       /**
+        * Replacement for the original getProperties() method which makes sure
+        * that Tx_ExtBase_Reflection_PropertyReflection objects are returned instead of the
+        * orginal ReflectionProperty instances.
+        *
+        * @param  long $filter: A filter mask
+        * @return array of Tx_ExtBase_Reflection_PropertyReflection Property reflection objects of the properties in this class
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getProperties($filter = NULL) {
+               $extendedProperties = array();
+               $properties = ($filter === NULL ? parent::getProperties() : parent::getProperties($filter));
+               foreach ($properties as $property) {
+                       $extendedProperties[] = new Tx_ExtBase_Reflection_PropertyReflection($this->getName(), $property->getName());
+               }
+               return $extendedProperties;
+       }
+
+       /**
+        * Replacement for the original getProperty() method which makes sure
+        * that a Tx_ExtBase_Reflection_PropertyReflection object is returned instead of the
+        * orginal ReflectionProperty instance.
+        *
+        * @param  string $name: Name of the property
+        * @return Tx_ExtBase_Reflection_PropertyReflection Property reflection object of the specified property in this class
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getProperty($name) {
+               return new Tx_ExtBase_Reflection_PropertyReflection($this->getName(), $name);
+       }
+
+       /**
+        * Replacement for the original getInterfaces() method which makes sure
+        * that Tx_ExtBase_Reflection_ClassReflection objects are returned instead of the
+        * orginal ReflectionClass instances.
+        *
+        * @return array of Tx_ExtBase_Reflection_ClassReflection Class reflection objects of the properties in this class
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getInterfaces() {
+               $extendedInterfaces = array();
+               $interfaces = parent::getInterfaces();
+               foreach ($interfaces as $interface) {
+                       $extendedInterfaces[] = new Tx_ExtBase_Reflection_ClassReflection($interface->getName());
+               }
+               return $extendedInterfaces;
+       }
+
+       /**
+        * Replacement for the original getParentClass() method which makes sure
+        * that a Tx_ExtBase_Reflection_ClassReflection object is returned instead of the
+        * orginal ReflectionClass instance.
+        *
+        * @return Tx_ExtBase_Reflection_ClassReflection Reflection of the parent class - if any
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getParentClass() {
+               $parentClass = parent::getParentClass();
+               return ($parentClass === NULL) ? NULL : new Tx_ExtBase_Reflection_ClassReflection($parentClass->getName());
+       }
+
+       /**
+        * Checks if the doc comment of this method is tagged with
+        * the specified tag
+        *
+        * @param  string $tag: Tag name to check for
+        * @return boolean TRUE if such a tag has been defined, otherwise FALSE
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function isTaggedWith($tag) {
+               $result = $this->getDocCommentParser()->isTaggedWith($tag);
+               return $result;
+       }
+
+       /**
+        * Returns an array of tags and their values
+        *
+        * @return array Tags and values
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagsValues() {
+               return $this->getDocCommentParser()->getTagsValues();
+       }
+
+       /**
+        * Returns the values of the specified tag
+        * @return array Values of the given tag
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagValues($tag) {
+               return $this->getDocCommentParser()->getTagValues($tag);
+       }
+
+       /**
+        * Returns an instance of the doc comment parser and
+        * runs the parse() method.
+        *
+        * @return Tx_ExtBase_Reflection_DocCommentParser
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       protected function getDocCommentParser() {
+               if (!is_object($this->docCommentParser)) {
+                       $this->docCommentParser = new Tx_ExtBase_Reflection_DocCommentParser;
+                       $this->docCommentParser->parseDocComment($this->getDocComment());
+               }
+               return $this->docCommentParser;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Reflection/DocCommentParser.php b/typo3/sysext/extbase/Classes/Reflection/DocCommentParser.php
new file mode 100644 (file)
index 0000000..f10152e
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 framework.                            *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: DocCommentParser.php 1966 2009-03-03 13:46:17Z k-fish $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+
+/**
+ * A little parser which creates tag objects from doc comments
+ *
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: DocCommentParser.php 1966 2009-03-03 13:46:17Z k-fish $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_ExtBase_Reflection_DocCommentParser {
+
+       /**
+        * @var string The description as found in the doc comment
+        */
+       protected $description = '';
+
+       /**
+        * @var array An array of tag names and their values (multiple values are possible)
+        */
+       protected $tags = array();
+
+       /**
+        * Parses the given doc comment and saves the result (description and
+        * tags) in the parser's object. They can be retrieved by the
+        * getTags() getTagValues() and getDescription() methods.
+        *
+        * @param string $docComment A doc comment as returned by the reflection getDocComment() method
+        * @return void
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function parseDocComment($docComment) {
+               $this->description = '';
+               $this->tags = array();
+
+               $lines = explode(chr(10), $docComment);
+               foreach ($lines as $line) {
+                       if (strlen($line) > 0 && strpos($line, '@') !== FALSE) {
+                               $this->parseTag(substr($line, strpos($line, '@')));
+                       } else if (count($this->tags) === 0) {
+                               $this->description .= preg_replace('/\s*\\/?[\\\\*]*(.*)$/', '$1', $line) . chr(10);
+                       }
+               }
+               $this->description = trim($this->description);
+       }
+
+       /**
+        * Returns the tags which have been previously parsed
+        *
+        * @return array Array of tag names and their (multiple) values
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagsValues() {
+               return $this->tags;
+       }
+
+       /**
+        * Returns the values of the specified tag. The doc comment
+        * must be parsed with parseDocComment() before tags are
+        * available.
+        *
+        * @param string $tagName The tag name to retrieve the values for
+        * @return array The tag's values
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagValues($tagName) {
+               if (!$this->isTaggedWith($tagName)) throw new RuntimeException('Tag "' . $tagName . '" does not exist.', 1169128255);
+               return $this->tags[$tagName];
+       }
+
+       /**
+        * Checks if a tag with the given name exists
+        *
+        * @param string $tagName The tag name to check for
+        * @return boolean TRUE the tag exists, otherwise FALSE
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function isTaggedWith($tagName) {
+               return (isset($this->tags[$tagName]));
+       }
+
+       /**
+        * Returns the description which has been previously parsed
+        *
+        * @return string The description which has been parsed
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function getDescription() {
+               return $this->description;
+       }
+
+       /**
+        * Parses a line of a doc comment for a tag and its value.
+        * The result is stored in the interal tags array.
+        *
+        * @param string $line A line of a doc comment which starts with an @-sign
+        * @return void
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       protected function parseTag($line) {
+               $tagAndValue = preg_split('/\s/', $line, 2);
+               $tag = substr($tagAndValue[0], 1);
+               if (count($tagAndValue) > 1) {
+                       $this->tags[$tag][] = trim($tagAndValue[1]);
+               } else {
+                       $this->tags[$tag] = array();
+               }
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Reflection/Exception.php b/typo3/sysext/extbase/Classes/Reflection/Exception.php
new file mode 100644 (file)
index 0000000..405879b
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 framework.                            *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: Exception.php 1811 2009-01-28 12:04:49Z robert $
+ */
+
+/**
+ * A generic Reflection Exception
+ *
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: Exception.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_ExtBase_Reflection_Exception extends Tx_ExtBase_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Reflection/MethodReflection.php b/typo3/sysext/extbase/Classes/Reflection/MethodReflection.php
new file mode 100644 (file)
index 0000000..198e80e
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 framework.                            *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: MethodReflection.php 1811 2009-01-28 12:04:49Z robert $
+ */
+
+/**
+ * Extended version of the ReflectionMethod
+ *
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: MethodReflection.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_ExtBase_Reflection_MethodReflection extends ReflectionMethod {
+
+       /**
+        * @var Tx_ExtBase_Reflection_DocCommentParser: An instance of the doc comment parser
+        */
+       protected $docCommentParser;
+
+       /**
+        * The constructor, initializes the reflection class
+        *
+        * @param  string $className Name of the method's class
+        * @param  string $methodName Name of the method to reflect
+        * @return void
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function __construct($className, $methodName) {
+               parent::__construct($className, $methodName);
+       }
+
+       /**
+        * Returns the declaring class
+        *
+        * @return Tx_ExtBase_Reflection_ClassReflection The declaring class
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getDeclaringClass() {
+               return new Tx_ExtBase_Reflection_ClassReflection(parent::getDeclaringClass()->getName());
+       }
+
+       /**
+        * Replacement for the original getParameters() method which makes sure
+        * that Tx_ExtBase_Reflection_ParameterReflection objects are returned instead of the
+        * orginal ReflectionParameter instances.
+        *
+        * @return array of Tx_ExtBase_Reflection_ParameterReflection Parameter reflection objects of the parameters of this method
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getParameters() {
+               $extendedParameters = array();
+               foreach (parent::getParameters() as $parameter) {
+                       $extendedParameters[] = new Tx_ExtBase_Reflection_ParameterReflection(array($this->getDeclaringClass()->getName(), $this->getName()), $parameter->getName());
+               }
+               return $extendedParameters;
+       }
+
+       /**
+        * Checks if the doc comment of this method is tagged with
+        * the specified tag
+        *
+        * @param string $tag Tag name to check for
+        * @return boolean TRUE if such a tag has been defined, otherwise FALSE
+        */
+       public function isTaggedWith($tag) {
+               $result = $this->getDocCommentParser()->isTaggedWith($tag);
+               return $result;
+       }
+
+       /**
+        * Returns an array of tags and their values
+        *
+        * @return array Tags and values
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagsValues() {
+               return $this->getDocCommentParser()->getTagsValues();
+       }
+
+       /**
+        * Returns the values of the specified tag
+        *
+        * @param string $tag Tag name to check for
+        * @return array Values of the given tag
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagValues($tag) {
+               return $this->getDocCommentParser()->getTagValues($tag);
+       }
+
+       /**
+        * Returns an instance of the doc comment parser and
+        * runs the parse() method.
+        *
+        * @return Tx_ExtBase_Reflection_DocCommentParser
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       protected function getDocCommentParser() {
+               if (!is_object($this->docCommentParser)) {
+                       $this->docCommentParser = new Tx_ExtBase_Reflection_DocCommentParser;
+                       $this->docCommentParser->parseDocComment($this->getDocComment());
+               }
+               return $this->docCommentParser;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Reflection/ObjectAccess.php b/typo3/sysext/extbase/Classes/Reflection/ObjectAccess.php
new file mode 100644 (file)
index 0000000..295f2c4
--- /dev/null
@@ -0,0 +1,180 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 framework.                            *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: ObjectAccess.php 2031 2009-03-24 11:36:56Z robert $
+ */
+/**
+ * Provides methods to call appropriate getter/setter on an object given the
+ * property name. It does this following these rules:
+ * - if the target object is an instance of ArrayAccess, it gets/sets the property
+ * - if public getter/setter method exists, call it.
+ * - if public property exists, return/set the value of it.
+ * - else, throw exception
+ *
+ * @package
+ * @subpackage
+ * @version $Id: ObjectAccess.php 2031 2009-03-24 11:36:56Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_ExtBase_Reflection_ObjectAccess {
+
+       const ACCESS_GET = 0;
+       const ACCESS_SET = 1;
+       const ACCESS_PUBLIC = 2;
+
+       /**
+        * Get a property of a given object.
+        * Tries to get the property the following ways:
+        * - if the target object is an instance of ArrayAccess, it gets the property
+        *   on it if it exists.
+        * - if public getter method exists, call it.
+        * - if public property exists, return the value of it.
+        * - else, throw exception
+        *
+        * @param object $object Object to get the property from
+        * @param string $propertyName name of the property to retrieve
+        * @return object Value of the property.
+        * @author Robert Lemke <robert@typo3.org>
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       static public function getProperty($object, $propertyName) {
+               if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301367);
+               if (!is_string($propertyName)) throw new InvalidArgumentException('Given property name is not of type string.', 1231178303);
+
+               if (is_callable(array($object, $getterMethodName = self::buildGetterMethodName($propertyName)))) {
+                       return call_user_func(array($object, $getterMethodName));
+               } elseif ($object instanceof ArrayAccess && isset($object[$propertyName])) {
+                       return $object[$propertyName];
+               } elseif (array_key_exists($propertyName, get_object_vars($object))) {
+                       return $object->$propertyName;
+               }
+               return NULL;
+       }
+
+       /**
+        * Set a property for a given object.
+        * Tries to set the property the following ways:
+        * - 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 object $object The target object
+        * @param string $propertyName Name of the property to set
+        * @param object $propertyValue Value of the property
+        * @return void
+        * @throws Tx_ExtBase_Reflection_Exception if property was could not be set
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       static public function setProperty($object, $propertyName, $propertyValue) {
+               if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301368);
+               if (!is_string($propertyName)) throw new InvalidArgumentException('Given property name is not of type string.', 1231178878);
+
+               if (is_callable(array($object, $setterMethodName = self::buildSetterMethodName($propertyName)))) {
+                       call_user_func(array($object, $setterMethodName), $propertyValue);
+               } elseif ($object instanceof \ArrayAccess) {
+                       $object[$propertyName] = $propertyValue;
+               } elseif (array_key_exists($propertyName, get_object_vars($object))) {
+                       $object->$propertyName = $propertyValue;
+               } else {
+                       return FALSE;
+               }
+               return TRUE;
+       }
+
+       /**
+        * Returns an array of properties which can be get/set with the getProperty
+        * and setProperty methods.
+        * Includes the following properties:
+        * - which can be set through a public setter method.
+        * - public properties which can be directly set.
+        *
+        * @param object $object Object to receive property names for
+        * @return array Array of all declared property names
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @todo What to do with ArrayAccess
+        */
+       static public function getAccessiblePropertyNames($object) {
+               if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301369);
+               $declaredPropertyNames = array_keys(get_class_vars(get_class($object)));
+
+               foreach (get_class_methods($object) as $methodName) {
+                       if (substr($methodName, 0, 3) === 'get') {
+                               $declaredPropertyNames[] = lcfirst(substr($methodName, 3));
+                       }
+               }
+
+               $propertyNames = array_unique($declaredPropertyNames);
+               sort($propertyNames);
+               return $propertyNames;
+       }
+
+       /**
+        * Get all properties (names and their current values) of the current
+        * $object that are accessible through this class.
+        *
+        * @param object $object Object to get all properties from.
+        * @return array Associative array of all properties.
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @todo What to do with ArrayAccess
+        */
+       static public function getAccessibleProperties($object) {
+               if (!is_object($object)) throw new InvalidArgumentException('$object must be an object, ' . gettype($object). ' given.', 1237301370);
+               $properties = array();
+               foreach (self::getAccessiblePropertyNames($object) as $propertyName) {
+                       $properties[$propertyName] = self::getProperty($object, $propertyName);
+               }
+               return $properties;
+       }
+
+       /**
+        * Build the getter method name for a given property by capitalizing the
+        * first letter of the property, and prepending it with "get".
+        *
+        * @param string $property Name of the property
+        * @return string Name of the getter method name
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       static protected function buildGetterMethodName($property) {
+               return 'get' . ucfirst($property);
+       }
+
+       /**
+        * Build the setter method name for a given property by capitalizing the
+        * first letter of the property, and prepending it with "set".
+        *
+        * @param string $property Name of the property
+        * @return string Name of the setter method name
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       static protected function buildSetterMethodName($property) {
+               return 'set' . ucfirst($property);
+       }
+}
+
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Reflection/ParameterReflection.php b/typo3/sysext/extbase/Classes/Reflection/ParameterReflection.php
new file mode 100644 (file)
index 0000000..971344f
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 framework.                            *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: ParameterReflection.php 1811 2009-01-28 12:04:49Z robert $
+ */
+
+/**
+ * Extended version of the ReflectionParameter
+ *
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: ParameterReflection.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_ExtBase_Reflection_ParameterReflection extends ReflectionParameter {
+
+       /**
+        * The constructor, initializes the reflection parameter
+        *
+        * @param  string $functionName: Name of the function
+        * @param  string $propertyName: Name of the property to reflect
+        * @return void
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function __construct($function, $parameterName) {
+               parent::__construct($function, $parameterName);
+       }
+
+       /**
+        * Returns the declaring class
+        *
+        * @return Tx_ExtBase_Reflection_ClassReflection The declaring class
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getDeclaringClass() {
+               return new Tx_ExtBase_Reflection_ClassReflection(parent::getDeclaringClass()->getName());
+       }
+
+       /**
+        * Returns the parameter class
+        *
+        * @return Tx_ExtBase_Reflection_ClassReflection The parameter class
+        * @author Robert Lemke <robert@typo3.org>
+        * @author Karsten Dambekalns <karsten@typo3.org>
+        */
+       public function getClass() {
+               try {
+                       $class = parent::getClass();
+               } catch (Exception $e) {
+                       return NULL;
+               }
+
+               return is_object($class) ? new Tx_ExtBase_Reflection_ClassReflection($class->getName()) : NULL;
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Reflection/PropertyReflection.php b/typo3/sysext/extbase/Classes/Reflection/PropertyReflection.php
new file mode 100644 (file)
index 0000000..b8d9133
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 framework.                            *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: PropertyReflection.php 1811 2009-01-28 12:04:49Z robert $
+ */
+
+/**
+ * Extended version of the ReflectionProperty
+ *
+ * @package FLOW3
+ * @subpackage Reflection
+ * @version $Id: PropertyReflection.php 1811 2009-01-28 12:04:49Z robert $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_ExtBase_Reflection_PropertyReflection extends ReflectionProperty {
+
+       /**
+        * @var Tx_ExtBase_Reflection_DocCommentParser: An instance of the doc comment parser
+        */
+       protected $docCommentParser;
+
+       /**
+        * The constructor, initializes the reflection class
+        *
+        * @param string $className Name of the property's class
+        * @param string $propertyName Name of the property to reflect
+        * @return void
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function __construct($className, $propertyName) {
+               parent::__construct($className, $propertyName);
+       }
+
+       /**
+        * Checks if the doc comment of this property is tagged with
+        * the specified tag
+        *
+        * @param string $tag Tag name to check for
+        * @return boolean TRUE if such a tag has been defined, otherwise FALSE
+        */
+       public function isTaggedWith($tag) {
+               $result = $this->getDocCommentParser()->isTaggedWith($tag);
+               return $result;
+       }
+
+       /**
+        * Returns an array of tags and their values
+        *
+        * @return array Tags and values
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagsValues() {
+               return $this->getDocCommentParser()->getTagsValues();
+       }
+
+       /**
+        * Returns the values of the specified tag
+        *
+        * @return array Values of the given tag
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       public function getTagValues($tag) {
+               return $this->getDocCommentParser()->getTagValues($tag);
+       }
+
+       /**
+        * Returns the value of the reflected property - even if it is protected.
+        *
+        * @param object $object Instance of the declaring class Tx_ExtBase_Reflection_to read the value from
+        * @return mixed Value of the property
+        * @throws Tx_ExtBase_Reflection_Exception
+        * @author Robert Lemke <robert@typo3.org>
+        * @author Karsten Dambekalns <karsten@typo3.org>
+        * @todo Maybe support private properties as well, as of PHP 5.3.0 we can do
+        *   $obj = new Foo;
+        *   $prop = new ReflectionProperty('Foo', 'y'); // y is private member
+        *   $prop->setAccessible(true);
+        *   var_dump($prop->getValue($obj)); // int(2)
+        */
+       public function getValue($object = NULL) {
+               if (!is_object($object)) throw new Tx_ExtBase_Reflection_Exception('$object is of type ' . gettype($object) . ', instance of class ' . $this->class . ' expected.', 1210859212);
+               if ($this->isPublic()) return parent::getValue($object);
+               if ($this->isPrivate()) throw new Tx_ExtBase_Reflection_Exception('Cannot return value of private property "' . $this->name . '.', 1210859206);
+
+               parent::setAccessible(TRUE);
+               return parent::getValue($object);
+       }
+
+       /**
+        * Returns an instance of the doc comment parser and
+        * runs the parse() method.
+        *
+        * @return Tx_ExtBase_Reflection_DocCommentParser
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       protected function getDocCommentParser() {
+               if (!is_object($this->docCommentParser)) {
+                       $this->docCommentParser = new Tx_ExtBase_Reflection_DocCommentParser;
+                       $this->docCommentParser->parseDocComment($this->getDocComment());
+               }
+               return $this->docCommentParser;
+       }
+}
+
+?>
\ No newline at end of file