1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Reflection;
13:
14: use Nette,
15: Nette\ObjectMixin;
16:
17:
18:
19: 20: 21: 22: 23:
24: class ClassReflection extends \ReflectionClass
25: {
26:
27:
28: private static $extMethods;
29:
30:
31:
32: 33: 34: 35:
36: public static function from($class)
37: {
38: return new static($class);
39: }
40:
41:
42:
43: public function __toString()
44: {
45: return 'Class ' . $this->getName();
46: }
47:
48:
49:
50: 51: 52:
53: public function hasEventProperty($name)
54: {
55: if (preg_match('#^on[A-Z]#', $name) && $this->hasProperty($name)) {
56: $rp = $this->getProperty($name);
57: return $rp->isPublic() && !$rp->isStatic();
58: }
59: return FALSE;
60: }
61:
62:
63:
64: 65: 66: 67: 68: 69:
70: public function setExtensionMethod($name, $callback)
71: {
72: $l = & self::$extMethods[strtolower($name)];
73: $l[strtolower($this->getName())] = callback($callback);
74: $l[''] = NULL;
75: return $this;
76: }
77:
78:
79:
80: 81: 82: 83: 84:
85: public function getExtensionMethod($name)
86: {
87: $class = strtolower($this->getName());
88: $l = & self::$extMethods[strtolower($name)];
89:
90: if (empty($l)) {
91: return FALSE;
92:
93: } elseif (isset($l[''][$class])) {
94: return $l[''][$class];
95: }
96:
97: $cl = $class;
98: do {
99: if (isset($l[$cl])) {
100: return $l[''][$class] = $l[$cl];
101: }
102: } while (($cl = strtolower(get_parent_class($cl))) !== '');
103:
104: foreach (class_implements($class) as $cl) {
105: $cl = strtolower($cl);
106: if (isset($l[$cl])) {
107: return $l[''][$class] = $l[$cl];
108: }
109: }
110: return $l[''][$class] = FALSE;
111: }
112:
113:
114:
115:
116:
117:
118:
119: 120: 121:
122: public function getConstructor()
123: {
124: return ($ref = parent::getConstructor()) ? MethodReflection::from($this->getName(), $ref->getName()) : NULL;
125: }
126:
127:
128:
129: 130: 131:
132: public function getExtension()
133: {
134: return ($name = $this->getExtensionName()) ? new ExtensionReflection($name) : NULL;
135: }
136:
137:
138:
139: public function getInterfaces()
140: {
141: $res = array();
142: foreach (parent::getInterfaceNames() as $val) {
143: $res[$val] = new static($val);
144: }
145: return $res;
146: }
147:
148:
149:
150: 151: 152:
153: public function getMethod($name)
154: {
155: return new MethodReflection($this->getName(), $name);
156: }
157:
158:
159:
160: public function getMethods($filter = -1)
161: {
162: foreach ($res = parent::getMethods($filter) as $key => $val) {
163: $res[$key] = new MethodReflection($this->getName(), $val->getName());
164: }
165: return $res;
166: }
167:
168:
169:
170: 171: 172:
173: public function getParentClass()
174: {
175: return ($ref = parent::getParentClass()) ? new static($ref->getName()) : NULL;
176: }
177:
178:
179:
180: public function getProperties($filter = -1)
181: {
182: foreach ($res = parent::getProperties($filter) as $key => $val) {
183: $res[$key] = new PropertyReflection($this->getName(), $val->getName());
184: }
185: return $res;
186: }
187:
188:
189:
190: 191: 192:
193: public function getProperty($name)
194: {
195: return new PropertyReflection($this->getName(), $name);
196: }
197:
198:
199:
200:
201:
202:
203:
204: 205: 206: 207: 208:
209: public function hasAnnotation($name)
210: {
211: $res = AnnotationsParser::getAll($this);
212: return !empty($res[$name]);
213: }
214:
215:
216:
217: 218: 219: 220: 221:
222: public function getAnnotation($name)
223: {
224: $res = AnnotationsParser::getAll($this);
225: return isset($res[$name]) ? end($res[$name]) : NULL;
226: }
227:
228:
229:
230: 231: 232: 233:
234: public function getAnnotations()
235: {
236: return AnnotationsParser::getAll($this);
237: }
238:
239:
240:
241:
242:
243:
244:
245: 246: 247:
248: public static function getReflection()
249: {
250: return new Nette\Reflection\ClassReflection(get_called_class());
251: }
252:
253:
254:
255: public function __call($name, $args)
256: {
257: return ObjectMixin::call($this, $name, $args);
258: }
259:
260:
261:
262: public function &__get($name)
263: {
264: return ObjectMixin::get($this, $name);
265: }
266:
267:
268:
269: public function __set($name, $value)
270: {
271: return ObjectMixin::set($this, $name, $value);
272: }
273:
274:
275:
276: public function __isset($name)
277: {
278: return ObjectMixin::has($this, $name);
279: }
280:
281:
282:
283: public function __unset($name)
284: {
285: throw new \MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");
286: }
287:
288: }
289: