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\Php;
17:
18: use TokenReflection;
19: use TokenReflection\Broker, TokenReflection\Exception;
20: use Reflector, ReflectionProperty as InternalReflectionProperty;
21:
22: /**
23: * Reflection of a not tokenized but defined class property.
24: *
25: * Descendant of the internal reflection with additional features.
26: */
27: class ReflectionProperty extends InternalReflectionProperty implements IReflection, TokenReflection\IReflectionProperty
28: {
29: /**
30: * Reflection broker.
31: *
32: * @var \TokenReflection\Broker
33: */
34: private $broker;
35:
36: /**
37: * Is the property accessible despite its access level.
38: *
39: * @var boolean
40: */
41: private $accessible = false;
42:
43: /**
44: * Constructor.
45: *
46: * @param string|\TokenReflection\Php\ReflectionClass|\ReflectionClass $class Defining class
47: * @param string $propertyName Property name
48: * @param \TokenReflection\Broker $broker Reflection broker
49: */
50: public function __construct($class, $propertyName, Broker $broker)
51: {
52: parent::__construct($class, $propertyName);
53: $this->broker = $broker;
54: }
55:
56: /**
57: * Returns the declaring class reflection.
58: *
59: * @return \TokenReflection\IReflectionClass
60: */
61: public function getDeclaringClass()
62: {
63: return ReflectionClass::create(parent::getDeclaringClass(), $this->broker);
64: }
65:
66: /**
67: * Returns the declaring class name.
68: *
69: * @return string
70: */
71: public function getDeclaringClassName()
72: {
73: return $this->getDeclaringClass()->getName();
74: }
75:
76: /**
77: * Returns the definition start line number in the file.
78: *
79: * @return null
80: */
81: public function getStartLine()
82: {
83: return null;
84: }
85:
86: /**
87: * Returns the definition end line number in the file.
88: *
89: * @return null
90: */
91: public function getEndLine()
92: {
93: return null;
94: }
95:
96: /**
97: * Returns the appropriate docblock definition.
98: *
99: * @return boolean
100: */
101: public function getDocComment()
102: {
103: return false;
104: }
105:
106: /**
107: * Checks if there is a particular annotation.
108: *
109: * @param string $name Annotation name
110: * @return boolean
111: */
112: public function hasAnnotation($name)
113: {
114: return false;
115: }
116:
117: /**
118: * Returns a particular annotation value.
119: *
120: * @param string $name Annotation name
121: * @return null
122: */
123: public function getAnnotation($name)
124: {
125: return null;
126: }
127:
128: /**
129: * Returns parsed docblock.
130: *
131: * @return array
132: */
133: public function getAnnotations()
134: {
135: return array();
136: }
137:
138: /**
139: * Returns the property default value.
140: *
141: * @return mixed
142: */
143: public function getDefaultValue()
144: {
145: $values = $this->getDeclaringClass()->getDefaultProperties();
146: return $values[$this->getName()];
147: }
148:
149: /**
150: * Returns the part of the source code defining the property default value.
151: *
152: * @return string
153: */
154: public function getDefaultValueDefinition()
155: {
156: $value = $this->getDefaultValue();
157: return null === $value ? null : var_export($value, true);
158: }
159:
160: /**
161: * Returns if the property is internal.
162: *
163: * @return boolean
164: */
165: public function isInternal()
166: {
167: return $this->getDeclaringClass()->isInternal();
168: }
169:
170: /**
171: * Returns if the property is user defined.
172: *
173: * @return boolean
174: */
175: public function isUserDefined()
176: {
177: return $this->getDeclaringClass()->isUserDefined();
178: }
179:
180: /**
181: * Returns if the current reflection comes from a tokenized source.
182: *
183: * @return boolean
184: */
185: public function isTokenized()
186: {
187: return false;
188: }
189:
190: /**
191: * Returns if the reflection subject is deprecated.
192: *
193: * @return boolean
194: */
195: public function isDeprecated()
196: {
197: return false;
198: }
199:
200: /**
201: * Returns the reflection broker used by this reflection object.
202: *
203: * @return \TokenReflection\Broker
204: */
205: public function getBroker()
206: {
207: return $this->broker;
208: }
209:
210: /**
211: * Returns imported namespaces and aliases from the declaring namespace.
212: *
213: * @return array
214: */
215: public function getNamespaceAliases()
216: {
217: return array();
218: }
219:
220: /**
221: * Returns the defining trait.
222: *
223: * @return \TokenReflection\IReflectionClass|null
224: */
225: public function getDeclaringTrait()
226: {
227: return null;
228: }
229:
230: /**
231: * Returns the declaring trait name.
232: *
233: * @return string|null
234: */
235: public function getDeclaringTraitName()
236: {
237: return null;
238: }
239:
240: /**
241: * Returns if the property is set accessible.
242: *
243: * @return boolean
244: */
245: public function isAccessible()
246: {
247: return $this->accessible;
248: }
249:
250: /**
251: * Sets a property to be accessible or not.
252: *
253: * @param boolean $accessible If the property should be accessible.
254: */
255: public function setAccessible($accessible)
256: {
257: $this->accessible = (bool) $accessible;
258:
259: parent::setAccessible($accessible);
260: }
261:
262: /**
263: * Returns the PHP extension reflection.
264: *
265: * @return \TokenReflection\Php\ReflectionExtension
266: */
267: public function getExtension()
268: {
269: return $this->getDeclaringClass()->getExtension();
270: }
271:
272: /**
273: * Returns the PHP extension name.
274: *
275: * @return string|boolean
276: */
277: public function getExtensionName()
278: {
279: $extension = $this->getExtension();
280: return $extension ? $extension->getName() : false;
281: }
282:
283: /**
284: * Returns the file name the reflection object is defined in.
285: *
286: * @return string
287: */
288: public function getFileName()
289: {
290: return $this->getDeclaringClass()->getFileName();
291: }
292:
293: /**
294: * Returns an element pretty (docblock compatible) name.
295: *
296: * @return string
297: */
298: public function getPrettyName()
299: {
300: return sprintf('%s::$%s', $this->getDeclaringClassName(), $this->getName());
301: }
302:
303: /**
304: * Magic __get method.
305: *
306: * @param string $key Variable name
307: * @return mixed
308: */
309: final public function __get($key)
310: {
311: return TokenReflection\ReflectionElement::get($this, $key);
312: }
313:
314: /**
315: * Magic __isset method.
316: *
317: * @param string $key Variable name
318: * @return boolean
319: */
320: final public function __isset($key)
321: {
322: return TokenReflection\ReflectionElement::exists($this, $key);
323: }
324:
325: /**
326: * Creates a reflection instance.
327: *
328: * @param \ReflectionClass $internalReflection Internal reflection instance
329: * @param \TokenReflection\Broker $broker Reflection broker instance
330: * @return \TokenReflection\Php\ReflectionProperty
331: * @throws \TokenReflection\Exception\RuntimeException If an invalid internal reflection object was provided.
332: */
333: public static function create(Reflector $internalReflection, Broker $broker)
334: {
335: static $cache = array();
336:
337: if (!$internalReflection instanceof InternalReflectionProperty) {
338: throw new Exception\RuntimeException('Invalid reflection instance provided, ReflectionProperty expected.', Exception\RuntimeException::INVALID_ARGUMENT);
339: }
340:
341: $key = $internalReflection->getDeclaringClass()->getName() . '::' . $internalReflection->getName();
342: if (!isset($cache[$key])) {
343: $cache[$key] = new self($internalReflection->getDeclaringClass()->getName(), $internalReflection->getName(), $broker);
344: }
345:
346: return $cache[$key];
347: }
348: }
349: