1: <?php
2: /**
3: * PHP Token Reflection
4: *
5: * Version 1.3.1
6: *
7: * LICENSE
8: *
9: * This source file is subject to the new BSD license that is bundled
10: * with this library in the file LICENSE.
11: *
12: * @author Ondřej Nešpor
13: * @author Jaroslav Hanslík
14: */
15:
16: namespace TokenReflection\Dummy;
17:
18: use TokenReflection;
19: use TokenReflection\Broker, TokenReflection\IReflectionClass, TokenReflection\ReflectionBase;
20: use ReflectionClass as InternalReflectionClass, TokenReflection\Exception;
21:
22: /**
23: * Dummy class "reflection" of a nonexistent class.
24: */
25: class ReflectionClass implements IReflectionClass
26: {
27: /**
28: * Reflection broker.
29: *
30: * @var \TokenReflection\Broker
31: */
32: private $broker;
33:
34: /**
35: * Class name (FQN).
36: *
37: * @var string
38: */
39: private $name;
40:
41: /**
42: * Constructor.
43: *
44: * @param string $className Class name
45: * @param \TokenReflection\Broker $broker Reflection broker
46: */
47: public function __construct($className, Broker $broker)
48: {
49: $this->name = ltrim($className, '\\');
50: $this->broker = $broker;
51: }
52:
53: /**
54: * Returns the name (FQN).
55: *
56: * @return string
57: */
58: public function getName()
59: {
60: return $this->name;
61: }
62:
63: /**
64: * Returns an element pretty (docblock compatible) name.
65: *
66: * @return string
67: */
68: public function getPrettyName()
69: {
70: return $this->name;
71: }
72:
73: /**
74: * Returns the unqualified name (UQN).
75: *
76: * @return string
77: */
78: public function getShortName()
79: {
80: $pos = strrpos($this->name, '\\');
81: return false === $pos ? $this->name : substr($this->name, $pos + 1);
82: }
83:
84: /**
85: * Returns the namespace name.
86: *
87: * @return string
88: */
89: public function getNamespaceName()
90: {
91: $pos = strrpos($this->name, '\\');
92: return false === $pos ? '' : substr($this->name, 0, $pos);
93: }
94:
95: /**
96: * Returns if the class is defined within a namespace.
97: *
98: * @return boolean
99: */
100: public function inNamespace()
101: {
102: return false !== strrpos($this->name, '\\');
103: }
104:
105: /**
106: * Returns imported namespaces and aliases from the declaring namespace.
107: *
108: * @return array
109: */
110: public function getNamespaceAliases()
111: {
112: return array();
113: }
114:
115: /**
116: * Returns the PHP extension reflection.
117: *
118: * @return null
119: */
120: public function getExtension()
121: {
122: return null;
123: }
124:
125: /**
126: * Returns the PHP extension name.
127: *
128: * @return boolean
129: */
130: public function getExtensionName()
131: {
132: return false;
133: }
134:
135: /**
136: * Returns the file name the reflection object is defined in.
137: *
138: * @return null
139: */
140: public function getFileName()
141: {
142: return null;
143: }
144:
145: /**
146: * Returns a file reflection.
147: *
148: * @return \TokenReflection\ReflectionFile
149: * @throws \TokenReflection\Exception\RuntimeException If the file is not stored inside the broker
150: */
151: public function getFileReflection()
152: {
153: throw new Exception\BrokerException($this->getBroker(), sprintf('Class was not parsed from a file', $this->getName()), Exception\BrokerException::UNSUPPORTED);
154: }
155:
156: /**
157: * Returns the definition start line number in the file.
158: *
159: * @return null
160: */
161: public function getStartLine()
162: {
163: return null;
164: }
165:
166: /**
167: * Returns the definition end line number in the file.
168: *
169: * @return null
170: */
171: public function getEndLine()
172: {
173: return null;
174: }
175:
176: /**
177: * Returns the appropriate docblock definition.
178: *
179: * @return boolean
180: */
181: public function getDocComment()
182: {
183: return false;
184: }
185:
186: /**
187: * Checks if there is a particular annotation.
188: *
189: * @param string $name Annotation name
190: * @return boolean
191: */
192: public function hasAnnotation($name)
193: {
194: return false;
195: }
196:
197: /**
198: * Returns a particular annotation value.
199: *
200: * @param string $name Annotation name
201: * @return null
202: */
203: public function getAnnotation($name)
204: {
205: return null;
206: }
207:
208: /**
209: * Returns parsed docblock.
210: *
211: * @return array
212: */
213: public function getAnnotations()
214: {
215: return array();
216: }
217:
218: /**
219: * Returns modifiers.
220: *
221: * @return integer
222: */
223: public function getModifiers()
224: {
225: return 0;
226: }
227:
228: /**
229: * Returns if the class is abstract.
230: *
231: * @return boolean
232: */
233: public function isAbstract()
234: {
235: return false;
236: }
237:
238: /**
239: * Returns if the class is final.
240: *
241: * @return boolean
242: */
243: public function isFinal()
244: {
245: return false;
246: }
247:
248: /**
249: * Returns if the class is an interface.
250: *
251: * @return boolean
252: */
253: public function isInterface()
254: {
255: return false;
256: }
257:
258: /**
259: * Returns if the class is an exception or its descendant.
260: *
261: * @return boolean
262: */
263: public function isException()
264: {
265: return false;
266: }
267:
268: /**
269: * Returns if it is possible to create an instance of this class.
270: *
271: * @return boolean
272: */
273: public function isInstantiable()
274: {
275: return false;
276: }
277:
278: /**
279: * Returns traits used by this class.
280: *
281: * @return array
282: */
283: public function getTraits()
284: {
285: return array();
286: }
287:
288: /**
289: * Returns traits used by this class and not its parents.
290: *
291: * @return array
292: */
293: public function getOwnTraits()
294: {
295: return array();
296: }
297:
298: /**
299: * Returns names of used traits.
300: *
301: * @return array
302: */
303: public function getTraitNames()
304: {
305: return array();
306: }
307:
308: /**
309: * Returns traits used by this class and not its parents.
310: *
311: * @return array
312: */
313: public function getOwnTraitNames()
314: {
315: return array();
316: }
317:
318: /**
319: * Returns method aliases from traits.
320: *
321: * @return array
322: */
323: public function getTraitAliases()
324: {
325: return array();
326: }
327:
328: /**
329: * Returns if the class is a trait.
330: *
331: * @return boolean
332: */
333: public function isTrait()
334: {
335: return false;
336: }
337:
338: /**
339: * Returns if the class uses a particular trait.
340: *
341: * @param \ReflectionClass|\TokenReflection\IReflectionClass|string $trait Trait reflection or name
342: * @return boolean
343: */
344: public function usesTrait($trait)
345: {
346: return false;
347: }
348:
349: /**
350: * Returns if objects of this class are cloneable.
351: *
352: * Introduced in PHP 5.4.
353: *
354: * @return boolean
355: * @see http://svn.php.net/viewvc/php/php-src/trunk/ext/reflection/php_reflection.c?revision=307971&view=markup#l4059
356: */
357: public function isCloneable()
358: {
359: return false;
360: }
361:
362: /**
363: * Returns if the class is iterateable.
364: *
365: * Returns true if the class implements the Traversable interface.
366: *
367: * @return boolean
368: */
369: public function isIterateable()
370: {
371: return false;
372: }
373:
374: /**
375: * Returns if the reflection object is internal.
376: *
377: * @return boolean
378: */
379: public function isInternal()
380: {
381: return false;
382: }
383:
384: /**
385: * Returns if the reflection object is user defined.
386: *
387: * @return boolean
388: */
389: public function isUserDefined()
390: {
391: return false;
392: }
393:
394: /**
395: * Returns if the current reflection comes from a tokenized source.
396: *
397: * @return boolean
398: */
399: public function isTokenized()
400: {
401: return false;
402: }
403:
404: /**
405: * Returns if the current class is a subclass of the given class.
406: *
407: * @param string|object $class Class name or reflection object
408: * @return boolean
409: */
410: public function isSubclassOf($class)
411: {
412: return false;
413: }
414:
415: /**
416: * Returns the parent class reflection.
417: *
418: * @return null
419: */
420: public function getParentClass()
421: {
422: return false;
423: }
424:
425: /**
426: * Returns the parent classes reflections.
427: *
428: * @return array
429: */
430: public function getParentClasses()
431: {
432: return array();
433: }
434:
435: /**
436: * Returns the parent classes names.
437: *
438: * @return array
439: */
440: public function getParentClassNameList()
441: {
442: return array();
443: }
444:
445: /**
446: * Returns the parent class reflection.
447: *
448: * @return null
449: */
450: public function getParentClassName()
451: {
452: return null;
453: }
454:
455: /**
456: * Returns if the class implements the given interface.
457: *
458: * @param string|object $interface Interface name or reflection object
459: * @return boolean
460: * @throws \TokenReflection\Exception\RuntimeException If the provided parameter is not an interface.
461: */
462: public function implementsInterface($interface)
463: {
464: if (is_object($interface)) {
465: if (!$interface instanceof IReflectionClass) {
466: throw new Exception\RuntimeException(sprintf('Parameter must be a string or an instance of class reflection, "%s" provided.', get_class($interface)), Exception\RuntimeException::INVALID_ARGUMENT, $this);
467: }
468:
469: $interfaceName = $interface->getName();
470:
471: if (!$interface->isInterface()) {
472: throw new Exception\RuntimeException(sprintf('"%s" is not an interface.', $interfaceName), Exception\RuntimeException::INVALID_ARGUMENT, $this);
473: }
474: }
475:
476: // Only validation, always returns false
477: return false;
478: }
479:
480: /**
481: * Returns interface reflections.
482: *
483: * @return array
484: */
485: public function getInterfaces()
486: {
487: return array();
488: }
489:
490: /**
491: * Returns interface names.
492: *
493: * @return array
494: */
495: public function getInterfaceNames()
496: {
497: return array();
498: }
499:
500: /**
501: * Returns interfaces implemented by this class, not its parents.
502: *
503: * @return array
504: */
505: public function getOwnInterfaces()
506: {
507: return array();
508: }
509:
510: /**
511: * Returns names of interfaces implemented by this class, not its parents.
512: *
513: * @return array
514: */
515: public function getOwnInterfaceNames()
516: {
517: return array();
518: }
519:
520: /**
521: * Returns the class constructor reflection.
522: *
523: * @return null
524: */
525: public function getConstructor()
526: {
527: return null;
528: }
529:
530: /**
531: * Returns the class desctructor reflection.
532: *
533: * @return null
534: */
535: public function getDestructor()
536: {
537: return null;
538: }
539:
540: /**
541: * Returns if the class implements the given method.
542: *
543: * @param string $name Method name
544: * @return boolean
545: */
546: public function hasMethod($name)
547: {
548: return false;
549: }
550:
551: /**
552: * Returns a method reflection.
553: *
554: * @param string $name Method name
555: * @throws \TokenReflection\Exception\RuntimeException If the requested method does not exist.
556: */
557: public function getMethod($name)
558: {
559: throw new Exception\RuntimeException(sprintf('There is no method "%s".', $name), Exception\RuntimeException::DOES_NOT_EXIST, $this);
560: }
561:
562: /**
563: * Returns method reflections.
564: *
565: * @param integer $filter Methods filter
566: * @return array
567: */
568: public function getMethods($filter = null)
569: {
570: return array();
571: }
572:
573: /**
574: * Returns if the class implements (and not its parents) the given method.
575: *
576: * @param string $name Method name
577: * @return boolean
578: */
579: public function hasOwnMethod($name)
580: {
581: return false;
582: }
583:
584: /**
585: * Returns methods declared by this class, not its parents.
586: *
587: * @param integer $filter Methods filter
588: * @return array
589: */
590: public function getOwnMethods($filter = null)
591: {
592: return array();
593: }
594:
595: /**
596: * Returns if the class imports the given method from traits.
597: *
598: * @param string $name Method name
599: * @return boolean
600: */
601: public function hasTraitMethod($name)
602: {
603: return false;
604: }
605:
606: /**
607: * Returns method reflections imported from traits.
608: *
609: * @param integer $filter Methods filter
610: * @return array
611: */
612: public function getTraitMethods($filter = null)
613: {
614: return array();
615: }
616:
617: /**
618: * Returns if the class defines the given constant.
619: *
620: * @param string $name Constant name.
621: * @return boolean
622: */
623: public function hasConstant($name)
624: {
625: return false;
626: }
627:
628: /**
629: * Returns a constant value.
630: *
631: * @param string $name Constant name
632: * @throws \TokenReflection\Exception\RuntimeException If the requested constant does not exist.
633: */
634: public function getConstant($name)
635: {
636: throw new Exception\RuntimeException(sprintf('There is no constant "%s".', $name), Exception\RuntimeException::DOES_NOT_EXIST, $this);
637: }
638:
639: /**
640: * Returns a constant reflection.
641: *
642: * @param string $name Constant name
643: * @throws \TokenReflection\Exception\RuntimeException If the requested constant does not exist.
644: */
645: public function getConstantReflection($name)
646: {
647: throw new Exception\RuntimeException(sprintf('There is no constant "%s".', $name), Exception\RuntimeException::DOES_NOT_EXIST, $this);
648: }
649:
650: /**
651: * Returns an array of constant values.
652: *
653: * @return array
654: */
655: public function getConstants()
656: {
657: return array();
658: }
659:
660: /**
661: * Returns an array of constant reflections.
662: *
663: * @return array
664: */
665: public function getConstantReflections()
666: {
667: return array();
668: }
669:
670: /**
671: * Returns if the class (and not its parents) defines the given constant.
672: *
673: * @param string $name Constant name.
674: * @return boolean
675: */
676: public function hasOwnConstant($name)
677: {
678: return false;
679: }
680:
681: /**
682: * Returns constants declared by this class, not its parents.
683: *
684: * @return array
685: */
686: public function getOwnConstants()
687: {
688: return array();
689: }
690:
691: /**
692: * Returns an array of constant reflections defined by this class not its parents.
693: *
694: * @return array
695: */
696: public function getOwnConstantReflections()
697: {
698: return array();
699: }
700:
701: /**
702: * Returns default properties.
703: *
704: * @return array
705: */
706: public function getDefaultProperties()
707: {
708: return array();
709: }
710:
711: /**
712: * Returns if the class implements the given property.
713: *
714: * @param string $name Property name
715: * @return boolean
716: */
717: public function hasProperty($name)
718: {
719: return false;
720: }
721:
722: /**
723: * Returns class properties.
724: *
725: * @param integer $filter Property types
726: * @return array
727: */
728: public function getProperties($filter = null)
729: {
730: return array();
731: }
732:
733: /**
734: * Return a property reflections.
735: *
736: * @param string $name Property name
737: * @throws \TokenReflection\Exception\RuntimeException If the requested property does not exist.
738: */
739: public function getProperty($name)
740: {
741: throw new Exception\RuntimeException(sprintf('There is no property "%s".', $name), Exception\RuntimeException::DOES_NOT_EXIST, $this);
742: }
743:
744: /**
745: * Returns if the class (and not its parents) implements the given property.
746: *
747: * @param string $name Property name
748: * @return boolean
749: */
750: public function hasOwnProperty($name)
751: {
752: return false;
753: }
754:
755: /**
756: * Returns properties declared by this class, not its parents.
757: *
758: * @param integer $filter Properties filter
759: * @return array
760: */
761: public function getOwnProperties($filter = null)
762: {
763: return array();
764: }
765:
766: /**
767: * Returns if the class imports the given property from traits.
768: *
769: * @param string $name Property name
770: * @return boolean
771: */
772: public function hasTraitProperty($name)
773: {
774: return false;
775: }
776:
777: /**
778: * Returns property reflections imported from traits.
779: *
780: * @param integer $filter Properties filter
781: * @return array
782: */
783: public function getTraitProperties($filter = null)
784: {
785: return array();
786: }
787:
788: /**
789: * Returns static properties reflections.
790: *
791: * @return array
792: */
793: public function getStaticProperties()
794: {
795: return array();
796: }
797:
798: /**
799: * Returns a value of a static property.
800: *
801: * @param string $name Property name
802: * @param mixed $default Default value
803: * @throws \TokenReflection\Exception\RuntimeException If the requested static property does not exist.
804: */
805: public function getStaticPropertyValue($name, $default = null)
806: {
807: throw new Exception\RuntimeException(sprintf('There is no static property "%s".', $name), Exception\RuntimeException::DOES_NOT_EXIST, $this);
808: }
809:
810: /**
811: * Returns reflections of direct subclasses.
812: *
813: * @return array
814: */
815: public function getDirectSubclasses()
816: {
817: return array();
818: }
819:
820: /**
821: * Returns names of direct subclasses.
822: *
823: * @return array
824: */
825: public function getDirectSubclassNames()
826: {
827: return array();
828: }
829:
830: /**
831: * Returns reflections of indirect subclasses.
832: *
833: * @return array
834: */
835: public function getIndirectSubclasses()
836: {
837: return array();
838: }
839:
840: /**
841: * Returns names of indirect subclasses.
842: *
843: * @return array
844: */
845: public function getIndirectSubclassNames()
846: {
847: return array();
848: }
849:
850: /**
851: * Returns reflections of classes directly implementing this interface.
852: *
853: * @return array
854: */
855: public function getDirectImplementers()
856: {
857: return array();
858: }
859:
860: /**
861: * Returns names of classes directly implementing this interface.
862: *
863: * @return array
864: */
865: public function getDirectImplementerNames()
866: {
867: return array();
868: }
869:
870: /**
871: * Returns reflections of classes indirectly implementing this interface.
872: *
873: * @return array
874: */
875: public function getIndirectImplementers()
876: {
877: return array();
878: }
879:
880: /**
881: * Returns names of classes indirectly implementing this interface.
882: *
883: * @return array
884: */
885: public function getIndirectImplementerNames()
886: {
887: return array();
888: }
889:
890: /**
891: * Returns if the given object is an instance of this class.
892: *
893: * @param object $object Instance
894: * @return boolean
895: * @throws \TokenReflection\Exception\RuntimeException If the provided argument is not an object.
896: */
897: public function isInstance($object)
898: {
899: if (!is_object($object)) {
900: throw new Exception\RuntimeException(sprintf('Parameter must be a class instance, "%s" provided.', gettype($object)), Exception\RuntimeException::INVALID_ARGUMENT, $this);
901: }
902:
903: return $this->name === get_class($object) || is_subclass_of($object, $this->name);
904: }
905:
906: /**
907: * Creates a new class instance without using a constructor.
908: *
909: * @return object
910: * @throws \TokenReflection\Exception\RuntimeException If the class inherits from an internal class.
911: */
912: public function newInstanceWithoutConstructor()
913: {
914: if (!class_exists($this->name, true)) {
915: throw new Exception\RuntimeException('Could not create an instance; class does not exist.', Exception\RuntimeException::DOES_NOT_EXIST, $this);
916: }
917:
918: $reflection = new \TokenReflection\Php\ReflectionClass($this->name, $this->getBroker());
919: return $reflection->newInstanceWithoutConstructor();
920: }
921:
922: /**
923: * Creates a new instance using variable number of parameters.
924: *
925: * Use any number of constructor parameters as function parameters.
926: *
927: * @param mixed $args
928: * @return object
929: */
930: public function newInstance($args)
931: {
932: return $this->newInstanceArgs(func_get_args());
933: }
934:
935: /**
936: * Creates a new instance using an array of parameters.
937: *
938: * @param array $args Array of constructor parameters
939: * @return object
940: * @throws \TokenReflection\Exception\RuntimeException If the required class does not exist.
941: */
942: public function newInstanceArgs(array $args = array())
943: {
944: if (!class_exists($this->name, true)) {
945: throw new Exception\RuntimeException('Could not create an instance of class; class does not exist.', Exception\RuntimeException::DOES_NOT_EXIST, $this);
946: }
947:
948: $reflection = new InternalReflectionClass($this->name);
949: return $reflection->newInstanceArgs($args);
950: }
951:
952: /**
953: * Sets a static property value.
954: *
955: * @param string $name Property name
956: * @param mixed $value Property value
957: * @throws \TokenReflection\Exception\RuntimeException If the requested static property does not exist.
958: */
959: public function setStaticPropertyValue($name, $value)
960: {
961: throw new Exception\RuntimeException(sprintf('There is no static property "%s".', $name), Exception\RuntimeException::DOES_NOT_EXIST, $this);
962: }
963:
964: /**
965: * Returns the string representation of the reflection object.
966: *
967: * @return string
968: */
969: public function __toString()
970: {
971: return sprintf(
972: "Class|Interface [ <user> class|interface %s ] {\n %s%s%s%s%s\n}\n",
973: $this->getName(),
974: "\n\n - Constants [0] {\n }",
975: "\n\n - Static properties [0] {\n }",
976: "\n\n - Static methods [0] {\n }",
977: "\n\n - Properties [0] {\n }",
978: "\n\n - Methods [0] {\n }"
979: );
980: }
981:
982: /**
983: * Exports a reflected object.
984: *
985: * @param \TokenReflection\Broker $broker Broker instance
986: * @param string|object $className Class name or class instance
987: * @param boolean $return Return the export instead of outputting it
988: * @return string|null
989: * @throws \TokenReflection\Exception\RuntimeException If requested parameter doesn't exist.
990: */
991: public static function export(Broker $broker, $className, $return = false)
992: {
993: TokenReflection\ReflectionClass::export($broker, $className, $return);
994: }
995:
996: /**
997: * Outputs the reflection subject source code.
998: *
999: * @return string
1000: */
1001: public function getSource()
1002: {
1003: return '';
1004: }
1005:
1006: /**
1007: * Returns the start position in the file token stream.
1008: *
1009: * @return integer
1010: */
1011: public function getStartPosition()
1012: {
1013: return -1;
1014: }
1015:
1016: /**
1017: * Returns the end position in the file token stream.
1018: *
1019: * @return integer
1020: */
1021: public function getEndPosition()
1022: {
1023: return -1;
1024: }
1025:
1026: /**
1027: * Returns if the class definition is complete.
1028: *
1029: * Dummy classes never have the definition complete.
1030: *
1031: * @return boolean
1032: */
1033: public function isComplete()
1034: {
1035: return false;
1036: }
1037:
1038: /**
1039: * Returns if the class definition is valid.
1040: *
1041: * Dummy classes are always valid.
1042: *
1043: * @return boolean
1044: */
1045: public function isValid()
1046: {
1047: return true;
1048: }
1049:
1050: /**
1051: * Returns if the reflection subject is deprecated.
1052: *
1053: * @return boolean
1054: */
1055: public function isDeprecated()
1056: {
1057: return false;
1058: }
1059:
1060: /**
1061: * Returns the reflection broker used by this reflection object.
1062: *
1063: * @return \TokenReflection\Broker
1064: */
1065: public function getBroker()
1066: {
1067: return $this->broker;
1068: }
1069:
1070: /**
1071: * Magic __get method.
1072: *
1073: * @param string $key Variable name
1074: * @return mixed
1075: */
1076: final public function __get($key)
1077: {
1078: return ReflectionBase::get($this, $key);
1079: }
1080:
1081: /**
1082: * Magic __isset method.
1083: *
1084: * @param string $key Variable name
1085: * @return boolean
1086: */
1087: final public function __isset($key)
1088: {
1089: return ReflectionBase::exists($this, $key);
1090: }
1091: }
1092: