/** * Implements specific function call methods. These methods are available for all the base inheritence classes. * Currently, we have implemented support for: * - function hooking; this enables an aspect oriented coding style * - function result caching; this dramatically improves program execution * - function timing; this times the execution of a specific function. Do note that the result is encapsulated in a Map. * - function memory measurement; this calculates the amount of memory needed for a specific function. Do note that the result is encapsulated in a Map. * Note: Calling functions using the caching method, these functions need to be at least protected or public, and can not use referenced parameters. * Note: This function should not be called directly, and should be used only in the __call function. * @param string The name of the function to call * @param array An array containing all the arguments * @param mixed The context from the call, a string in case of static context, the object reference when called as an instance * @param mixed The returnvalue of the function is stored here. * @return boolean Returns true when a handler is called, false otherwise. */ protected static final function __callDefaultHandlers($name, array &$arguments, $sourceContext, &$returnValue) { /* upon extension of this function, the \System\Inspection\APIGen::addClassMethods should also be extended */ switch (true) { //we support function hooking case mb_substr($name, 0, 2) == 'h_': //we remove the 'h_' character from the functionname to call the original $returnValue = \System\Inspection\Hook::call(array($sourceContext, mb_substr($name, 2)), $arguments); return true; //we support function timing //we support function timing case mb_substr($name, 0, 2) == 't_': $col = new \System\Collection\Map(); $time = \System\Inspection\Timer::timeCall(array($sourceContext, mb_substr($name, 2)), $returnVal, $arguments); $col['time'] = $time; $col['result'] = $returnVal; $returnValue = $col; return true; //we support function memory measurement //we support function memory measurement case mb_substr($name, 0, 2) == 'm_': $returnValue = \System\Inspection\Memory::measureCall(array($sourceContext, mb_substr($name, 2)), $returnVal, $arguments); $returnValue['result'] = $returnVal; return true; //we support function result caching. //we support function result caching. case mb_substr($name, 0, 2) == 'c_': //we remove the 'c_' character from the functionname to call the original if (is_object($sourceContext)) { /* do note: static calls from instance context are cached in the instance, and called as such */ $returnValue = $sourceContext->functionCache(mb_substr($name, 2), $arguments); //from an instance context } else { $returnValue = self::functionCacheStatic(mb_substr($name, 2), $arguments); //from a static context } return true; case mb_substr($name, 0, 2) == 'is': $propertyName = lcfirst(mb_substr($name, 2)); if (property_exists($sourceContext, $propertyName)) { $reflectionProperty = new \ReflectionProperty($sourceContext, $propertyName); if (mb_stripos($reflectionProperty->getDocComment(), '@publicget') !== false && mb_stripos($reflectionProperty->getDocComment(), '@var bool') !== false && ($reflectionProperty->isPublic() || $reflectionProperty->isProtected())) { $returnValue = !$reflectionProperty->isStatic() ? (bool) $sourceContext->{$propertyName} : (bool) static::${$propertyName}; return true; } } break; case mb_substr($name, 0, 3) == 'get': $propertyName = lcfirst(mb_substr($name, 3)); if (property_exists($sourceContext, $propertyName)) { $reflectionProperty = new \ReflectionProperty($sourceContext, $propertyName); if (mb_stripos($reflectionProperty->getDocComment(), '@publicget') !== false && ($reflectionProperty->isPublic() || $reflectionProperty->isProtected())) { //when the @validatehandle comment is set, we look at the @var comment to create a new map and ensure validity if (mb_stripos($reflectionProperty->getDocComment(), '@validatehandle') !== false) { $typeDef = self::getFunctionParamType($reflectionProperty); if (($typeDef = self::getFunctionParamType($reflectionProperty)) && is_subclass_of($typeDef, '\\System\\Collection\\BaseMap')) { if (!$reflectionProperty->isStatic()) { if (!$sourceContext->{$propertyName} instanceof \System\Collection\BaseMap) { $sourceContext->{$propertyName} = new $typeDef(); } } else { if (!static::${$propertyName}) { static::${$propertyName} = new $typeDef(); } } } else { throw new \System\Error\Exception\InvalidMethodException('@validatehandle is defined for ' . $name . '(), but the parameter type is not given or not a decendant of \\System\\Collection\\BaseMap'); } } $returnValue = !$reflectionProperty->isStatic() ? $sourceContext->{$propertyName} : static::${$propertyName}; return true; } } break; case mb_substr($name, 0, 3) == 'set': $propertyName = lcfirst(mb_substr($name, 3)); if (count($arguments) == 1 && property_exists($sourceContext, $propertyName)) { $propertyName = lcfirst(mb_substr($name, 3)); $reflectionProperty = new \ReflectionProperty($sourceContext, $propertyName); if (mb_stripos($reflectionProperty->getDocComment(), '@publicset') !== false && ($reflectionProperty->isPublic() || $reflectionProperty->isProtected()) && self::checkPublicSetTypeEquality($reflectionProperty, $arguments[0])) { if (!$reflectionProperty->isStatic()) { $sourceContext->{$propertyName} = $arguments[0]; $returnValue = $sourceContext; } else { static::${$propertyName} = $arguments[0]; $returnValue = static::${$propertyName}; //static functions cannot return an instance object, and thus return the value set } return true; } } break; } return false; }
/** * Constructs the object and connects the hooks to the event */ public function __construct() { \System\Inspection\Hook::register('\\System\\Security\\XOREncoding::XOREncrypt', array($this, 'raise'), \System\Inspection\Hook::HOOK_POST); }