public function __clone()
 {
     // TODO: Test this. Make sure cloning works properly.
     $newObject = clone $this->_hookObject;
     Hook::hookObject($newObject, get_class($newObject) . '->', false);
     return $newObject;
 }
Example #2
0
 /**
  * Hook an object.
  *
  * This hooks all (public) methods defined in the given object.
  *
  * @param object &$object The object to hook.
  * @param string $prefix The prefix used to call the object's methods. Usually something like "$object->".
  * @param bool $recursive Whether to hook objects recursively.
  * @return bool True on success, false on failure.
  */
 public static function hookObject(&$object, $prefix = '', $recursive = true)
 {
     if ((object) $object === $object) {
         $isString = false;
     } else {
         $isString = true;
     }
     // Make sure we don't take over the hook object, or we'll end up
     // recursively calling ourself. Some system classes shouldn't be hooked.
     $className = str_replace('\\', '_', $isString ? $object : get_class($object));
     global $_;
     if (isset($_) && in_array($className, array('\\SciActive\\Hook', 'depend', 'config', 'info'))) {
         return false;
     }
     if ($recursive && !$isString) {
         foreach ($object as $curName => &$curProperty) {
             if ((object) $curProperty === $curProperty) {
                 Hook::hookObject($curProperty, $prefix . $curName . '->');
             }
         }
     }
     if (!class_exists("\\SciActive\\HookOverride_{$className}")) {
         if ($isString) {
             $reflection = new \ReflectionClass($object);
         } else {
             $reflection = new \ReflectionObject($object);
         }
         $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
         $code = '';
         foreach ($methods as &$curMethod) {
             $fname = $curMethod->getName();
             if (in_array($fname, array('__construct', '__destruct', '__get', '__set', '__isset', '__unset', '__toString', '__invoke', '__set_state', '__clone', '__sleep', 'jsonSerialize'))) {
                 continue;
             }
             //$fprefix = $curMethod->isFinal() ? 'final ' : '';
             $fprefix = $curMethod->isStatic() ? 'static ' : '';
             $params = $curMethod->getParameters();
             $paramArray = $paramNameArray = array();
             foreach ($params as &$curParam) {
                 $paramName = $curParam->getName();
                 $paramPrefix = $curParam->isPassedByReference() ? '&' : '';
                 if ($curParam->isDefaultValueAvailable()) {
                     $paramSuffix = ' = ' . var_export($curParam->getDefaultValue(), true);
                 } else {
                     $paramSuffix = '';
                 }
                 $paramArray[] = "{$paramPrefix}\${$paramName}{$paramSuffix}";
                 $paramNameArray[] = "{$paramPrefix}\${$paramName}";
             }
             unset($curParam);
             $code .= $fprefix . "function {$fname}(" . implode(', ', $paramArray) . ") {\n" . (defined('HHVM_VERSION') ? "    \$arguments = array();\n" . (count($paramNameArray) > 0 ? "    \$arguments[] = " . implode('; $arguments[] = ', $paramNameArray) . ";\n" : '') . "    \$real_arg_count = func_num_args();\n" . "    \$arg_count = count(\$arguments);\n" . "    if (\$real_arg_count > \$arg_count) {\n" . "        for (\$i = \$arg_count; \$i < \$real_arg_count; \$i++)\n" . "            \$arguments[] = func_get_arg(\$i);\n" . "    }\n" : (version_compare(PHP_VERSION, '5.4.0') >= 0 ? "    \$arguments = debug_backtrace(false, 1);\n" : "    \$arguments = debug_backtrace(false);\n") . "    \$arguments = \$arguments[0]['args'];\n") . "    \$function = array(\$this->_hookObject, '{$fname}');\n" . "    \$data = array();\n" . "    \\SciActive\\Hook::runCallbacks(\$this->_hookPrefix.'{$fname}', \$arguments, 'before', \$this->_hookObject, \$function, \$data);\n" . "    if (\$arguments !== false) {\n" . "        \$return = call_user_func_array(\$function, \$arguments);\n" . "        if ((object) \$return === \$return && get_class(\$return) === '{$className}')\n" . "            \\SciActive\\Hook::hookObject(\$return, '{$prefix}', false);\n" . "        \$return = array(\$return);\n" . "        \\SciActive\\Hook::runCallbacks(\$this->_hookPrefix.'{$fname}', \$return, 'after', \$this->_hookObject, \$function, \$data);\n" . "        if ((array) \$return === \$return)\n" . "            return \$return[0];\n" . "    }\n" . "}\n\n";
         }
         unset($curMethod);
         // Build a HookOverride class.
         $include = str_replace(array('_NAMEHERE_', '//#CODEHERE#', '<?php', '?>'), array($className, $code, '', ''), Hook::$hookFile);
         eval($include);
     }
     eval('$object = new \\SciActive\\HookOverride_' . $className . ' ($object, $prefix);');
     return true;
 }