blob: 6328908081236ac419a1deb7f1152515450dfbcf [file] [log] [blame]
<?php
/**
* File containing the ezcReflectionProperty class.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @package Reflection
* @version //autogen//
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
/**
* Extends the ReflectionProperty class to provide type information
* using PHPDoc annotations.
*
* @package Reflection
* @version //autogen//
* @author Stefan Marr <mail@stefan-marr.de>
*/
class ezcReflectionProperty extends ReflectionProperty
{
/**
* @var ezcReflectionDocCommentParser Parser for source code annotations
*/
protected $docParser;
/**
* @var ReflectionProperty
* Name, instance of the property's class
* or ReflectionProperty object of the property
*/
protected $reflectionSource;
/**
* Constructs a new ezcReflectionProperty object
*
* Throws an Exception in case the given property does not exist
* @param string|object|ReflectionProperty $class
* Name, instance of the property's class
* or ReflectionProperty object of the property
* @param string $name
* Name of the property to be reflected.
* Can be null or will be ignored if a ReflectionProperty object is
* given as first parameter.
*/
public function __construct( $class, $name = null )
{
if ( !$class instanceof ReflectionProperty )
{
parent::__construct( $class, $name );
}
$this->reflectionSource = $class;
$this->docParser = ezcReflection::getDocCommentParser();
$this->docParser->parse( $this->getDocComment() );
}
/**
* Use overloading to call additional methods
* of the ReflectionProperty instance given to the constructor.
*
* @param string $method Method to be called
* @param array $arguments Arguments that were passed
* @return mixed
*/
public function __call( $method, $arguments )
{
$callback = array( $this->reflectionSource, $method );
if ( $this->reflectionSource instanceof parent
and is_callable( $callback ) )
{
// query external reflection object
return call_user_func_array( $callback, $arguments );
}
else
{
throw new ezcReflectionCallToUndefinedMethodException( __CLASS__, $method );
}
}
/**
* Forwards a method invocation to either the reflection source passed to
* the constructor of this class when creating an instance or to the parent
* class.
*
* This method is part of the dependency injection mechanism and serves as
* a helper for implementing wrapper methods without code duplication.
* @param string $method Name of the method to be invoked
* @param mixed[] $arguments Arguments to be passed to the method
* @return mixed Return value of the invoked method
*/
protected function forwardCallToReflectionSource( $method, $arguments = array() ) {
if ( $this->reflectionSource instanceof parent ) {
return call_user_func_array( array( $this->reflectionSource, $method ), $arguments );
} else {
//*
return call_user_func_array( array( $this, 'parent::' . $method ), $arguments );
/*/
$argumentStrings = array();
foreach ( array_keys( $arguments ) as $key ) {
$argumentStrings[] = '$arguments[' . var_export( $key, true ) . ']';
}
$cmd = 'return parent::$method( ' . implode( ', ', $argumentStrings ) . ' );';
return eval( $cmd );
//*/
}
}
/**
* Determines the type of the property based on source code annotations.
*
* @return ezcReflectionType Type of the property
* @since PHP 5.1.0
*/
public function getType()
{
$vars = $this->docParser->getVarAnnotations();
if ( isset( $vars[0] ) )
{
return ezcReflection::getTypeByName( $vars[0]->getTypeName() );
}
else
{
return null;
}
}
/**
* Returns the declaring class.
*
* @return ezcReflectionClass
*/
public function getDeclaringClass()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
return new ezcReflectionClass( $this->reflectionSource->getDeclaringClass() );
}
else
{
$class = parent::getDeclaringClass();
return new ezcReflectionClass( $class->getName() );
}
}
/**
* Checks whether the property is annotated with the annotation $annotation
*
* @param string $annotation Name of the annotation
* @return boolean
* @since PHP 5.1.0
*/
public function hasAnnotation($annotation) {
return $this->docParser->hasAnnotation($annotation);
}
/**
* Returns an array of annotations (optinally only annotations of a given name)
*
* @param string $name Name of the annotations
* @return ezcReflectionAnnotation[] Annotations
* @since PHP 5.1.0
*/
public function getAnnotations($name = '') {
if ($name == '') {
return $this->docParser->getAnnotations();
}
else {
return $this->docParser->getAnnotationsByName($name);
}
}
/**
* Returns the PHPDoc comment of the property.
*
* @return string PHPDoc comment
* @since PHP 5.1.0
*/
public function getDocComment()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
// query external reflection object
$comment = $this->reflectionSource->getDocComment();
}
else
{
$comment = parent::getDocComment();
}
return $comment;
}
/**
* Returns the name of the property.
*
* @return string property name
*/
public function getName()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
$name = $this->reflectionSource->getName();
}
else
{
$name = parent::getName();
}
return $name;
}
/**
* Returns true if this property has public as access level.
*
* @return bool
*/
public function isPublic()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
return $this->reflectionSource->isPublic();
}
else
{
return parent::isPublic();
}
}
/**
* Returns true if this property has protected as access level.
*
* @return bool
*/
public function isProtected()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
return $this->reflectionSource->isProtected();
}
else
{
return parent::isProtected();
}
}
/**
* Returns true if this property has private as access level.
*
* @return bool
*/
public function isPrivate()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
return $this->reflectionSource->isPrivate();
}
else
{
return parent::isPrivate();
}
}
/**
* Returns true if this property has is a static property.
*
* @return bool
*/
public function isStatic()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
return $this->reflectionSource->isStatic();
}
else
{
return parent::isStatic();
}
}
/**
* Returns whether the property is a default property defined in the class.
*
* A default property is defined in the class definition.
* A non-default property is an instance specific state.
* @return bool
*/
public function isDefault()
{
if ( $this->reflectionSource instanceof ReflectionProperty )
{
return $this->reflectionSource->isDefault();
}
else
{
return parent::isDefault();
}
}
/**
* Returns a bitfield of the access modifiers for this property.
*
* @return int
*/
public function getModifiers()
{
return $this->forwardCallToReflectionSource( __FUNCTION__ );
}
/**
* Returns the property's value.
*
* @param object $object An object from which the property value is obtained
* @return mixed The property's value
*/
public function getValue( $object = null )
{
return $this->forwardCallToReflectionSource( __FUNCTION__, array( $object ) );
}
/**
* Changes the property's value.
*
* @param object $object An object on which the property value will be changed
* @param mixed $value Value of the property
* @return void
*/
public function setValue( $object, $value = null )
{
return $this->forwardCallToReflectionSource( __FUNCTION__, array( $object, $value ) );
}
/**
* Sets whether non-public properties can be requested
*
* @param boolean $value Whether non-public properties can be requested
* @return void
* @since PHP 5.3.0
*/
public function setAccessible( $value )
{
$this->forwardCallToReflectionSource( __FUNCTION__, array( $object, $value ) );
}
/**
* Returns a string representation
* @return string
*/
public function __toString() {
if ( $this->reflectionSource ) {
return $this->reflectionSource->__toString();
} else {
return parent::__toString();
}
}
/**
* Exports a ReflectionProperty instance.
*
* Returns the output if TRUE is specified for return, printing it otherwise.
* This is purely a wrapper method, which calls the corresponding method of
* the parent class.
* @param ReflectionClass|string $class
* ReflectionClass object or name of the class
* @param ReflectionProperty|string $property
* ReflectionProperty object or name of the class
* @param boolean $return
* Whether to return (TRUE) or print (FALSE) the output
* @return mixed
*/
public static function export($class, $property, $return = false) {
return parent::export($class, $property, $return);
}
}
?>