public static function getReturn($class, $method, $params) { if (MonkeyPatchManager::$debug) { $trace = debug_backtrace(); $file = $trace[0]['file']; $line = $trace[0]['line']; if (isset($trace[2])) { $called_method = isset($trace[2]['class']) ? $trace[2]['class'] . '::' . $trace[2]['function'] . '()' : $trace[2]['function'] . '()'; } else { $called_method = 'n/a'; } $log_args = function () use($params) { $output = ''; foreach ($params as $arg) { $output .= var_export($arg, true) . ', '; } $output = rtrim($output, ', '); return $output; }; MonkeyPatchManager::log('invoke_method: ' . $class . '::' . $method . '(' . $log_args() . ') on line ' . $line . ' in ' . $file . ' by ' . $called_method); // var_dump($trace); exit; } self::$invocations[$class . '::' . $method][] = $params; $patch = isset(self::$patches[$class][$method]) ? self::$patches[$class][$method] : null; if ($patch === null) { return __GO_TO_ORIG__; } if (is_callable($patch)) { return call_user_func_array($patch, $params); } else { return $patch; } }
public function test_patch_miss_cache() { $cache_dir = APPPATH . 'tests/_ci_phpunit_test/tmp/cache_test'; CIPHPUnitTest::setPatcherCacheDir($cache_dir); $cache_file = Cache::getSrcCacheFilePath(__FILE__); $this->assertFalse(file_exists($cache_file)); MonkeyPatchManager::patch(__FILE__); $this->assertTrue(file_exists($cache_file)); }
public function patch($source) { $patched = false; static::$replacement = []; $parser = (new ParserFactory())->create(MonkeyPatchManager::getPhpParser(), new Lexer(['usedAttributes' => ['startTokenPos', 'endTokenPos']])); $traverser = new NodeTraverser(); $traverser->addVisitor($this->node_visitor); $ast_orig = $parser->parse($source); $traverser->traverse($ast_orig); if (static::$replacement !== []) { $patched = true; $new_source = static::generateNewSource($source); } else { $new_source = $source; } return [$new_source, $patched]; }
public static function getReturn($class, $method, $params) { if (MonkeyPatchManager::$debug) { $trace = debug_backtrace(); $info = Backtrace::getInfo('MethodPatcher', $trace); $file = $info['file']; $line = $info['line']; if (isset($info['class_method'])) { $called_method = $info['class_method']; } elseif (isset($info['function'])) { $called_method = $info['function']; } else { $called_method = 'n/a'; } $log_args = function () use($params) { $output = ''; foreach ($params as $arg) { $output .= var_export($arg, true) . ', '; } $output = rtrim($output, ', '); return $output; }; MonkeyPatchManager::log('invoke_method: ' . $class . '::' . $method . '(' . $log_args() . ') on line ' . $line . ' in ' . $file . ' by ' . $called_method); // var_dump($trace); exit; } self::$invocations[$class . '::' . $method][] = $params; if (isset(self::$patches[$class]) && array_key_exists($method, self::$patches[$class])) { $patch = self::$patches[$class][$method]; } else { return __GO_TO_ORIG__; } if (is_callable($patch)) { return call_user_func_array($patch, $params); } else { return $patch; } }
public static function __callStatic($function, array $arguments) { $function = strtolower($function); self::logInvocation($function, $arguments); self::$invocations[$function][] = $arguments; if (isset(self::$patches_to_apply[$function])) { if (!self::checkCalledMethod($function)) { MonkeyPatchManager::log('invoke_func: ' . $function . '() not patched (out of scope)'); self::checkPassedByReference($function); return call_user_func_array($function, $arguments); } } if (array_key_exists($function, self::$patches)) { MonkeyPatchManager::log('invoke_func: ' . $function . '() patched'); if (is_callable(self::$patches[$function])) { $callable = self::$patches[$function]; $return = call_user_func_array($callable, $arguments); if ($return !== __GO_TO_ORIG__) { return $return; } return call_user_func_array($function, $arguments); } return self::$patches[$function]; } MonkeyPatchManager::log('invoke_func: ' . $function . '() not patched (no patch)'); self::checkPassedByReference($function); return call_user_func_array($function, $arguments); }
protected static function checkFunctionWhitelistUpdate() { $cached = Cache::getTmpFunctionWhitelist(); $current = FunctionPatcher::getFunctionWhitelist(); // Updated? if ($cached !== $current) { MonkeyPatchManager::log('clear_src_cache: from ' . __METHOD__); Cache::clearSrcCache(); Cache::writeTmpFunctionWhitelist($current); } }
public static function clearCache() { self::recursiveUnlink(self::$cache_dir); MonkeyPatchManager::log('clear_cache: cleared ' . self::$cache_dir); }
/** * Get patched constant value * * @param string $constant * @return mixed */ public static function get($constant) { self::logInvocation($constant); if (isset(self::$patches_to_apply[$constant])) { if (!self::checkCalledMethod($constant)) { MonkeyPatchManager::log('invoke_const: ' . $constant . ' not patched (out of scope)'); return constant($constant); } } if (array_key_exists($constant, self::$patches)) { MonkeyPatchManager::log('invoke_const: ' . $constant . ' patched'); return self::$patches[$constant]; } MonkeyPatchManager::log('invoke_const: ' . $constant . ' not patched (no patch)'); return constant($constant); }