public static function aggregate($destClass, $sourceClass) { $destClass = strtolower($destClass); $sourceClass = strtolower($sourceClass); if (!isset(self::$mixins[$destClass]) || !in_array($sourceClass, self::$mixins[$destClass])) { if (!function_exists('runkit_method_copy')) { throw new Exception('Warning : runkit extension must be installed to support mixins features.'); } $reflection = new ReflectionClass($sourceClass); $sourceMethods = $reflection->getMethods(); $destReflection = new ReflectionClass($destClass); // à virer en 5.1 $destMethods = array(); foreach ($destReflection->getMethods() as $method) { $destMethods[] = $method->name; } foreach ($sourceMethods as $method) { //if ($destReflection->hasMethod($method->name)) pas avant PHP 5.1 if (!in_array($method->name, $destMethods)) { runkit_method_copy($destClass, $method->name, $sourceClass); } else { runkit_method_remove($destClass, $method->name); runkit_method_copy($destClass, $method->name, $sourceClass); } } self::$mixins[$destClass][] = $sourceClass; } }
/** * Modifies composer class loader. */ public function activate() { class_exists('Composer\\Autoload\\ClassLoader'); if (method_exists('Composer\\Autoload\\ClassLoader', self::ORIG_LOAD_CLASS)) { return; } runkit_method_rename('Composer\\Autoload\\ClassLoader', 'loadClass', self::ORIG_LOAD_CLASS); runkit_method_copy('Composer\\Autoload\\ClassLoader', 'loadClass', 'Guise\\ClassLoader'); }
/** * Creates runkit method to be used for mocking, taking care of callback to this object. * * Also temporary renames the original method if there is. */ protected function createFunction() { list($class, $method) = $this->getClassAndMethod(); $this->restore_name = 'restore_' . $class . '_' . $method . '_' . $this->id . '_' . uniqid(); // We save the original method in the class for restoring. runkit_method_copy($class, $this->restore_name, $class, $method); runkit_method_redefine($class, $method, '', $this->getCallback(), RUNKIT_ACC_STATIC); $this->active = true; }
protected function _redirectCallToMethod() { $newOrigFuncName = $this->_functionName . $this->_origFuncSuffix; $spyFuncName = $this->_functionName . $this->_spyFuncSuffix; $isStatic = (new \ReflectionMethod($this->_context, $this->_functionName))->isStatic(); $isInherited = !method_exists($this->_context, $this->_functionName) && method_exists(get_parent_class($this->_context), $this->_functionName); runkit_method_add($this->_context, $spyFuncName, '', $this->_getSpyFunctionBody(), RUNKIT_ACC_PRIVATE | ($isStatic ? RUNKIT_ACC_STATIC : 0)); if (!method_exists($this->_context, $newOrigFuncName)) { runkit_method_copy($this->_context, $newOrigFuncName, $this->_context, $this->_functionName); } //keep memory address of function to prevent seg fault $runkit_method_modifier = $isInherited ? 'runkit_method_add' : 'runkit_method_redefine'; $runkit_method_modifier($this->_context, $this->_functionName, '', $this->_getReplaceFunctionBody(), RUNKIT_ACC_PUBLIC | ($isStatic ? RUNKIT_ACC_STATIC : 0)); }
/** * Weaves the advice handler into to class/method. * * @param \ReflectionMethod $method */ protected function weaveHandler(\ReflectionMethod $method) { $class = $method->getDeclaringClass(); $origMethod = $method->getName(); $wovenMethod = sprintf('__guise_method__%s', $method->getName()); if ($class->hasMethod($wovenMethod)) { return; } class_exists('Guise\\Weaver\\Handler'); runkit_method_rename($class->getName(), $method->getName(), $wovenMethod); runkit_method_copy($class->getName(), $origMethod, 'Guise\\Weaver\\Handler', 'handle'); }
public static function addMethods($class) { foreach (get_class_methods('PropertyManipulatorMethods') as $method) { runkit_method_copy($class, $method, 'PropertyManipulatorMethods'); } }
/** * Mock a method. * * Replace the code of a function of a specific class * * @param Callable $method Method defined in an array form * @param String $mock Replacement code for the method * @param String $visibility Visibility of the redefined method * @param String $args Comma-delimited list of arguments for the redefined method * * @return void */ protected function mock_method($method, $mock, $visibility = 'public', $args = '') { $class_name = is_object($method[0]) ? get_class($method[0]) : $method[0]; $method_name = $method[1]; if (method_exists($class_name, $method_name . self::FUNCTION_ID) === FALSE) { runkit_method_copy($class_name, $method_name . self::FUNCTION_ID, $class_name, $method_name); } switch ($visibility) { case 'public': $visibility_flag = RUNKIT_ACC_PUBLIC; break; case 'protected': $visibility_flag = RUNKIT_ACC_PROTECTED; break; case 'private': $visibility_flag = RUNKIT_ACC_PRIVATE; break; } runkit_method_redefine($class_name, $method_name, $args, $mock, $visibility_flag); }