5 * Copyright (c) 2002-2011, Sebastian Bergmann <sebastian@phpunit.de>.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * * Neither the name of Sebastian Bergmann nor the names of his
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
39 * @author Sebastian Bergmann <sebastian@phpunit.de>
40 * @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de>
41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
42 * @link http://www.phpunit.de/
43 * @since File available since Release 3.1.0
46 if (!defined('T_NAMESPACE')) {
47 define('T_NAMESPACE', 377);
55 * @author Sebastian Bergmann <sebastian@phpunit.de>
56 * @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de>
57 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
58 * @version Release: 3.5.13
59 * @link http://www.phpunit.de/
60 * @since Class available since Release 3.1.0
62 class PHPUnit_Util_Class
64 protected static $buffer = array();
67 * Starts the collection of loaded classes.
70 public static function collectStart()
72 self::$buffer = get_declared_classes();
76 * Stops the collection of loaded classes and
77 * returns the names of the loaded classes.
81 public static function collectEnd()
84 array_diff(get_declared_classes(), self::$buffer)
89 * Returns the class hierarchy for a given class.
91 * @param string $className
92 * @param boolean $asReflectionObjects
95 public static function getHierarchy($className, $asReflectionObjects = FALSE)
97 if ($asReflectionObjects) {
98 $classes = array(new ReflectionClass($className));
100 $classes = array($className);
106 if ($asReflectionObjects) {
107 $class = new ReflectionClass(
108 $classes[count($classes)-1]->getName()
111 $class = new ReflectionClass($classes[count($classes)-1]);
114 $parent = $class->getParentClass();
116 if ($parent !== FALSE) {
117 if ($asReflectionObjects) {
118 $classes[] = $parent;
120 $classes[] = $parent->getName();
131 * Returns the parameters of a function or method.
133 * @param ReflectionFunction|ReflectionMethod $method
134 * @param boolean $forCall
136 * @since Method available since Release 3.2.0
138 public static function getMethodParameters($method, $forCall = FALSE)
140 $parameters = array();
142 foreach ($method->getParameters() as $i => $parameter) {
143 $name = '$' . $parameter->getName();
153 if ($parameter->isArray()) {
154 $typeHint = 'array ';
157 $class = $parameter->getClass();
160 catch (ReflectionException $e) {
165 $typeHint = $class->getName() . ' ';
169 if ($parameter->isDefaultValueAvailable()) {
170 $value = $parameter->getDefaultValue();
171 $default = ' = ' . var_export($value, TRUE);
174 else if ($parameter->isOptional()) {
175 $default = ' = null';
181 if ($parameter->isPassedByReference()) {
185 $parameters[] = $typeHint . $ref . $name . $default;
188 return join(', ', $parameters);
192 * Returns the package information of a user-defined class.
194 * @param string $className
195 * @param string $docComment
198 public static function getPackageInformation($className, $docComment)
208 if (strpos($className, '\\') !== FALSE) {
209 $result['namespace'] = self::arrayToName(
210 explode('\\', $className)
214 if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
215 $result['category'] = $matches[1];
218 if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
219 $result['package'] = $matches[1];
220 $result['fullPackage'] = $matches[1];
223 if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
224 $result['subpackage'] = $matches[1];
225 $result['fullPackage'] .= '.' . $matches[1];
228 if (empty($result['fullPackage'])) {
229 $result['fullPackage'] = self::arrayToName(
230 explode('_', str_replace('\\', '_', $className)), '.'
238 * Returns the value of a static attribute.
239 * This also works for attributes that are declared protected or private.
241 * @param string $className
242 * @param string $attributeName
244 * @throws InvalidArgumentException
245 * @since Method available since Release 3.4.0
247 public static function getStaticAttribute($className, $attributeName)
249 if (!is_string($className)) {
250 throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
253 if (!class_exists($className)) {
254 throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class name');
257 if (!is_string($attributeName)) {
258 throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
261 $class = new ReflectionClass($className);
264 $attributes = $class->getStaticProperties();
266 if (array_key_exists($attributeName, $attributes)) {
267 return $attributes[$attributeName];
270 $class = $class->getParentClass();
273 throw new PHPUnit_Framework_Exception(
275 'Attribute "%s" not found in class.',
283 * Returns the value of an object's attribute.
284 * This also works for attributes that are declared protected or private.
286 * @param object $object
287 * @param string $attributeName
289 * @throws InvalidArgumentException
290 * @since Method available since Release 3.4.0
292 public static function getObjectAttribute($object, $attributeName)
294 if (!is_object($object)) {
295 throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'object');
298 if (!is_string($attributeName)) {
299 throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
302 PHPUnit_Framework_Assert::assertObjectHasAttribute(
303 $attributeName, $object
307 $attribute = new ReflectionProperty($object, $attributeName);
310 catch (ReflectionException $e) {
311 $reflector = new ReflectionObject($object);
313 while ($reflector = $reflector->getParentClass()) {
315 $attribute = $reflector->getProperty($attributeName);
319 catch(ReflectionException $e) {
324 if ($attribute == NULL || $attribute->isPublic()) {
325 return $object->$attributeName;
327 $array = (array)$object;
328 $protectedName = "\0*\0" . $attributeName;
330 if (array_key_exists($protectedName, $array)) {
331 return $array[$protectedName];
333 $classes = self::getHierarchy(get_class($object));
335 foreach ($classes as $class) {
336 $privateName = sprintf(
343 if (array_key_exists($privateName, $array)) {
344 return $array[$privateName];
350 throw new PHPUnit_Framework_Exception(
352 'Attribute "%s" not found in object.',
362 * @param string $className
364 * @since Method available since Release 3.4.0
366 public static function parseFullyQualifiedClassName($className)
370 'className' => $className,
371 'fullyQualifiedClassName' => $className
374 if (strpos($className, '\\') !== FALSE) {
375 $tmp = explode('\\', $className);
376 $result['className'] = $tmp[count($tmp)-1];
377 $result['namespace'] = self::arrayToName($tmp);
384 * Returns the package information of a user-defined class.
386 * @param array $parts
387 * @param string $join
389 * @since Method available since Release 3.2.12
391 protected static function arrayToName(array $parts, $join = '\\')
395 if (count($parts) > 1) {
398 $result = join($join, $parts);