<?php
namespace ticky;
use ticky\exception;
class reflect {
private static $reflectionClass;
public static function getInstance($class, array $args = []) {
$reflectionClass = self::getClass($class);
if (!$reflectionClass->isInstantiable()) {
throw new exception('Access to non-public constructor');
}
if ($args) {
return $reflectionClass->newInstanceArgs($args);
}
return $reflectionClass->newInstance();
}
public static function hasClass($class) {
if (!class_exists($class)) {
throw new exception('Class ' . $class . ' does not exist');
}
return true;
}
private static function getClass($class) {
if (@self::$reflectionClass[$class]) {
return self::$reflectionClass[$class];
} elseif (self::hasClass($class)) {
$reflectionClass = new \ReflectionClass($class);
self::$reflectionClass[$class] = $reflectionClass;
return $reflectionClass;
}
}
public static function getName($class) {
$reflectionClass = self::getClass($class);
return $reflectionClass->getShortName();
}
public static function hasMethod($class, $method) {
$reflectionClass = self::getClass($class);
return $reflectionClass->hasMethod($method);
}
public static function getMethod($class, $method) {
if (!self::hasMethod($class, $method) && self::hasMethod($class, '__call')) {
return self::getClass($class)->getMethod('__call');
} elseif (!self::hasMethod($class, $method) && !self::hasMethod($class, '__call')) {
throw new exception('Reflect error', 'Class ' . $class . ' method ' . $method . ' does not exist');
}
return self::getClass($class)->getMethod($method);
}
public static function invoke($class, $method) {
$reflectionMethod = self::getMethod($class, $method);
$methodAccess = self::getMethodAccess($class, $method);
if ($methodAccess !== 'public') {
throw new exception('Class ' . $class . ' ' . $methodAccess . ' method ' . $method . ' not allow access');
}
$instance = self::getInstance($class);
return $reflectionMethod->invoke($instance);
}
public static function getMethodAccess($class = null, $method = null) {
$class = $class ? $class : self::class;
$method = $method ? $method : __FUNCTION__;
$reflectionMethod = self::getMethod($class, $method);
if ($reflectionMethod->isAbstract()) {
return 'abstract';
}
if ($reflectionMethod->isPublic()) {
return 'public';
}
if ($reflectionMethod->isPrivate()) {
return 'private';
}
if ($reflectionMethod->isProtected()) {
return 'protected';
}
if ($reflectionMethod->isFinal()) {
return 'final';
}
if ($reflectionMethod->isStatic()) {
return 'static';
}
}
public static function getDocComment($class) {
$reflectionClass = self::getClass($class);
return $reflectionClass->getDocComment();
}
}