/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { // number (integer) if (!empty($attributes['number'])) { $number = $compiler->compileVarRef($attributes['number'], $options); } else { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'number', 'tag' => 'likes'))); } if (!empty($attributes['url'])) { $url = $compiler->compileVarRef($attributes['url'], $options); } else { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'url', 'tag' => 'likes'))); } return 'XenForo_Template_Helper_Core::callHelper(\'likeshtml\', array(' . $number . ',' . $url . ',' . $compiler->compileVarRef($attributes['liked'], $options) . ',' . $compiler->compileVarRef($attributes['users'], $options) . '))'; }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { if (empty($options['allowRawStatements'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('x_tags_only_used_where_full_statements_allowed', array('tag' => 'set'))); } if (empty($attributes['var'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'var', 'tag' => 'set'))); } $var = $compiler->compileVarRef($attributes['var'], array_merge($options, array('disableVarMap' => true))); $var = substr($var, 1); // need to take off leading $ if (empty($children)) { $children = null; } if (!empty($attributes['value'])) { if ($children) { throw $compiler->getNewCompilerException(new XenForo_Phrase('tag_contained_children_and_value_attribute')); } $value = $compiler->compileAndCombineSegments($attributes['value'], array_merge($options, array('varEscape' => false))); $childOutput = '$' . $var . ' = ' . $value . ";\n"; } else { $childOutput = $compiler->compileIntoVariable($children, $var, $options, false); } $statement = $compiler->getNewRawStatement(); $statement->addStatement($childOutput); return $statement; }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { if ($tag == 'breadcrumb') { throw $compiler->getNewCompilerException(new XenForo_Phrase('breadcrumb_tag_must_be_within_navigation_tag')); } if (empty($options['allowRawStatements'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('x_tags_only_used_where_full_statements_allowed', array('tag' => 'navigation'))); } $rawStatement = $compiler->getNewRawStatement(); $rawStatement->addStatement("\$__extraData['navigation'] = array();\n"); foreach ($children as $child) { if ($compiler->isSegmentNamedTag($child, 'breadcrumb')) { if (isset($child['attributes']['source'])) { $sourceVar = $compiler->compileVarRef($child['attributes']['source'], $options); $rawStatement->addStatement('$__extraData[\'navigation\'] = XenForo_Template_Helper_Core::appendBreadCrumbs($__extraData[\'navigation\'], ' . $sourceVar . ");\n"); } else { $parts = array(); foreach ($child['attributes'] as $name => $value) { $parts[] = "'" . $compiler->escapeSingleQuotedString($name) . "' => " . $compiler->compileAndCombineSegments($value, $options); } $parts[] = "'value' => " . $compiler->compileAndCombineSegments($child['children'], $options); $rawStatement->addStatement('$__extraData[\'navigation\'][] = array(' . implode(', ', $parts) . ");\n"); } } else { if (is_string($child) && trim($child) === '') { // whitespace -- ignore it } else { throw $compiler->getNewCompilerException(new XenForo_Phrase('invalid_data_found_in_navigation_tag'), $child); } } } return $rawStatement; }
/** * Compile the var named in the first argument and return PHP code to access it raw. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the function called * @param array Arguments to the function (should have at least 1) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $function, array $arguments, array $options) { if (count($arguments) != 1) { throw $compiler->getNewCompilerArgumentException(); } return $compiler->compileVarRef($arguments[0], $options); }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { if (!empty($attributes['user'])) { $user = $compiler->compileVarRef($attributes['user'], $options); } else { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'user', 'tag' => 'follow'))); } return 'XenForo_Template_Helper_Core::followHtml(' . $user . ',' . $compiler->getNamedParamsAsPhpCode($attributes, $options, array('code')) . ')'; }
/** * Helper to allow foreach tags to be compiled in multiple places with easier validation. * * @param string $inner Compiled inner code * @param XenForo_Template_Compiler $compiler * @param array $attributes * @param array $options * * @return XenForo_Compiler_Statement_Raw */ public static function compileForeach($inner, XenForo_Template_Compiler $compiler, array $attributes, array $options) { if (empty($attributes['loop'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'loop', 'tag' => 'foreach'))); } if (empty($attributes['value'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'value', 'tag' => 'foreach'))); } $noMapOptions = array_merge($options, array('disableVarMap' => true)); $loop = $compiler->compileVarRef($attributes['loop'], $options); $value = $compiler->compileVarRef($attributes['value'], $noMapOptions); if (isset($attributes['key'])) { $key = $compiler->compileVarRef($attributes['key'], $noMapOptions); $keyCode = $key . ' => '; } else { $keyCode = ''; } if (isset($attributes['i'])) { $i = $compiler->compileVarRef($attributes['i'], $noMapOptions); } else { $i = ''; } if (isset($attributes['count'])) { $count = $compiler->compileVarRef($attributes['count'], $noMapOptions); } else { $count = ''; } $statement = $compiler->getNewRawStatement(); if ($i) { $statement->addStatement($i . " = 0;\n"); } if ($count) { $statement->addStatement($count . ' = count(' . $loop . ");\n"); } $statement->addStatement('foreach (' . $loop . ' AS ' . $keyCode . $value . ")\n{\n"); if ($i) { $statement->addStatement($i . "++;\n"); } $statement->addStatement($inner)->addStatement("}\n"); return $statement; }
/** * Compile the var named in the first argument and return PHP code to access it raw. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the function called * @param array Arguments to the function (should have at least 1) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $function, array $arguments, array $options) { if (count($arguments) > 2) { throw $compiler->getNewCompilerArgumentException(); } $compileOptions = array_merge($options, array('varEscape' => false)); $raw = $compiler->compileVarRef($arguments[0], $options); if (empty($arguments[1])) { return $raw; } else { return 'XenForo_Template_Helper_Core::rawCondition(' . $raw . ', ' . $compiler->compileAndCombineSegments($arguments[1], $compileOptions) . ')'; } }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { if (!empty($attributes['time'])) { $time = $compiler->compileVarRef($attributes['time'], $options); } else { if (!empty($children)) { $time = $compiler->compileAndCombineSegments($children, $options); } else { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'time', 'tag' => 'datetime'))); } } return 'XenForo_Template_Helper_Core::callHelper(\'datetimehtml\', array(' . $time . ',' . $compiler->getNamedParamsAsPhpCode($attributes, $options, array('code')) . '))'; }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { if (empty($options['allowRawStatements'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('x_tags_only_used_where_full_statements_allowed', array('tag' => 'container'))); } if (empty($attributes['var'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_container_tag_var_attribute')); } $var = $compiler->compileVarRef($attributes['var'], array_merge($options, array('disableVarMap' => true))); $var = preg_replace('/^\\$([^[\']*)/', '__extraData[\'$1\']', $var); $childOutput = $compiler->compileIntoVariable($children, $var, $options, false); $statement = $compiler->getNewRawStatement(); $statement->addStatement($childOutput); return $statement; }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { // user array if (!empty($attributes['user'])) { $user = $compiler->compileVarRef($attributes['user'], $options); } else { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'user', 'tag' => 'avatar'))); } // avatar image mode (span or img) if (isset($attributes['img'])) { $img = $compiler->parseConditionExpression($attributes['img'], $options); } else { $img = 'false'; } return 'XenForo_Template_Helper_Core::callHelper(\'avatarhtml\', array(' . $user . ',' . $img . ',' . $compiler->getNamedParamsAsPhpCode($attributes, $options, array('code')) . ',' . $compiler->compileAndCombineSegments($children, $options) . '))'; }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { if (empty($options['allowRawStatements'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('x_tags_only_used_where_full_statements_allowed', array('tag' => 'set'))); } if (empty($attributes['var'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_attribute_x_for_tag_y', array('attribute' => 'var', 'tag' => 'set'))); } $var = $compiler->compileVarRef($attributes['var'], array_merge($options, array('disableVarMap' => true))); $var = substr($var, 1); // need to take off leading $ $childOutput = $compiler->compileIntoVariable($children, $var, $options, false); $statement = $compiler->getNewRawStatement(); $statement->addStatement($childOutput); return $statement; }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { // user array if (!empty($attributes['user'])) { $user = $compiler->compileVarRef($attributes['user'], $options); unset($attributes['user']); } else { throw $compiler->getNewCompilerException(new XenForo_Phrase('missing_x_attribute_for_y_tag', array('attribute' => 'user', 'tag' => 'username'))); } if (!empty($attributes['rich'])) { $rich = $compiler->parseConditionExpression($attributes['rich'], $options); } else { $rich = 'false'; } unset($attributes['rich']); return 'XenForo_Template_Helper_Core::userNameHtml(' . $user . ',' . $compiler->compileAndCombineSegments($children, $options) . ',' . $rich . ',' . $compiler->getNamedParamsAsPhpCode($attributes, $options, array('code')) . ')'; }
/** * Compile the specified tag and return PHP code to handle it. * * @param XenForo_Template_Compiler The invoking compiler * @param string Name of the tag called * @param array Attributes for the tag (may be empty) * @param array Nodes (tags/curlies/text) within this tag (may be empty) * @param array Compilation options * * @return string */ public function compile(XenForo_Template_Compiler $compiler, $tag, array $attributes, array $children, array $options) { if (empty($options['allowRawStatements'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('x_tags_only_used_where_full_statements_allowed', array('tag' => 'include'))); } if (empty($attributes['template']) || count($attributes['template']) != 1 || !is_string($attributes['template'][0])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('invalid_template_include_specified')); } $include = $attributes['template'][0]; $template = $compiler->includeParsedTemplate($include); $statement = $compiler->getNewRawStatement(); $tempVars = array(); $mapVars = array(); foreach ($children as $child) { if ($compiler->isSegmentNamedTag($child, 'map')) { $childAttr = $child['attributes']; if (empty($childAttr['from']) || empty($childAttr['to'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('included_template_variable_mappings_must_include_from_and_to_attributes')); } $from = $compiler->compileVarRef($childAttr['from'], $options); if (count($childAttr['to']) != 1 || !is_string($childAttr['to'][0])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('invalid_template_include_variable_mapping_specified')); } if (!preg_match('#^\\$([a-zA-Z_][a-zA-Z0-9_]*)$#', $childAttr['to'][0])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('invalid_template_include_variable_mapping_specified')); } // "from $outer" and "to $inner"; when processed (within inner template), need to map the other direction. $mapVars[substr($childAttr['to'][0], 1)] = substr($from, 1); } else { if ($compiler->isSegmentNamedTag($child, 'set')) { // take var as "to" and compile into a temporary variable $childAttr = $child['attributes']; if (empty($childAttr['var'])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('included_template_variable_assignments_must_include_var_attribute')); } if (count($childAttr['var']) != 1 || !is_string($childAttr['var'][0])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('invalid_template_include_variable_assignment_specified')); } $mapRegex = '#^\\$([a-zA-Z_][a-zA-Z0-9_]*)$#'; if (!preg_match($mapRegex, $childAttr['var'][0])) { throw $compiler->getNewCompilerException(new XenForo_Phrase('invalid_template_include_variable_assignment_specified')); } if (!empty($childAttr['value'])) { if ($child['children']) { throw $compiler->getNewCompilerException(new XenForo_Phrase('tag_contained_children_and_value_attribute')); } $value = $compiler->compileAndCombineSegments($childAttr['value'], array_merge($options, array('varEscape' => false))); $setVar = $compiler->getUniqueVar(); $childOutput = '$' . $setVar . ' = ' . $value . ";\n"; } else { $childOutput = $compiler->compileIntoVariable($child['children'], $setVar, $options); } $statement->addStatement($childOutput); $mapVars[substr($childAttr['var'][0], 1)] = $setVar; $tempVars[] = $setVar; } } } if ($template) { $oldMap = $compiler->getVariableMap(); $compiler->setVariableMap($mapVars, true); $compiled = $compiler->compileIntoVariable($template, $var, $options); $tempVars[] = $var; $compiler->setVariableMap($oldMap); $statement->addStatement($compiled); $statement->addStatement('$' . $compiler->getOutputVar() . ' .= $' . $var . ";\n" . 'unset($' . implode(', $', $tempVars) . ");\n"); return $statement; } else { return ''; } }