Fixing file upload params ($_FILES) normalization. Closes #75
[akelos.git] / vendor / simpletest / reflection_php5.php
blob1de0f043eca0ba90ac0fdab9cfdbc138ef18f5dd
1 <?php
2 /**
3 * base include file for SimpleTest
4 * @package SimpleTest
5 * @subpackage UnitTester
6 * @version $Id: reflection_php5.php,v 1.20 2006/02/05 21:39:07 lastcraft Exp $
7 */
9 /**
10 * Version specific reflection API.
11 * @package SimpleTest
12 * @subpackage UnitTester
14 class SimpleReflection {
15 var $_interface;
17 /**
18 * Stashes the class/interface.
19 * @param string $interface Class or interface
20 * to inspect.
22 function SimpleReflection($interface) {
23 $this->_interface = $interface;
26 /**
27 * Checks that a class has been declared. Versions
28 * before PHP5.0.2 need a check that it's not really
29 * an interface.
30 * @return boolean True if defined.
31 * @access public
33 function classExists() {
34 if (! class_exists($this->_interface)) {
35 return false;
37 $reflection = new ReflectionClass($this->_interface);
38 return ! $reflection->isInterface();
41 /**
42 * Needed to kill the autoload feature in PHP5
43 * for classes created dynamically.
44 * @return boolean True if defined.
45 * @access public
47 function classExistsSansAutoload() {
48 return class_exists($this->_interface, false);
51 /**
52 * Checks that a class or interface has been
53 * declared.
54 * @return boolean True if defined.
55 * @access public
57 function classOrInterfaceExists() {
58 return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
61 /**
62 * Needed to kill the autoload feature in PHP5
63 * for classes created dynamically.
64 * @return boolean True if defined.
65 * @access public
67 function classOrInterfaceExistsSansAutoload() {
68 return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
71 /**
72 * Needed to select the autoload feature in PHP5
73 * for classes created dynamically.
74 * @param string $interface Class or interface name.
75 * @param boolean $autoload True totriggerautoload.
76 * @return boolean True if interface defined.
77 * @access private
79 function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
80 if (function_exists('interface_exists')) {
81 if (interface_exists($this->_interface, $autoload)) {
82 return true;
85 return class_exists($this->_interface, $autoload);
88 /**
89 * Gets the list of methods on a class or
90 * interface. Needs to recursively look at all of
91 * the interfaces included.
92 * @returns array List of method names.
93 * @access public
95 function getMethods() {
96 return array_unique(get_class_methods($this->_interface));
99 /**
100 * Gets the list of interfaces from a class. If the
101 * class name is actually an interface then just that
102 * interface is returned.
103 * @returns array List of interfaces.
104 * @access public
106 function getInterfaces() {
107 $reflection = new ReflectionClass($this->_interface);
108 if ($reflection->isInterface()) {
109 return array($this->_interface);
111 return $this->_onlyParents($reflection->getInterfaces());
115 * Gets the list of methods for the implemented
116 * interfaces only.
117 * @returns array List of enforced method signatures.
118 * @access public
120 function getInterfaceMethods() {
121 $methods = array();
122 foreach ($this->getInterfaces() as $interface) {
123 $methods = array_merge($methods, get_class_methods($interface));
125 return array_unique($methods);
129 * Checks to see if the method signature has to be tightly
130 * specified.
131 * @param string $method Method name.
132 * @returns boolean True if enforced.
133 * @access private
135 function _isInterfaceMethod($method) {
136 return in_array($method, $this->getInterfaceMethods());
140 * Finds the parent class name.
141 * @returns string Parent class name.
142 * @access public
144 function getParent() {
145 $reflection = new ReflectionClass($this->_interface);
146 $parent = $reflection->getParentClass();
147 if ($parent) {
148 return $parent->getName();
150 return false;
154 * Determines if the class is abstract.
155 * @returns boolean True if abstract.
156 * @access public
158 function isAbstract() {
159 $reflection = new ReflectionClass($this->_interface);
160 return $reflection->isAbstract();
164 * Wittles a list of interfaces down to only the top
165 * level parents.
166 * @param array $interfaces Reflection API interfaces
167 * to reduce.
168 * @returns array List of parent interface names.
169 * @access private
171 function _onlyParents($interfaces) {
172 $parents = array();
173 foreach ($interfaces as $interface) {
174 foreach($interfaces as $possible_parent) {
175 if ($interface->getName() == $possible_parent->getName()) {
176 continue;
178 if ($interface->isSubClassOf($possible_parent)) {
179 break;
182 $parents[] = $interface->getName();
184 return $parents;
188 * Gets the source code matching the declaration
189 * of a method.
190 * @param string $name Method name.
191 * @return string Method signature up to last
192 * bracket.
193 * @access public
195 function getSignature($name) {
196 if ($name == '__get') {
197 return 'function __get($key)';
199 if ($name == '__set') {
200 return 'function __set($key, $value)';
202 if (! is_callable(array($this->_interface, $name))) {
203 return "function $name()";
205 if ($this->_isInterfaceMethod($name)) {
206 return $this->_getFullSignature($name);
208 return "function $name()";
212 * For a signature specified in an interface, full
213 * details must be replicated to be a valid implementation.
214 * @param string $name Method name.
215 * @return string Method signature up to last
216 * bracket.
217 * @access private
219 function _getFullSignature($name) {
220 $interface = new ReflectionClass($this->_interface);
221 $method = $interface->getMethod($name);
222 $reference = $method->returnsReference() ? '&' : '';
223 return "function $reference$name(" .
224 implode(', ', $this->_getParameterSignatures($method)) .
225 ")";
229 * Gets the source code for each parameter.
230 * @param ReflectionMethod $method Method object from
231 * reflection API
232 * @return array List of strings, each
233 * a snippet of code.
234 * @access private
236 function _getParameterSignatures($method) {
237 $signatures = array();
238 foreach ($method->getParameters() as $parameter) {
239 $type = $parameter->getClass();
240 $signatures[] =
241 (! is_null($type) ? $type->getName() . ' ' : '') .
242 ($parameter->isPassedByReference() ? '&' : '') .
243 '$' . $this->_suppressSpurious($parameter->getName()) .
244 ($this->_isOptional($parameter) ? ' = null' : '');
246 return $signatures;
250 * The SPL library has problems with the
251 * Reflection library. In particular, you can
252 * get extra characters in parameter names :(.
253 * @param string $name Parameter name.
254 * @return string Cleaner name.
255 * @access private
257 function _suppressSpurious($name) {
258 return str_replace(array('[', ']', ' '), '', $name);
262 * Test of a reflection parameter being optional
263 * that works with early versions of PHP5.
264 * @param reflectionParameter $parameter Is this optional.
265 * @return boolean True if optional.
266 * @access private
268 function _isOptional($parameter) {
269 if (method_exists($parameter, 'isOptional')) {
270 return $parameter->isOptional();
272 return false;