/** * Will inject invocation code for a given function into a given piece of code. * Invocation code will be the instantiation of a \AppserverIo\Doppelgaenger\Entities\MethodInvocation object * as a basic representation of the given function * * @param string $bucketData Reference on the current bucket's data * @param FunctionDefinition $functionDefinition Definition of the function to inject invocation code into * @param array $callbackChain Chain of callbacks which is used to recursively chain calls * * @return boolean */ protected function injectInvocationCode(&$bucketData, FunctionDefinition $functionDefinition, array $callbackChain) { // start building up the code $code = ' ' . ReservedKeywords::METHOD_INVOCATION_OBJECT . ' = new \\AppserverIo\\Doppelgaenger\\Entities\\MethodInvocation( '; // add the original method call to the callback chain so it can be integrated, add it and add the context if ($functionDefinition->isStatic()) { $contextCode = '__CLASS__'; } else { $contextCode = '$this'; } // iterate the callback chain and build up the code but pop the first element as we will invoke it initially unset($callbackChain[0]); // empty chain? Add the original function at least if (empty($callbackChain)) { $callbackChain[] = array($functionDefinition->getStructureName(), $functionDefinition->getName()); } $code .= ' array('; foreach ($callbackChain as $callback) { // do some brushing up for the structure $structure = $callback[0]; if ($structure === $functionDefinition->getStructureName()) { $structure = $contextCode; } // also brush up the function call to direct to the original if ($callback[1] === $functionDefinition->getName()) { $callback[1] = $functionDefinition->getName() . ReservedKeywords::ORIGINAL_FUNCTION_SUFFIX; } $code .= 'array(' . $structure . ', \'' . $callback[1] . '\'),'; } $code .= '), '; // continue with the access modifiers $code .= ' ' . $contextCode . ', ' . ($functionDefinition->isAbstract() ? 'true' : 'false') . ', ' . ($functionDefinition->isFinal() ? 'true' : 'false') . ', ' . ($functionDefinition->isStatic() ? 'true' : 'false') . ', '; // we have to build up manual parameter collection as func_get_args() only returns copies // @see http://php.net/manual/en/function.func-get-args.php $parametersCode = ' array('; foreach ($functionDefinition->getParameterDefinitions() as $parameterDefinition) { $name = $parameterDefinition->name; $parametersCode .= '\'' . substr($name, 1) . '\' => ' . $name . ','; } $parametersCode .= ')'; $code .= ' \'' . $functionDefinition->getName() . '\', ' . $parametersCode . ', __CLASS__, \'' . $functionDefinition->getVisibility() . '\' );'; // Insert the code $placeholder = Placeholders::FUNCTION_BEGIN . $functionDefinition->getName() . Placeholders::PLACEHOLDER_CLOSE; $bucketData = str_replace($placeholder, $placeholder . $code, $bucketData); return true; }