Location: PHPKode > scripts > phpCoreClass > phpcoreclass/class.phpCoreClass.php
<?php
/**
 * @desc Extends the core PHP stdClass to publish, to extending classes, some "meta" informations
 * 			about the class/object itself via protected properties.
 * 			Behavior which can be redefined in extending classes are protected.
 * 			
 * 			in futur versions, will be added:
 * 				-phpCoreClassModel (managing a class model via code)
 * 				-phpCoreClassModelGenerator (generating code from models via code)
 * 				-phpCoreDirectory (managing directories where generations will be written in)
 *
 * @author St├ęphane ERARD
 * @copyright St├ęphane ERARD 
 * @license GPL v2
 * 
 */
class phpCoreClass
{
	/**
	 * @desc an global ID related to the php environment.
	 * 			So this property is only to be used inside
	 * 			one php environment instance, a script
	 * 			execution instance. 
	 *
	 * @var int
	 */
	protected $____PGUID;
	
	/**
	 * @desc is this class abstract
	 *
	 * @var boolean
	 */
	protected $____isAbstract = false;
	
	/**
	 * @desc is this class final/leaf ?
	 *
	 * @var boolean
	 */
	protected $____isFinal = false;
	
	/**
	 * @desc the name of the Class, in the PHP point of view.
	 *
	 * @var string
	 */
	protected $____Name;
	
	/**
	 * @desc the ReflectionObject of the class. PHP Point of view.
	 *
	 * @var ReflectionObject
	 */
	protected $____Reflector;
	
	/**
	 * @desc an array of all parents of this class, including phpCoreClass.
	 *			array elements are of type ReflectionClass
	 * @var array
	 */
	protected $____Parent = array();
	
	/**
	 * @desc an array of all features of a PHP class.
	 * 			This is only needed by the internal of the phpCoreClass.
	 *			This shouldn't be modifier until you entirely understand how building method works.
	 * 
	 * @var array
	 */
	protected $____Features = array( array( '____Constant', 'Constants', true ),
									array('____Property', 'Properties', true ),
									array('____Method', 'Methods', true )
								);
	
	/**
	 * @desc an array of all Constants of this Class
	 *		array elements are of type ReflectionClass
	 * @var array
	 */
	private $____Constant = array();
	
	/**
	 * @desc an array of all Properties of this Class
	 *		array elements are of type ReflectionClass
	 * @var array
	 */
	private $____Property = array();
	
	/**
	 * @desc an array of all Methods of this Class
	 *		array elements are of type ReflectionClass
	 * @var array
	 */
	private $____Method = array();
	
	/**
	 * @desc a multi dimensionnal array of all classes and their instances.
	 *		array keys are class names while array elements are instances.
	 * @var array
	 */
	static public $____Objects = array();
	
	
	
	/**
	 * @desc The constructor of the phpCoreClass.
	 * 			As this class is pretty special, we finalize the constructor, and allow
	 * 			pre and post processing by extending protected methods ____buildPre and 
	 * 			____buildPost.
	 * 
	 * 		All the thing done by the building process is:
	 * 			1-call pre building process (dummy method implemented in this class)
	 * 			2-set name using this class name (from php internal get_class())
	 * 			3-set object reflector using ReflectionObject (php internal)
	 * 			4-set Parent's Tree of this class as an array stored in $this->____Parent
	 * 			5-build Features of a PHP Class : Constants, Properties and Methods.
	 * 			 	These are defined in the $this->____Features property.
	 * 				This is only an implementation facility.
	 * 			6-call post building process( dummy method implemented in this class)
	 *
	 * 		Clearly, the work done by this class is to simply prepare some meta information
	 * 		about the class/object itself.
	 * 		The goal is to ease the development of underlying classes such as phpCodeCoreClassifier, 
	 * 		which will itself ease the development of underlying classes such as phpCodeClass, etc.
	 * 		This will be done, foreach underlying classes, in different ways. All will need
	 * 		informations about their own internal features (at their own very level, without inheritance
	 * 		interference in properties and attributs), to build themselves and
	 * 		ease the build of underlying classes (as the parent classes will by themselves
	 * 		build the underlying objects, simply as they propose some ways to design these
	 * 		underlying classes).
	 */
	final public function __construct()
	{
		$args = $this->____buildPre( $args );
		
		$this->____Name = get_class( $this );

		$this->____Reflector = new ReflectionObject( $this );
		$this->____buildParentsTree();

		$this->____buildFeaturesTree();
		$this->____buildFeaturesByParentsTree();
		$this->____buildInstance();
		
		$this->____buildPost( $args );
	}

		/**
		 * @desc If you need builder pre processing, this is the method to redefine in
		 * 			extending classes of this one.
		 *
		 * @param array $args
		 * @return array
		 */
		protected function ____buildPre( $args )
		{
			//dummy
			return $args;
		}
		
		/**
		 * @desc If you need builder post processing, this is the method to redefine in
		 * 			extending classes of this one.
		 *
		 */
		protected function ____buildPost()
		{
			//dummy
		}

	/**
	 * @desc build an array of ReflectionClass objects else for the root class (phpCoreObject)
	 *	 		which is a ReflectionObject.
	 *
	 */
	private function ____buildParentsTree()
	{
		$refl = $this->____Reflector;
		while( is_a( $refl, ReflectionClass ) )
		{
			$this->____Parent[$refl->getName()] = new ReflectionClass( $refl->getName() ); //because of next line : we reassign $refl container
			$refl = $refl->getParentClass();
		}
		//$this->____Parent[__CLASS__] = $this->____Reflector;
		$this->____Parent = array_reverse( $this->____Parent, 0 );
	}
	
	/**
	 * @desc build dynamic properties to this object which will
	 * 			be arrays of things compounding and defining this object
	 * 			(the ____Features). 
	 *
	 */
	private function ____buildFeaturesTree()
	{
		$refl = $this->____Reflector;
		foreach( $this->____Features as $feature )
		{
			$featurePluralName = $feature[1];
			$featurePropertyName = $feature[0];
			$featurePropertyIsCollection = $feature[2];
			
			$reflFeatGetter = "get$featurePluralName";
			$this->$featurePropertyName = $refl->$reflFeatGetter();	
		}
	}

	/**
	 * @desc build dynamic properties, and sorting them by parent.
	 * 			Foreach features, will build an array of the features
	 * 			given by each class of $this->____Parent array.
	 * 		This is only for ease of development.
	 *
	 * @param array $features
	 */
	protected function ____buildFeaturesByParentsTree( $features = NULL )
	{
		if( is_null( $features ) ) $features = $this->____Features;

		foreach( $features as $feature )
		{
			$pluralFeatureName = $feature[1];	//Constants
			$thisFeatureName = $feature[0];		//____Constant
			$thisPropByParentName = "____{$pluralFeatureName}ByParent";	//ConstantsByParent
			$this->$thisPropByParentName = array();
			$thisPropBy = &$this->$thisPropByParentName;
			$parents = $this->____Parent;
			foreach( array_keys( $parents ) as $parent )
			{
				$reflFeatGetter = "get$pluralFeatureName";
				$thisPropBy[$parent] = array();
				$features_ = call_user_method_array( $reflFeatGetter, new ReflectionClass( $parent ), array() );
				foreach( $features_ as $feature_ )
				{
					if( is_a( $feature_, Reflector ) )
					{
						if( $feature_->getDeclaringClass()->getName() == $parent )
						{
							$thisPropBy[$parent][$feature_->getName()] = $feature_;
						}
					}
				}
			}
		}
	}

	private function ____buildInstance()
	{
		$this->____PGUID = time();
		$h = &self::$____Objects; //object'instances reference container, sorted by class hierarchy
		foreach( array_keys( $this->____Parent ) as $parent )
		{
			if( !isset( $h[$parent] ) )
			{
				$h[$parent] = array();
			}
			$h = &$h[$parent];
		}
		array_push( $h, &$this );
	}

	/**
	 * @desc return the name of the class from PHP point of view.
	 *
	 * @return string
	 */
	final public function getName()
	{
		return $this->____Name;
	}
	
	public function __get( $name )
	{
		return $this->$name;
	}
	
	public function __set( $name, $value )
	{
		$this->$name = $value;
		return $this;
	}
}
Return current item: phpCoreClass