<?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;
}
}