1 <?php
2
3 namespace PayPal\Common;
4
5 use PayPal\Exception\PayPalConfigurationException;
6
7 8 9 10 11
12 class ReflectionUtil
13 {
14
15 16 17 18 19
20 private static $propertiesRefl = array();
21
22 23 24 25 26
27 private static $propertiesType = array();
28
29
30 31 32 33 34 35 36 37 38 39
40 public static function getPropertyClass($class, $propertyName)
41 {
42 if ($class == get_class(new PayPalModel())) {
43
44 return get_class(new PayPalModel());
45 }
46
47
48 if (!class_exists($class) || !method_exists($class, self::getter($class, $propertyName))) {
49 return null;
50 }
51
52 if (($annotations = self::propertyAnnotations($class, $propertyName)) && isset($annotations['return'])) {
53 $param = $annotations['return'];
54 }
55
56 if (isset($param)) {
57 $anno = preg_split("/[\s\[\]]+/", $param);
58 return $anno[0];
59 } else {
60 throw new PayPalConfigurationException("Getter function for '$propertyName' in '$class' class should have a proper return type.");
61 }
62 }
63
64 65 66 67 68 69 70 71
72 public static function isPropertyClassArray($class, $propertyName)
73 {
74
75 if (!class_exists($class) || !method_exists($class, self::getter($class, $propertyName))) {
76 return null;
77 }
78
79 if (($annotations = self::propertyAnnotations($class, $propertyName)) && isset($annotations['return'])) {
80 $param = $annotations['return'];
81 }
82
83 if (isset($param)) {
84 return substr($param, -strlen('[]'))==='[]';
85 } else {
86 throw new PayPalConfigurationException("Getter function for '$propertyName' in '$class' class should have a proper return type.");
87 }
88 }
89
90 91 92 93 94 95 96 97
98 public static function propertyAnnotations($class, $propertyName)
99 {
100 $class = is_object($class) ? get_class($class) : $class;
101 if (!class_exists('ReflectionProperty')) {
102 throw new \RuntimeException("Property type of " . $class . "::{$propertyName} cannot be resolved");
103 }
104
105 if ($annotations =& self::$propertiesType[$class][$propertyName]) {
106 return $annotations;
107 }
108
109 if (!($refl =& self::$propertiesRefl[$class][$propertyName])) {
110 $getter = self::getter($class, $propertyName);
111 $refl = new \ReflectionMethod($class, $getter);
112 self::$propertiesRefl[$class][$propertyName] = $refl;
113 }
114
115
116 if (!preg_match_all(
117 '~\@([^\s@\(]+)[\t ]*(?:\(?([^\n@]+)\)?)?~i',
118 $refl->getDocComment(),
119 $annots,
120 PREG_PATTERN_ORDER)) {
121 return null;
122 }
123 foreach ($annots[1] as $i => $annot) {
124 $annotations[strtolower($annot)] = empty($annots[2][$i]) ? true : rtrim($annots[2][$i], " \t\n\r)");
125 }
126
127 return $annotations;
128 }
129
130 131 132 133 134 135
136 private static function replace_callback($match)
137 {
138 return ucwords($match[2]);
139 }
140
141 142 143 144 145 146 147 148
149 public static function getter($class, $propertyName)
150 {
151 return method_exists($class, "get" . ucfirst($propertyName)) ?
152 "get" . ucfirst($propertyName) :
153 "get" . preg_replace_callback("/([_\-\s]?([a-z0-9]+))/", "self::replace_callback", $propertyName);
154 }
155 }
156