<?php
class Goose
{
public static function cast($class, $object)
{
if ($object instanceof $class)
{
return $object;
}
$c = new ReflectionClass($class);
// generate an object....
$code = 'class '.$name
.($c->isInterface() ? ' implements ' : ' extends ').$c->getName().' {'
.' protected $__obj;'
.' public function __construct($object) { $this->__obj = $object; }';
foreach ($c->getMethods() as $m)
{
/* @var $m ReflectionMethod */
if (!$m->isConstructor()
&& !$m->isDestructor())
{
$code .= self::buildMethod($m);
}
}
$code .= '}';
return new $name($object);
}
public static function isA($interface, $object)
{
if ($interface instanceof $object)
{
return TRUE;
}
$c1 = new ReflectionClass($interface);
$c2 = new ReflectionClass($object);
// include the constructor if we're not an object,
// because we'll probably want to construct it
return self::implementsInterface($c1, $c2, $construct);
}
protected static function buildMethod(ReflectionMethod $m)
{
$mod = ($m->getModifiers() & ~ReflectionMethod::IS_ABSTRACT);
return implode(' ', Reflection
::getModifierNames($mod))
. ' function '.$m->getName() .' () {'
. ' $a = func_get_args();'
. ' call_user_func_array(array($this->__obj, "'.$m->getName().'"), $a);'
. '}';
}
protected static function implementsInterface(ReflectionClass $interface, ReflectionClass $class, $include_constructor)
{
foreach ($interface->getMethods() as $m1)
{
/* @type $m1 ReflectionMethod */
if (($m1->isConstructor() === $include_constructor)
&& !$m1->isDestructor()
&& (($m2 = self::hasMethod($class, $m1)) === FALSE
|| !self::checkModifiers($m1, $m2)
|| !self::checkParameters($m1, $m2)))
{
return FALSE;
}
}
return TRUE;
}
protected static function hasMethod(ReflectionClass $c, ReflectionMethod $m)
{
$name = $m->getName();
if ($c->hasMethod($name))
{
return $c->getMethod($name);
}
return FALSE;
}
protected static function checkModifiers(ReflectionMethod $m1, ReflectionMethod $m2)
{
$mask = $m1->getModifiers();
switch (TRUE)
{
case ($mask & ReflectionMethod::IS_PUBLIC):
$mask |= ReflectionMethod::IS_PROTECTED;
case ($mask & ReflectionMethod::IS_PROTECTED):
$mask |= ReflectionMethod::IS_PRIVATE;
}
return ($m1->getModifiers() & $mask);
}
protected static function checkParameters(ReflectionMethod $m1, ReflectionMethod $m2)
{
if ($m2->getNumberOfRequiredParameters() < $m1->getNumberOfRequiredParameters())
{
return FALSE;
}
$params1 = $m1->getParameters();
$params2 = $m2->getParameters();
for ($i = 0; $i < $c; $i++)
{
$p1 = $params1[$i];
$p2 = $params2[$i];
/* @var $p1 ReflectionParameter */
/* @var $p2 ReflectionParameter */
if ($p1->isOptional() !== $p2->isOptional()
|| $p1->allowsNull() !== $p2->allowsNull()
|| $p1->isArray() !== $p2->isArray()
/*|| $p1->getClass() !== $p2->getClass()*/
|| $p1->isPassedByReference() !== $p2->isPassedByReference())
{
return FALSE;
}
}
return TRUE;
}
}
?>