Ejemplo n.º 1
0
    static function generatePHPCodeChildren($useComments, $php, $tpl, &$nodeChildren, &$resourceData, &$parameters, $currentParameters)
    {
        foreach ($nodeChildren as $node) {
            $newNode = false;
            $nodeType = $node[0];
            if ($nodeType > eZTemplate::NODE_USER_CUSTOM) {
                // Do custom nodes
            } else {
                if ($nodeType > eZTemplate::NODE_INTERNAL) {
                    // Do custom internal nodes
                    if ($nodeType == eZTemplate::NODE_INTERNAL_CODE_PIECE) {
                        $codePiece = $node[1];
                        $spacing = $currentParameters['spacing'];
                        if (isset($node[2]['spacing'])) {
                            $spacing += $node[2]['spacing'];
                        }
                        $php->addCodePiece($codePiece, array('spacing' => $spacing));
                    } else {
                        if ($nodeType == eZTemplate::NODE_INTERNAL_WARNING) {
                            $warningText = $php->thisVariableText($node[1], 23, 0, false);
                            $warningLabel = false;
                            $warningLabelText = '';
                            if (isset($node[2])) {
                                $warningLabelText = $php->thisVariableText($node[2], 0, 0, false);
                            }
                            $spacing = $currentParameters['spacing'];
                            if (isset($node[3]['spacing'])) {
                                $spacing += $node[3]['spacing'];
                            }
                            $placementText = 'false';
                            if (isset($node[4])) {
                                $placementText = $php->thisVariableText($node[4], 0, 0, false);
                            }
                            $php->addCodePiece("\$tpl->warning( " . $warningLabelText . ", " . $warningText . ", " . $placementText . " );", array('spacing' => $spacing));
                        } else {
                            if ($nodeType == eZTemplate::NODE_INTERNAL_ERROR) {
                                $errorText = $php->thisVariableText($node[1], 21, 0, false);
                                $errorLabel = false;
                                $errorLabelText = '';
                                if (isset($node[2])) {
                                    $errorLabelText = $php->thisVariableText($node[2], 0, 0, false);
                                }
                                $spacing = $currentParameters['spacing'];
                                if (isset($node[3]['spacing'])) {
                                    $spacing += $node[3]['spacing'];
                                }
                                $placementText = 'false';
                                if (isset($node[4])) {
                                    $placementText = $php->thisVariableText($node[4], 0, 0, false);
                                }
                                $php->addCodePiece("\$tpl->error( " . $errorLabelText . ", " . $errorText . ", " . $placementText . " );", array('spacing' => $spacing));
                            } else {
                                if ($nodeType == eZTemplate::NODE_INTERNAL_OUTPUT_READ) {
                                    $variableName = $node[1];
                                    $spacing = $currentParameters['spacing'];
                                    if (isset($node[2]['spacing'])) {
                                        $spacing += $node[2]['spacing'];
                                    }
                                    $textName = eZTemplateCompiler::currentTextName($parameters);
                                    $assignmentType = $node[3];
                                    $assignmentText = $php->variableNameText($variableName, $assignmentType, $node[2]);
                                    $php->addCodePiece("{$assignmentText}\${$textName};", array('spacing' => $spacing));
                                } else {
                                    if ($nodeType == eZTemplate::NODE_INTERNAL_OUTPUT_ASSIGN) {
                                        $variableName = $node[1];
                                        $spacing = $currentParameters['spacing'];
                                        if (isset($node[2]['spacing'])) {
                                            $spacing += $node[2]['spacing'];
                                        }
                                        $textName = eZTemplateCompiler::currentTextName($parameters);
                                        $assignmentType = $node[3];
                                        $assignmentText = $php->variableNameText($textName, $assignmentType, $node[2]);
                                        $php->addCodePiece("{$assignmentText}\${$variableName};", array('spacing' => $spacing));
                                    } else {
                                        if ($nodeType == eZTemplate::NODE_INTERNAL_OUTPUT_INCREASE) {
                                            $spacing = $currentParameters['spacing'];
                                            if (isset($node[1]['spacing'])) {
                                                $spacing += $node[1]['spacing'];
                                            }
                                            $textName = eZTemplateCompiler::currentTextName($parameters);
                                            $php->addCodePiece("if " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( !isset( \$textStack ) )\n" . "    \$textStack = array();\n" . "\$textStack[] = \${$textName};\n" . "\${$textName} = '';", array('spacing' => $spacing));
                                        } else {
                                            if ($nodeType == eZTemplate::NODE_INTERNAL_OUTPUT_DECREASE) {
                                                $spacing = $currentParameters['spacing'];
                                                if (isset($node[1]['spacing'])) {
                                                    $spacing += $node[1]['spacing'];
                                                }
                                                $textName = eZTemplateCompiler::currentTextName($parameters);
                                                $php->addCodePiece("\${$textName} = array_pop( \$textStack );", array('spacing' => $spacing));
                                            } else {
                                                if ($nodeType == eZTemplate::NODE_INTERNAL_OUTPUT_SPACING_INCREASE) {
                                                    $spacing = $node[1];
                                                    $currentParameters['spacing'] += $spacing;
                                                    continue;
                                                } else {
                                                    if ($nodeType == eZTemplate::NODE_INTERNAL_SPACING_DECREASE) {
                                                        $spacing = $node[1];
                                                        $currentParameters['spacing'] -= $spacing;
                                                        continue;
                                                    } else {
                                                        if ($nodeType == eZTemplate::NODE_INTERNAL_VARIABLE_SET) {
                                                            $variableName = $node[1];
                                                            $variableValue = $node[2];
                                                            $spacing = $currentParameters['spacing'];
                                                            if (isset($node[3]['spacing'])) {
                                                                $spacing += $node[3]['spacing'];
                                                            }
                                                            $php->addVariable($variableName, $variableValue, eZPHPCreator::VARIABLE_ASSIGNMENT, array('spacing' => $spacing));
                                                        } else {
                                                            if ($nodeType == eZTemplate::NODE_INTERNAL_VARIABLE_UNSET) {
                                                                $variableName = $node[1];
                                                                $spacing = $currentParameters['spacing'];
                                                                if (isset($node[2]['spacing'])) {
                                                                    $spacing += $node[2]['spacing'];
                                                                }
                                                                if (is_array($variableName)) {
                                                                    $namespace = $variableName[0];
                                                                    $namespaceScope = $variableName[1];
                                                                    $variableName = $variableName[2];
                                                                    $namespaceText = eZTemplateCompiler::generateMergeNamespaceCode($php, $tpl, $namespace, $namespaceScope, array('spacing' => $spacing), true);
                                                                    if (!is_string($namespaceText)) {
                                                                        $namespaceText = "\$namespace";
                                                                    }
                                                                    $variableNameText = $php->thisVariableText($variableName, 0, 0, false);
                                                                    if (isset($node[2]['remember_set']) and $node[2]['remember_set']) {
                                                                        $php->addCodePiece("if " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( isset( \$setArray[{$namespaceText}][{$variableNameText}] ) )\n" . "{\n");
                                                                        $spacing += 4;
                                                                    }
                                                                    if (isset($node[2]['local-variable'])) {
                                                                        $php->addCodePiece("\$tpl->unsetLocalVariable( {$variableNameText}, {$namespaceText} );\n", array('spacing' => $spacing));
                                                                    } else {
                                                                        $php->addCodePiece("unset( \$vars[{$namespaceText}][{$variableNameText}] );", array('spacing' => $spacing));
                                                                    }
                                                                    if (isset($node[2]['remember_set']) and $node[2]['remember_set']) {
                                                                        $php->addCodePiece("\n}\n");
                                                                        $spacing -= 4;
                                                                    }
                                                                } else {
                                                                    $php->addVariableUnset($variableName, array('spacing' => $spacing));
                                                                }
                                                            } else {
                                                                if ($nodeType == eZTemplate::NODE_INTERNAL_RESOURCE_ACQUISITION || $nodeType == eZTemplate::NODE_OPTIMIZED_RESOURCE_ACQUISITION) {
                                                                    $resource = $node[1];
                                                                    $resourceObject = $tpl->resourceHandler($resource);
                                                                    if (!$resourceObject) {
                                                                        continue;
                                                                    }
                                                                    $spacing = $currentParameters['spacing'];
                                                                    if (isset($node[7]['spacing'])) {
                                                                        $spacing += $node[7]['spacing'];
                                                                    }
                                                                    $newRootNamespace = $node[8];
                                                                    $resourceVariableName = $node[9];
                                                                    $resourceFilename = isset($node[10]) ? $node[10] : false;
                                                                    /* We can only use fallback code if we know upfront which
                                                                     * template is included; it does not work if we are using
                                                                     * something from the ezobjectforwarder which makes the
                                                                     * uriMap an array */
                                                                    $useFallbackCode = true;
                                                                    $uriMap = $node[2];
                                                                    if (is_string($uriMap)) {
                                                                        $uriMap = array($uriMap);
                                                                    } else {
                                                                        $useFallbackCode = false;
                                                                    }
                                                                    $resourceMap = array();
                                                                    $hasCompiledCode = false;
                                                                    if (is_array($uriMap)) {
                                                                        foreach ($uriMap as $uriKey => $originalURI) {
                                                                            $uri = $originalURI;
                                                                            if ($resource) {
                                                                                $uri = $resource . ':' . $uri;
                                                                            }
                                                                            unset($tmpResourceData);
                                                                            $tmpResourceData = $tpl->resourceData($resourceObject, $uri, $node[1], $originalURI);
                                                                            $uriText = $php->thisVariableText($uri, 0, 0, false);
                                                                            $resourceCanCache = true;
                                                                            if (!$resourceObject->servesStaticData()) {
                                                                                $resourceCanCache = false;
                                                                            }
                                                                            if (!$tpl->isCachingAllowed()) {
                                                                                $resourceCanCache = false;
                                                                            }
                                                                            $tmpResourceData['text'] = null;
                                                                            $tmpResourceData['root-node'] = null;
                                                                            $tmpResourceData['compiled-template'] = false;
                                                                            $tmpResourceData['time-stamp'] = null;
                                                                            $tmpResourceData['key-data'] = null;
                                                                            $tmpResourceData['use-comments'] = eZTemplateCompiler::isCommentsEnabled();
                                                                            $subSpacing = 0;
                                                                            $hasResourceData = false;
                                                                            $savedLocale = setlocale(LC_CTYPE, null);
                                                                            if (isset($GLOBALS['eZTemplateCompilerResourceCache'][$tmpResourceData['template-filename']])) {
                                                                                $tmpFileName = $tmpResourceData['template-filename'];
                                                                                unset($tmpResourceData);
                                                                                $tmpResourceData = $GLOBALS['eZTemplateCompilerResourceCache'][$tmpFileName];
                                                                                $tmpResourceData['compiled-template'] = true;
                                                                                $tmpResourceData['use-comments'] = eZTemplateCompiler::isCommentsEnabled();
                                                                                $hasResourceData = true;
                                                                                $hasCompiledCode = true;
                                                                            } else {
                                                                                if ($useFallbackCode) {
                                                                                    // If we can use fallback code we don't need to compile the templates in advance
                                                                                    // Simply fake that it has been compiled by setting some variables
                                                                                    // Note: Yes this is a hack, but rewriting this code is not an easy task
                                                                                    if ($resourceObject->handleResource($tpl, $tmpResourceData, $node[4], $node[5])) {
                                                                                        $tmpResourceData['compiled-template'] = true;
                                                                                        $hasResourceData = true;
                                                                                        $hasCompiledCode = true;
                                                                                    }
                                                                                } else {
                                                                                    if ($resourceObject->handleResource($tpl, $tmpResourceData, $node[4], $node[5])) {
                                                                                        if (!$tmpResourceData['compiled-template'] and $tmpResourceData['root-node'] === null) {
                                                                                            $root =& $tmpResourceData['root-node'];
                                                                                            $root = array(eZTemplate::NODE_ROOT, false);
                                                                                            $templateText =& $tmpResourceData["text"];
                                                                                            $keyData = $tmpResourceData['key-data'];
                                                                                            $rootNamespace = '';
                                                                                            $tpl->parse($templateText, $root, $rootNamespace, $tmpResourceData);
                                                                                            $hasResourceData = false;
                                                                                        }
                                                                                        /* We always DO need to execute this part if we
                                                                                         * don't have any fallback code. If we can
                                                                                         * generate the fallback code we make the
                                                                                         * included template compile on demand */
                                                                                        if (!$tmpResourceData['compiled-template'] and $resourceCanCache and $tpl->canCompileTemplate($tmpResourceData, $node[5]) and !$useFallbackCode) {
                                                                                            $generateStatus = $tpl->compileTemplate($tmpResourceData, $node[5]);
                                                                                            // Time limit #2:
                                                                                            /* We reset the time limit to 60 seconds to
                                                                                             * ensure that remaining template has
                                                                                             * enough time to compile. However if time
                                                                                             * limit is unlimited (0) we leave it be */
                                                                                            $maxExecutionTime = ini_get('max_execution_time');
                                                                                            if ($maxExecutionTime != 0 && $maxExecutionTime < 60) {
                                                                                                @set_time_limit(60);
                                                                                            }
                                                                                            if ($generateStatus) {
                                                                                                $tmpResourceData['compiled-template'] = true;
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                    $GLOBALS['eZTemplateCompilerResourceCache'][$tmpResourceData['template-filename']] =& $tmpResourceData;
                                                                                }
                                                                            }
                                                                            setlocale(LC_CTYPE, $savedLocale);
                                                                            $textName = eZTemplateCompiler::currentTextName($parameters);
                                                                            if ($tmpResourceData['compiled-template']) {
                                                                                $hasCompiledCode = true;
                                                                                //                            if ( !eZTemplateCompiler::isFallbackResourceCodeEnabled() )
                                                                                //                                $useFallbackCode = false;
                                                                                $keyData = $tmpResourceData['key-data'];
                                                                                $templatePath = $tmpResourceData['template-name'];
                                                                                $key = $resourceObject->cacheKey($keyData, $tmpResourceData, $templatePath, $node[5]);
                                                                                $cacheFileName = eZTemplateCompiler::compilationFilename($key, $tmpResourceData);
                                                                                $directory = eZTemplateCompiler::compilationDirectory();
                                                                                $phpScript = eZDir::path(array($directory, $cacheFileName));
                                                                                $phpScriptText = $php->thisVariableText($phpScript, 0, 0, false);
                                                                                $resourceMap[$uriKey] = array('key' => $uriKey, 'uri' => $uri, 'phpscript' => $phpScript);
                                                                            }
                                                                        }
                                                                    }
                                                                    if ($useComments) {
                                                                        $variablePlacement = $node[6];
                                                                        if ($variablePlacement) {
                                                                            $originalText = eZTemplateCompiler::fetchTemplatePiece($variablePlacement);
                                                                            $php->addComment("Resource Acquisition:", true, true, array('spacing' => $spacing));
                                                                            $php->addComment($originalText, true, true, array('spacing' => $spacing));
                                                                        }
                                                                    }
                                                                    if ($hasCompiledCode) {
                                                                        if ($resourceVariableName) {
                                                                            $phpScriptText = '$phpScript';
                                                                            $phpScriptArray = array();
                                                                            foreach ($resourceMap as $resourceMapItem) {
                                                                                $phpScriptArray[$resourceMapItem['key']] = $resourceMapItem['phpscript'];
                                                                            }
                                                                            if (!$resourceFilename) {
                                                                                $php->addVariable("phpScriptArray", $phpScriptArray, eZPHPCreator::VARIABLE_ASSIGNMENT, array('spacing' => $spacing));
                                                                                $resourceVariableNameText = "\${$resourceVariableName}";
                                                                                $php->addCodePiece("\$phpScript = isset( \$phpScriptArray[{$resourceVariableNameText}] ) ? \$phpScriptArray[{$resourceVariableNameText}] : false;\n", array('spacing' => $spacing));
                                                                            } else {
                                                                                $php->addVariable("phpScript", $phpScriptArray[$node[10]], eZPHPCreator::VARIABLE_ASSIGNMENT, array('spacing' => $spacing));
                                                                            }
                                                                            // The default is to only check if it exists
                                                                            $modificationCheckText = "file_exists( {$phpScriptText} )";
                                                                            if (eZTemplateCompiler::isDevelopmentModeEnabled()) {
                                                                                $modificationCheckText = "@filemtime( {$phpScriptText} ) > filemtime( {$uriText} )";
                                                                            }
                                                                            $php->addCodePiece("\$resourceFound = false;\nif " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( {$phpScriptText} !== false and {$modificationCheckText} )\n{\n", array('spacing' => $spacing));
                                                                        } else {
                                                                            $php->addCodePiece("\$resourceFound = false;\n", array('spacing' => $spacing));
                                                                            $phpScript = $resourceMap[0]['phpscript'];
                                                                            $phpScriptText = $php->thisVariableText($phpScript, 0, 0, false);
                                                                            // Not sure where this should come from
                                                                            //                         if ( $resourceIndex > 0 )
                                                                            //                             $php->addCodePiece( "else " );
                                                                            // The default is to only check if it exists
                                                                            $modificationCheckText = "file_exists( {$phpScriptText} )";
                                                                            if (eZTemplateCompiler::isDevelopmentModeEnabled()) {
                                                                                $modificationCheckText = "@filemtime( {$phpScriptText} ) > filemtime( {$uriText} )";
                                                                            }
                                                                            $php->addCodePiece("if " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( {$modificationCheckText} )\n{\n", array('spacing' => $spacing));
                                                                        }
                                                                        /* Generate code to do a namespace switch and includes the template */
                                                                        $code = "\$resourceFound = true;\n\$namespaceStack[] = array( \$rootNamespace, \$currentNamespace );\n";
                                                                        if ($newRootNamespace) {
                                                                            $newRootNamespaceText = $php->thisVariableText($newRootNamespace, 0, 0, false);
                                                                            $code .= "\$currentNamespace = \$rootNamespace = !\$currentNamespace ? {$newRootNamespaceText} : ( \$currentNamespace . ':' . {$newRootNamespaceText} );\n";
                                                                        } else {
                                                                            $code .= "\$rootNamespace = \$currentNamespace;\n";
                                                                        }
                                                                        $code .= "\$tpl->createLocalVariablesList();\n" . "\$tpl->appendTemplateFetch( {$uriText} );\n" . "include( '" . eZTemplateCompiler::TemplatePrefix() . "' . {$phpScriptText} );\n" . "\$tpl->unsetLocalVariables();\n" . "\$tpl->destroyLocalVariablesList();\n" . "list( \$rootNamespace, \$currentNamespace ) = array_pop( \$namespaceStack );\n";
                                                                        $php->addCodePiece($code, array('spacing' => $spacing + 4));
                                                                        if ($useFallbackCode) {
                                                                            $php->addCodePiece("}\nelse\n{\n    \$resourceFound = true;\n", array('spacing' => $spacing));
                                                                        } else {
                                                                            $php->addCodePiece("}\n", array('spacing' => $spacing));
                                                                        }
                                                                        $subSpacing = 4;
                                                                    } else {
                                                                        /* Yes, this is a hack, but it is required because
                                                                         * sometimes the generated nodes after this one emit an
                                                                         * else statement while there is no accompanied if */
                                                                        $php->addCodePiece("\nif " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "(false)\n{\n}\n");
                                                                    }
                                                                    /* The fallback code will be added if we need to process an
                                                                     * URI, this will also compile a template then. We need to
                                                                     * do the namespace switch manually here otherwise the
                                                                     * processed template will be run on the node from which
                                                                     * the template was included from. */
                                                                    if ($useFallbackCode) {
                                                                        $code = "\$resourceFound = true;\n\$namespaceStack[] = array( \$rootNamespace, \$currentNamespace );\n";
                                                                        if ($newRootNamespace) {
                                                                            $newRootNamespaceText = $php->thisVariableText($newRootNamespace, 0, 0, false);
                                                                            $code .= "\$currentNamespace = \$rootNamespace = !\$currentNamespace ? {$newRootNamespaceText} : ( \$currentNamespace . ':' . {$newRootNamespaceText} );\n";
                                                                        } else {
                                                                            $code .= "\$rootNamespace = \$currentNamespace;\n";
                                                                        }
                                                                        $php->addCodePiece($code);
                                                                        $php->addCodePiece("\$textElements = array();\n\$extraParameters = array();\n\$tpl->processURI( {$uriText}, true, \$extraParameters, \$textElements, \$rootNamespace, \$currentNamespace );\n\${$textName} .= implode( '', \$textElements );\n", array('spacing' => $spacing + $subSpacing));
                                                                        $php->addCodePiece("list( \$rootNamespace, \$currentNamespace ) = array_pop( \$namespaceStack );\n");
                                                                    }
                                                                    if ($hasCompiledCode and $useFallbackCode) {
                                                                        $php->addCodePiece("}\n", array('spacing' => $spacing));
                                                                    }
                                                                } else {
                                                                    if ($nodeType == eZTemplate::NODE_INTERNAL_NAMESPACE_CHANGE) {
                                                                        $variableData = $node[1];
                                                                        $spacing = $currentParameters['spacing'];
                                                                        if (isset($node[2]['spacing'])) {
                                                                            $spacing += $node[2]['spacing'];
                                                                        }
                                                                        $php->addCodePiece("\$namespaceStack[] = \$currentNamespace;\n", array('spacing' => $spacing));
                                                                        $php->addCodePiece('$currentNamespace .= ( $currentNamespace ? ":" : "" ) . \'' . $variableData[0][1] . '\';' . "\n", array('spacing' => $spacing));
                                                                    } else {
                                                                        if ($nodeType == eZTemplate::NODE_INTERNAL_NAMESPACE_RESTORE) {
                                                                            $spacing = $currentParameters['spacing'];
                                                                            if (isset($node[1]['spacing'])) {
                                                                                $spacing += $node[1]['spacing'];
                                                                            }
                                                                            $php->addCodePiece("\$currentNamespace = array_pop( \$namespaceStack );\n", array('spacing' => $spacing));
                                                                        } else {
                                                                            if ($nodeType == eZTemplate::NODE_OPTIMIZED_INIT) {
                                                                                $code = <<<END
\$node = ( array_key_exists( \$rootNamespace, \$vars ) and array_key_exists( "node", \$vars[\$rootNamespace] ) ) ? \$vars[\$rootNamespace]["node"] : null;
if ( is_object( \$node ) )
\$object = \$node->attribute( 'object' );
if ( isset( \$object ) && is_object( \$object ) )
\$nod_{$resourceData['uniqid']} = \$object->attribute( 'data_map' );
else
\$nod_{$resourceData['uniqid']} = false;
unset( \$node, \$object );

END;
                                                                                $php->addCodePiece($code);
                                                                                // Tell the rest of the system that we have create the nod_* variable
                                                                                $resourceData['node-object-cached'] = true;
                                                                            } else {
                                                                                eZDebug::writeWarning("Unknown internal template node type {$nodeType}, ignoring node for code generation", 'eZTemplateCompiler:generatePHPCodeChildren');
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                } else {
                    if ($nodeType == eZTemplate::NODE_ROOT) {
                        $children = $node[1];
                        if ($children) {
                            $newCurrentParameters = $currentParameters;
                            $newCurrentParameters['spacing'] += 4;
                            eZTemplateCompiler::generatePHPCodeChildren($useComments, $php, $tpl, $children, $resourceData, $parameters, $newCurrentParameters);
                        }
                        continue;
                    } else {
                        if ($nodeType == eZTemplate::NODE_TEXT) {
                            $text = $node[2];
                            if ($text != '') {
                                $variablePlacement = $node[3];
                                $originalText = eZTemplateCompiler::fetchTemplatePiece($variablePlacement);
                                if ($useComments) {
                                    $php->addComment("Text start:", true, true, array('spacing' => $currentParameters['spacing']));
                                    $php->addComment($originalText, true, true, array('spacing' => $currentParameters['spacing']));
                                    $php->addComment("Text end:", true, true, array('spacing' => $currentParameters['spacing']));
                                }
                                $php->addVariable(eZTemplateCompiler::currentTextName($parameters), $text, eZPHPCreator::VARIABLE_APPEND_TEXT, array('spacing' => $currentParameters['spacing']));
                            }
                            continue;
                        } else {
                            if ($nodeType == eZTemplate::NODE_VARIABLE) {
                                $variableAssignmentName = $node[1];
                                $variableData = $node[2];
                                $variablePlacement = $node[3];
                                $variableParameters = array();
                                if (isset($node[4]) and $node[4]) {
                                    $variableParameters = $node[4];
                                }
                                $variableOnlyExisting = isset($node[5]) ? $node[5] : false;
                                $variableOverWrite = isset($node[6]) ? $node[6] : false;
                                $rememberSet = isset($node[7]) ? $node[7] : false;
                                $spacing = $currentParameters['spacing'];
                                if (isset($variableParameters['spacing'])) {
                                    $spacing += $variableParameters['spacing'];
                                }
                                $variableParameters = array_merge(array('variable-name' => 'var', 'text-result' => true), $variableParameters);
                                $dataInspection = eZTemplateCompiler::inspectVariableData($tpl, $variableData, $variablePlacement, $resourceData);
                                $newNode = $node;
                                $newNode[1] = false;
                                $treatVariableDataAsNonObject = isset($variableParameters['treat-value-as-non-object']) && $variableParameters['treat-value-as-non-object'];
                                if ($useComments) {
                                    $php->addComment("Variable data: " . "Is constant: " . ($dataInspection['is-constant'] ? 'Yes' : 'No') . " Is variable: " . ($dataInspection['is-variable'] ? 'Yes' : 'No') . " Has attributes: " . ($dataInspection['has-attributes'] ? 'Yes' : 'No') . " Has operators: " . ($dataInspection['has-operators'] ? 'Yes' : 'No'), true, true, array('spacing' => $spacing));
                                    $originalText = eZTemplateCompiler::fetchTemplatePiece($variablePlacement);
                                    $php->addComment('{' . $originalText . '}', true, true, array('spacing' => $spacing));
                                }
                                $generatedVariableName = $variableParameters['variable-name'];
                                $assignVariable = false;
                                if ($variableAssignmentName !== false) {
                                    if (is_array($variableAssignmentName)) {
                                        $variableParameters['text-result'] = false;
                                        $assignVariable = true;
                                    } else {
                                        $generatedVariableName = $variableAssignmentName;
                                        $variableParameters['text-result'] = false;
                                    }
                                }
                                $isStaticElement = false;
                                $nodeElements = $node[2];
                                $knownTypes = array();
                                if (eZTemplateNodeTool::isStaticElement($nodeElements) and !$variableParameters['text-result']) {
                                    $variableText = $php->thisVariableText(eZTemplateNodeTool::elementStaticValue($nodeElements), 0, 0, false);
                                    $isStaticElement = true;
                                } else {
                                    if (eZTemplateNodeTool::isPHPVariableElement($nodeElements) and !$variableParameters['text-result']) {
                                        $variableText = '$' . eZTemplateNodeTool::elementStaticValue($nodeElements);
                                        $isStaticElement = true;
                                    } else {
                                        $variableText = "\${$generatedVariableName}";
                                        eZTemplateCompiler::generateVariableCode($php, $tpl, $node, $knownTypes, $dataInspection, array('spacing' => $spacing, 'variable' => $generatedVariableName, 'treat-value-as-non-object' => $treatVariableDataAsNonObject, 'counter' => 0), $resourceData);
                                    }
                                }
                                if ($variableParameters['text-result']) {
                                    $textName = eZTemplateCompiler::currentTextName($parameters);
                                    if (count($knownTypes) == 0 or in_array('objectproxy', $knownTypes)) {
                                        $php->addCodePiece("\${$textName} .= ( is_object( \${$generatedVariableName} ) ? compiledFetchText( \$tpl, \$rootNamespace, \$currentNamespace, false, \${$generatedVariableName} ) : \${$generatedVariableName} );" . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "\n" . "unset( \${$generatedVariableName} );\n", array('spacing' => $spacing));
                                    } else {
                                        $php->addCodePiece("\${$textName} .= \${$generatedVariableName};\n" . "unset( \${$generatedVariableName} );\n", array('spacing' => $spacing));
                                    }
                                } else {
                                    if ($assignVariable) {
                                        $namespace = $variableAssignmentName[0];
                                        $namespaceScope = $variableAssignmentName[1];
                                        $variableName = $variableAssignmentName[2];
                                        $namespaceText = eZTemplateCompiler::generateMergeNamespaceCode($php, $tpl, $namespace, $namespaceScope, array('spacing' => $spacing), true);
                                        if (!is_string($namespaceText)) {
                                            $namespaceText = "\$namespace";
                                        }
                                        $variableNameText = $php->thisVariableText($variableName, 0, 0, false);
                                        $unsetVariableText = false;
                                        if ($variableOnlyExisting) {
                                            if (!$isStaticElement) {
                                                $unsetVariableText = "\n    unset( {$variableText} );";
                                            }
                                            $php->addCodePiece("if " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( array_key_exists( {$namespaceText}, \$vars ) && array_key_exists( {$variableNameText}, \$vars[{$namespaceText}] ) )\n" . "{\n" . "    \$vars[{$namespaceText}][{$variableNameText}] = {$variableText};{$unsetVariableText}\n" . "}", array('spacing' => $spacing));
                                        } else {
                                            if ($variableOverWrite) {
                                                if (!$isStaticElement) {
                                                    $unsetVariableText = "\nunset( {$variableText} );";
                                                }
                                                if (isset($variableParameters['local-variable'])) {
                                                    $php->addCodePiece("if ( \$tpl->hasVariable( {$variableNameText}, {$namespaceText} ) )\n{\n");
                                                    // if the variable already exists
                                                    $php->addCodePiece("    \$tpl->warning( '" . eZTemplateDefFunction::DEF_FUNCTION_NAME . "', \"Variable '{$variableName}' is already defined.\", " . $php->thisVariableText($variablePlacement) . " );\n");
                                                    $php->addCodePiece("    \$tpl->setVariable( {$variableNameText}, {$variableText}, {$namespaceText} );\n}\nelse\n{\n");
                                                    $php->addCodePiece("    \$tpl->setLocalVariable( {$variableNameText}, {$variableText}, {$namespaceText} );\n}\n", array('spacing' => $spacing));
                                                } else {
                                                    $php->addCodePiece("\$vars[{$namespaceText}][{$variableNameText}] = {$variableText};{$unsetVariableText}", array('spacing' => $spacing));
                                                }
                                            } else {
                                                if ($rememberSet) {
                                                    if (!$isStaticElement) {
                                                        $unsetVariableText = "\n    unset( {$variableText} );";
                                                    }
                                                    $php->addCodePiece("if " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( !isset( \$vars[{$namespaceText}][{$variableNameText}] ) )\n" . "{\n" . "    \$vars[{$namespaceText}][{$variableNameText}] = {$variableText};{$unsetVariableText}\n" . "    \$setArray[{$namespaceText}][{$variableNameText}] = true;\n" . "}\n", array('spacing' => $spacing));
                                                } else {
                                                    if (!$isStaticElement) {
                                                        $unsetVariableText = "\n    unset( {$variableText} );";
                                                    }
                                                    $php->addCodePiece("if " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( !isset( \$vars[{$namespaceText}][{$variableNameText}] ) )\n{\n    \$vars[{$namespaceText}][{$variableNameText}] = {$variableText};{$unsetVariableText}\n}", array('spacing' => $spacing));
                                                }
                                            }
                                        }
                                    } else {
                                        if ($variableAssignmentName !== false and $isStaticElement) {
                                            $php->addCodePiece("\${$generatedVariableName} = {$variableText};", array('spacing' => $spacing));
                                        } else {
                                            if ($variableAssignmentName !== false and !$isStaticElement and !$treatVariableDataAsNonObject) {
                                                // Normal assignment from an expression, no need to anything extra
                                            }
                                        }
                                    }
                                }
                                unset($dataInspection);
                            } else {
                                if ($nodeType == eZTemplate::NODE_FUNCTION) {
                                    $functionChildren = $node[1];
                                    $functionName = $node[2];
                                    $functionParameters = $node[3];
                                    $functionPlacement = $node[4];
                                    $newNode = array($nodeType, false, $functionName, $functionParameters, $functionPlacement);
                                    $parameterText = 'No parameters';
                                    if ($functionParameters) {
                                        $parameterText = "Parameters: " . implode(', ', array_keys($functionParameters));
                                    }
                                    if ($useComments) {
                                        $php->addComment("Function: {$functionName}, {$parameterText}", true, true, array('spacing' => $currentParameters['spacing']));
                                        $originalText = eZTemplateCompiler::fetchTemplatePiece($functionPlacement);
                                        $php->addComment('{' . $originalText . '}', true, true, array('spacing' => $currentParameters['spacing']));
                                    }
                                    if (isset($node[5])) {
                                        $functionHook = $node[5];
                                        $functionHookCustomFunction = $functionHook['function'];
                                        if ($functionHookCustomFunction) {
                                            $functionHookCustomFunction = array_merge(array('add-function-name' => false, 'add-hook-name' => false, 'add-template-handler' => true, 'add-function-hook-data' => false, 'add-function-parameters' => true, 'add-function-placement' => false, 'add-calculated-namespace' => false, 'add-namespace' => true, 'add-input' => false, 'return-value' => false), $functionHookCustomFunction);
                                            if (!isset($parameters['hook-result-variable-counter'][$functionName])) {
                                                $parameters['hook-result-variable-counter'][$functionName] = 0;
                                            }
                                            if ($functionHookCustomFunction['return-value']) {
                                                $parameters['hook-result-variable-counter'][$functionName]++;
                                            }
                                            $hookResultName = $functionName . 'Result' . $parameters['hook-result-variable-counter'][$functionName];
                                            if ($functionHookCustomFunction['add-input']) {
                                                $parameters['hook-result-variable-counter'][$functionName]--;
                                            }
                                            $functionHookCustomFunctionName = $functionHookCustomFunction['name'];
                                            $codeText = '';
                                            if ($functionHookCustomFunction['return-value']) {
                                                $codeText = "\${$hookResultName} = ";
                                            }
                                            if ($functionHookCustomFunction['static']) {
                                                $hookClassName = $functionHookCustomFunction['class-name'];
                                                $codeText .= "{$hookClassName}::{$functionHookCustomFunctionName}( ";
                                            } else {
                                                $codeText .= "\$functionObject->{$functionHookCustomFunctionName}( ";
                                            }
                                            $codeTextLength = strlen($codeText);
                                            $functionNameText = $php->thisVariableText($functionName, 0, 0, false);
                                            $functionChildrenText = $php->thisVariableText($functionChildren, $codeTextLength, 0, false);
                                            $inputFunctionParameters = $functionParameters;
                                            if ($functionHookCustomFunction['add-calculated-namespace']) {
                                                unset($inputFunctionParameters['name']);
                                            }
                                            $functionParametersText = $php->thisVariableText($inputFunctionParameters, $codeTextLength, 0, false);
                                            $functionPlacementText = $php->thisVariableText($functionPlacement, $codeTextLength, 0, false);
                                            $functionHookText = $php->thisVariableText($functionHook, $codeTextLength, 0, false);
                                            $functionHookName = $functionHook['name'];
                                            $functionHookNameText = $php->thisVariableText($functionHookName, 0, 0, false);
                                            $codeParameters = array();
                                            if ($functionHookCustomFunction['add-function-name']) {
                                                $codeParameters[] = $functionNameText;
                                            }
                                            if ($functionHookCustomFunction['add-hook-name']) {
                                                $codeParameters[] = $functionHookNameText;
                                            }
                                            if ($functionHookCustomFunction['add-function-hook-data']) {
                                                $codeParameters[] = $functionHookText;
                                            }
                                            if ($functionHookCustomFunction['add-template-handler']) {
                                                $codeParameters[] = "\$tpl";
                                            }
                                            if ($functionHookCustomFunction['add-function-parameters']) {
                                                $codeParameters[] = $functionParametersText;
                                            }
                                            if ($functionHookCustomFunction['add-function-placement']) {
                                                $codeParameters[] = $functionPlacementText;
                                            }
                                            if ($functionHookCustomFunction['add-calculated-namespace']) {
                                                $name = '';
                                                if (isset($functionParameters['name'])) {
                                                    $nameParameter = $functionParameters['name'];
                                                    $nameInspection = eZTemplateCompiler::inspectVariableData($tpl, $nameParameter, $functionPlacement, $resourceData);
                                                    if ($nameInspection['is-constant'] and !$nameInspection['is-variable'] and !$nameInspection['has-attributes'] and !$nameInspection['has-operators']) {
                                                        $nameData = $nameParameter[0][1];
                                                        $nameText = $php->thisVariableText($nameData, 0, 0, false);
                                                        $php->addCodePiece("if ( \$currentNamespace != '' )\n    \$name = \$currentNamespace . ':' . {$nameText};\nelse\n    \$name = {$nameText};\n", array('spacing' => $currentParameters['spacing']));
                                                        $codeParameters[] = "\$name";
                                                    } else {
                                                        $persistence = array();
                                                        $knownTypes = array();
                                                        eZTemplateCompiler::generateVariableCode($php, $tpl, $nameParameter, $knownTypes, $nameInspection, $persistence, array('variable' => 'name', 'counter' => 0), $resourceData);
                                                        $php->addCodePiece("if " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( \$currentNamespace != '' )\n{\n    if ( \$name != '' )\n        \$name = \"\$currentNamespace:\$name\";\n    else\n        \$name = \$currentNamespace;\n}\n", array('spacing' => $currentParameters['spacing']));
                                                        $codeParameters[] = "\$name";
                                                    }
                                                } else {
                                                    $codeParameters[] = "\$currentNamespace";
                                                }
                                            }
                                            if ($functionHookCustomFunction['add-namespace']) {
                                                $codeParameters[] = "\$rootNamespace, \$currentNamespace";
                                            }
                                            if ($functionHookCustomFunction['add-input']) {
                                                $codeParameters[] = "\${$hookResultName}";
                                            }
                                            $codeText .= implode(",\n" . str_repeat(' ', $codeTextLength), $codeParameters);
                                            $codeText .= " );\n";
                                            if ($functionHookCustomFunction['static']) {
                                                $hookFile = $functionHookCustomFunction['php-file'];
                                                $hookFileText = $php->thisVariableText($hookFile, 0, 0, false);
                                                $php->addCodePiece("include_once( {$hookFileText} );\n", array('spacing' => $currentParameters['spacing']));
                                            } else {
                                                $php->addCodePiece("\$functionObject = \$tpl->fetchFunctionObject( {$functionNameText} );\n", array('spacing' => $currentParameters['spacing']));
                                            }
                                            $php->addCodePiece($codeText, array('spacing' => $currentParameters['spacing']));
                                        } else {
                                            $functionNameText = $php->thisVariableText($functionName, 0, 0, false);
                                            $functionChildrenText = $php->thisVariableText($functionChildren, 52, 0, false);
                                            $functionParametersText = $php->thisVariableText($functionParameters, 52, 0, false);
                                            $functionPlacementText = $php->thisVariableText($functionPlacement, 52, 0, false);
                                            $functionHookText = $php->thisVariableText($functionHook, 52, 0, false);
                                            $functionHookName = $functionHook['name'];
                                            $functionHookNameText = $php->thisVariableText($functionHookName, 0, 0, false);
                                            $functionHookParameters = $functionHook['parameters'];
                                            $php->addCodePiece("\$functionObject = \$tpl->fetchFunctionObject( {$functionNameText} );\n\$hookResult = \$functionObject->templateHookProcess( {$functionNameText}, {$functionHookNameText},\n                                                    {$functionHookText},\n                                                    \$tpl,\n                                                    {$functionParametersText},\n                                                    {$functionPlacementText},\n                                                    \$rootNamespace, \$currentNamespace );\n", array('spacing' => $currentParameters['spacing']));
                                        }
                                    } else {
                                        $textName = eZTemplateCompiler::currentTextName($parameters);
                                        $functionNameText = $php->thisVariableText($functionName, 0, 0, false);
                                        $functionChildrenText = $php->thisVariableText($functionChildren, 22, 0, false);
                                        $functionParametersText = $php->thisVariableText($functionParameters, 22, 0, false);
                                        $functionPlacementText = $php->thisVariableText($functionPlacement, 22, 0, false);
                                        $php->addCodePiece("\$textElements = array();\n\$tpl->processFunction( {$functionNameText}, \$textElements,\n                       {$functionChildrenText},\n                       {$functionParametersText},\n                       {$functionPlacementText},\n                       \$rootNamespace, \$currentNamespace );\n\${$textName} .= implode( '', \$textElements );\n", array('spacing' => $currentParameters['spacing']));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            $php->addSpace();
        }
    }