static function generateVariableDataCode($php, $tpl, $variableData, &$knownTypes, $dataInspection, &$persistence, $parameters, &$resourceData) { $staticTypeMap = array(eZTemplate::TYPE_STRING => 'string', eZTemplate::TYPE_NUMERIC => 'numeric', eZTemplate::TYPE_IDENTIFIER => 'string', eZTemplate::TYPE_ARRAY => 'array', eZTemplate::TYPE_BOOLEAN => 'boolean'); $variableAssignmentName = $parameters['variable']; $variableAssignmentCounter = $parameters['counter']; $spacing = 0; $optimizeNode = false; if (isset($parameters['spacing'])) { $spacing = $parameters['spacing']; } if ($variableAssignmentCounter > 0) { $variableAssignmentName .= $variableAssignmentCounter; } // We need to unset the assignment variable before any elements are processed // This ensures that we don't work on existing variables $php->addCodePiece("unset( \${$variableAssignmentName} );\n", array('spacing' => $spacing)); if (is_array($variableData)) { foreach ($variableData as $index => $variableDataItem) { $variableDataType = $variableDataItem[0]; if ($variableDataType == eZTemplate::TYPE_STRING or $variableDataType == eZTemplate::TYPE_NUMERIC or $variableDataType == eZTemplate::TYPE_IDENTIFIER or $variableDataType == eZTemplate::TYPE_ARRAY or $variableDataType == eZTemplate::TYPE_BOOLEAN) { $knownTypes = array_unique(array_merge($knownTypes, array($staticTypeMap[$variableDataType]))); $dataValue = $variableDataItem[1]; $dataText = $php->thisVariableText($dataValue, 0, 0, false); $php->addCodePiece("\${$variableAssignmentName} = {$dataText};\n", array('spacing' => $spacing)); } else { if ($variableDataType == eZTemplate::TYPE_OPTIMIZED_NODE) { $optimizeNode = true; if (!isset($resourceData['node-object-cached'])) { $tpl->error("eZTemplateCompiler" . ($resourceData['use-comments'] ? ":" . __LINE__ : ""), "Attribute node-object-cached of variable \$resourceData was not found but variable node eZTemplate::TYPE_OPTIMIZED_NODE is still present. This should not happen"); } $php->addCodePiece("\${$variableAssignmentName} = \$nod_{$resourceData['uniqid']};\n"); // If optimized node is not set, use unoptimized code. $php->addCodePiece("if ( !\${$variableAssignmentName} )\n{\n"); } else { if ($variableDataType == eZTemplate::TYPE_OPTIMIZED_ARRAY_LOOKUP) { $code = $resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/\n" : ""; // This code is used a lot so we create a variable for it $phpVar = "\${$variableAssignmentName}"; $indexName = "'{$variableDataItem[1][0][1]}'"; // Add sanity checking $code .= "if ( !isset( {$phpVar}[{$indexName}] ) )\n" . "{\n" . " \$tpl->error( 'eZTemplateCompiler" . ($resourceData['use-comments'] ? ":" . __LINE__ : "") . "', \"PHP variable \\{$phpVar}" . "[{$indexName}] does not exist, cannot fetch the value.\" );\n" . " {$phpVar} = null;\n" . "}\n" . "else\n "; // Add the actual code $code .= "{$phpVar} = {$phpVar}[{$indexName}];\n"; $php->addCodePiece($code); } else { if ($variableDataType == eZTemplate::TYPE_OPTIMIZED_ATTRIBUTE_LOOKUP) { $code = $resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/\n" : ""; $code .= <<<END if ( !is_object( \${$variableAssignmentName} ) ) { \${$variableAssignmentName} = null; } else if ( \${$variableAssignmentName}->hasAttribute( "{$variableDataItem[1][0][1]}" ) ) { \${$variableAssignmentName} = \${$variableAssignmentName}->attribute( "{$variableDataItem[1][0][1]}" ); } END; $php->addCodePiece($code); } else { if ($variableDataType == eZTemplate::TYPE_OPTIMIZED_CONTENT_CALL) { // Line number comment $code = $resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/\n" : ""; // This code is used a lot so we create a variable for it $phpVar = "\${$variableAssignmentName}"; // Add sanity checking $code .= "if ( !is_object( {$phpVar} ) )\n" . "{\n" . " \$tpl->error( 'eZTemplateCompiler" . ($resourceData['use-comments'] ? ":" . __LINE__ : "") . "', \"PHP variable \\{$phpVar} is not an object, cannot fetch content()\" );\n" . " {$phpVar} = null;\n" . "}\n" . "else\n" . "{\n"; // Add the actual code $code .= " {$phpVar}Tmp = {$phpVar}->content();\n" . " unset( {$phpVar} );\n" . " {$phpVar} = {$phpVar}Tmp;\n" . " unset( {$phpVar}Tmp );\n}\n"; $php->addCodePiece($code); } else { if ($variableDataType == eZTemplate::TYPE_PHP_VARIABLE) { $knownTypes = array(); $phpVariableName = $variableDataItem[1]; $php->addCodePiece("\${$variableAssignmentName} = \${$phpVariableName};\n", array('spacing' => $spacing)); } else { if ($variableDataType == eZTemplate::TYPE_VARIABLE) { $knownTypes = array(); $namespace = $variableDataItem[1][0]; $namespaceScope = $variableDataItem[1][1]; $variableName = $variableDataItem[1][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); $code = "unset( \${$variableAssignmentName} );\n"; $code .= "\${$variableAssignmentName} = ( array_key_exists( {$namespaceText}, \$vars ) and array_key_exists( {$variableNameText}, \$vars[{$namespaceText}] ) ) ? \$vars[{$namespaceText}][{$variableNameText}] : null;\n"; $php->addCodePiece($code, array('spacing' => $spacing)); } else { if ($variableDataType == eZTemplate::TYPE_ATTRIBUTE) { $knownTypes = array(); $newParameters = $parameters; $newParameters['counter'] += 1; $tmpVariableAssignmentName = $newParameters['variable']; $tmpVariableAssignmentCounter = $newParameters['counter']; if ($tmpVariableAssignmentCounter > 0) { $tmpVariableAssignmentName .= $tmpVariableAssignmentCounter; } if (eZTemplateNodeTool::isStaticElement($variableDataItem[1])) { $attributeStaticValue = eZTemplateNodeTool::elementStaticValue($variableDataItem[1]); $attributeText = $php->thisVariableText($attributeStaticValue, 0, 0, false); } else { $newParameters['counter'] += 1; $tmpKnownTypes = array(); eZTemplateCompiler::generateVariableDataCode($php, $tpl, $variableDataItem[1], $tmpKnownTypes, $dataInspection, $persistence, $newParameters, $resourceData); $newVariableAssignmentName = $newParameters['variable']; $newVariableAssignmentCounter = $newParameters['counter']; if ($newVariableAssignmentCounter > 0) { $newVariableAssignmentName .= $newVariableAssignmentCounter; } $attributeText = "\${$newVariableAssignmentName}"; } $php->addCodePiece("\${$tmpVariableAssignmentName} = compiledFetchAttribute( \${$variableAssignmentName}, {$attributeText} );\n" . "unset( \${$variableAssignmentName} );\n" . "\${$variableAssignmentName} = \${$tmpVariableAssignmentName};\n", array('spacing' => $spacing)); // End if optimized node object is null/false. See also eZTemplateOptimizer::optimizeVariable() if ($optimizeNode && $index == 3) { $php->addCodePiece("}\n"); } } else { if ($variableDataType == eZTemplate::TYPE_OPERATOR) { $knownTypes = array(); $operatorParameters = $variableDataItem[1]; $operatorName = $operatorParameters[0]; $operatorParameters = array_splice($operatorParameters, 1); $operatorNameText = $php->thisVariableText($operatorName, 0, 0, false); $operatorParametersText = $php->thisVariableText($operatorParameters, 23, 0, false); $operatorHint = eZTemplateCompiler::operatorHint($tpl, $operatorName); if (isset($operatorHint['output']) and $operatorHint['output']) { if (isset($operatorHint['output-type'])) { $knownType = $operatorHint['output-type']; if (is_array($knownType)) { $knownTypes = array_merge($knownTypes, $knownType); } else { $knownTypes[] = $knownType; } $knownTypes = array_unique($knownTypes); } else { $knownTypes[] = 'static'; } } $php->addCodePiece("if (! isset( \${$variableAssignmentName} ) ) \${$variableAssignmentName} = NULL;\n", array('spacing' => $spacing)); $php->addCodePiece("while " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( is_object( \${$variableAssignmentName} ) and method_exists( \${$variableAssignmentName}, 'templateValue' ) )\n" . " \${$variableAssignmentName} = \${$variableAssignmentName}" . "->templateValue();\n"); $php->addCodePiece("\$" . $variableAssignmentName . "Data = array( 'value' => \${$variableAssignmentName} );\n\$tpl->processOperator( {$operatorNameText},\n {$operatorParametersText},\n \$rootNamespace, \$currentNamespace, \$" . $variableAssignmentName . "Data, false, false );\n\${$variableAssignmentName} = \$" . $variableAssignmentName . "Data['value'];\nunset( \$" . $variableAssignmentName . "Data );\n", array('spacing' => $spacing)); } else { if ($variableDataType == eZTemplate::TYPE_VOID) { } else { if ($variableDataType == eZTemplate::TYPE_DYNAMIC_ARRAY) { $knownTypes = array_unique(array_merge($knownTypes, array('array'))); $code = '%output% = array( '; $matchMap = array('%input%', '%output%'); $replaceMap = array('$' . $variableAssignmentName, '$' . $variableAssignmentName); $unsetList = array(); $counter = 1; $paramCount = 0; $values = $variableDataItem[2]; $newParameters = $parameters; foreach ($values as $key => $value) { if ($paramCount != 0) { $code .= ', '; } ++$paramCount; $code .= '\'' . $key . '\' => '; if (eZTemplateNodeTool::isStaticElement($value)) { $code .= eZPHPCreator::variableText(eZTemplateNodeTool::elementStaticValue($value), 0, 0, false); continue; } $code .= '%' . $counter . '%'; $newParameters['counter'] += 1; $newVariableAssignmentName = $newParameters['variable']; $newVariableAssignmentCounter = $newParameters['counter']; if ($newVariableAssignmentCounter > 0) { $newVariableAssignmentName .= $newVariableAssignmentCounter; } $matchMap[] = '%' . $counter . '%'; $replaceMap[] = '$' . $newVariableAssignmentName; $unsetList[] = $newVariableAssignmentName; $tmpKnownTypes = array(); eZTemplateCompiler::generateVariableDataCode($php, $tpl, $value, $tmpKnownTypes, $dataInspection, $persistence, $newParameters, $resourceData); ++$counter; } $code .= ' );'; $code = str_replace($matchMap, $replaceMap, $code); $php->addCodePiece($code, array('spacing' => $spacing)); $php->addVariableUnsetList($unsetList, array('spacing' => $spacing)); } else { if ($variableDataType == eZTemplate::TYPE_INTERNAL_CODE_PIECE) { $code = $variableDataItem[1]; $values = false; $matchMap = array('%input%', '%output%'); $replaceMap = array('$' . $variableAssignmentName, '$' . $variableAssignmentName); $unsetList = array(); $counter = 1; if (isset($variableDataItem[3]) && is_array($variableDataItem[3])) { $newParameters = $parameters; $values = $variableDataItem[3]; foreach ($values as $value) { $newParameters['counter'] += 1; $newVariableAssignmentName = $newParameters['variable']; $newVariableAssignmentCounter = $newParameters['counter']; if ($newVariableAssignmentCounter > 0) { $newVariableAssignmentName .= $newVariableAssignmentCounter; } if (eZTemplateNodeTool::isStaticElement($value)) { $staticValue = eZTemplateNodeTool::elementStaticValue($value); $staticValueText = $php->thisVariableText($staticValue, 0, 0, false); if (preg_match("/%code{$counter}%/", $code)) { $matchMap[] = '%code' . $counter . '%'; $replaceMap[] = ''; } $matchMap[] = '%' . $counter . '%'; $replaceMap[] = $staticValueText; } else { $matchMap[] = '%' . $counter . '%'; $replaceMap[] = '$' . $newVariableAssignmentName; $unsetList[] = $newVariableAssignmentName; if (preg_match("/%code{$counter}%/", $code)) { $tmpPHP = new eZPHPCreator('', '', eZTemplateCompiler::TemplatePrefix()); $tmpKnownTypes = array(); eZTemplateCompiler::generateVariableDataCode($tmpPHP, $tpl, $value, $tmpKnownTypes, $dataInspection, $persistence, $newParameters, $resourceData); $newCode = $tmpPHP->fetch(false); if (count($tmpKnownTypes) == 0 or in_array('objectproxy', $tmpKnownTypes)) { $newCode .= "while " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( is_object( \${$newVariableAssignmentName} ) and method_exists( \${$newVariableAssignmentName}, 'templateValue' ) )\n" . " \${$newVariableAssignmentName} = \${$newVariableAssignmentName}" . "->templateValue();\n"; } $matchMap[] = '%code' . $counter . '%'; $replaceMap[] = $newCode; } else { $tmpKnownTypes = array(); eZTemplateCompiler::generateVariableDataCode($php, $tpl, $value, $tmpKnownTypes, $dataInspection, $persistence, $newParameters, $resourceData); if (!$parameters['treat-value-as-non-object'] and (count($tmpKnownTypes) == 0 or in_array('objectproxy', $tmpKnownTypes))) { $php->addCodePiece("while " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( is_object( \${$newVariableAssignmentName} ) and method_exists( \${$newVariableAssignmentName}, 'templateValue' ) )\n" . " \${$newVariableAssignmentName} = \${$newVariableAssignmentName}" . "->templateValue();\n", array('spacing' => $spacing)); } } } ++$counter; } } if (isset($variableDataItem[4]) && $variableDataItem[4] !== false) { $values = $variableDataItem[4]; for ($i = 0; $i < $values; $i++) { $newParameters['counter'] += 1; $newVariableAssignmentName = $newParameters['variable']; $newVariableAssignmentCounter = $newParameters['counter']; if ($newVariableAssignmentCounter > 0) { $newVariableAssignmentName .= $newVariableAssignmentCounter; } $matchMap[] = '%tmp' . ($i + 1) . '%'; $replaceMap[] = '$' . $newVariableAssignmentName; $unsetList[] = $newVariableAssignmentName; } } if (isset($variableDataItem[5]) and $variableDataItem[5]) { if (is_array($variableDataItem[5])) { $knownTypes = array_unique(array_merge($knownTypes, $variableDataItem[5])); } else { if (is_string($variableDataItem[5])) { $knownTypes = array_unique(array_merge($knownTypes, array($variableDataItem[5]))); } else { $knownTypes = array_unique(array_merge($knownTypes, array('static'))); } } } $code = str_replace($matchMap, $replaceMap, $code); $php->addCodePiece($code, array('spacing' => $spacing)); $php->addVariableUnsetList($unsetList, array('spacing' => $spacing)); } } } } } } } } } } } } } } // After the entire expression line is done we try to extract the actual value if proxies are used $php->addCodePiece("if (! isset( \${$variableAssignmentName} ) ) \${$variableAssignmentName} = NULL;\n"); $php->addCodePiece("while " . ($resourceData['use-comments'] ? "/*TC:" . __LINE__ . "*/" : "") . "( is_object( \${$variableAssignmentName} ) and method_exists( \${$variableAssignmentName}, 'templateValue' ) )\n" . " \${$variableAssignmentName} = \${$variableAssignmentName}" . "->templateValue();\n"); }