Source for file Validator.php
Documentation is available at Validator.php
require_once 'HTML/Template/PHPLIB/Helper.php';
* Class to validate templates (syntax checks)
* @package HTML_Template_PHPLIB
* @author Christian Weiske <cweiske@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @link http://pear.php.net/package/HTML_Template_PHPLIB
* Validates a template file.
* You can pass either a file name, or the file content. One of the parameters
* @param string $strFile Template file name to check
* @param string $strContent Template content to check
* @return mixed Boolean true if no errors have been found, array of
* errors otherwise. An error is an array with keys
* - 'short' (short error code, string)
* - 'message' (readable message)
* - 'code' (code that caused the error)
* false if no file and content is given
function validate($strFile = null , $strContent = null )
if ($arLines === false ) {
return count($arErrors) == 0 ? true : $arErrors;
}//function validate($strFile = null, $strContent = null)
* Check if all block definitions have a closing counterpart
* and if the block comments have all the required spaces
* @param array $arLines Array of template code lines
* @return array Array of errors/warnings. An error/warning is an array
* of several keys: message, line
//Array of block definitions found.
// key is the block name, value is an array of line numbers
$strRegex = '/<!--(\s*)(BEGIN|END)(\s*)([a-zA-Z0-9_]*)(\s*)-->/';
foreach ($arLines as $nLine => $strLine) {
if (preg_match($strRegex, $strLine, $arMatches)) {
//code line numbers start with 1, not 0
$strType = $arMatches[2 ];
$strBlockName = $arMatches[4 ];
$strArName = $strType == 'BEGIN' ? 'arBlockOpen' : 'arBlockClose';
if ($arMatches[1 ] == '') {
//space missing between <!-- and BEGIN|END
'short' => 'MISSING_SPACE',
'message' => 'Space missing between HTML comment opening marker and ' . $strType,
if ($arMatches[3 ] == '') {
//space missing between BEGIN and block name
'short' => 'MISSING_SPACE',
'message' => 'Space missing between ' . $strType . ' and block name',
if ($arMatches[4 ] == '') {
'short' => 'MISSING_BLOCK_NAME',
'message' => 'Block name missing',
$ {$strArName}[$strBlockName][] = $nLine;
'open' => $strType == 'BEGIN'
if ($arMatches[5 ] == '') {
//space missing between block name and -->
'short' => 'MISSING_SPACE',
'message' => 'Space missing between block name and HTML comment end marker',
* Check if all open blocks have a close counterpart
foreach ($arBlockOpen as $strBlockName => $arLines) {
if (count($arLines) > 1 ) {
'short' => 'DUPLICATE_BLOCK',
'message' => 'Block "' . $strBlockName . '" is opened'
. ' several times on lines ' . implode(', ', $arLines),
if (!isset ($arBlockClose[$strBlockName])) {
'short' => 'UNFINISHED_BLOCK',
'message' => 'Block "' . $strBlockName . '" is not closed.',
foreach ($arBlockClose as $strBlockName => $arLines) {
if (count($arLines) > 1 ) {
'short' => 'DUPLICATE_BLOCK',
'message' => 'Block "' . $strBlockName . '" is closed'
. ' several times on lines ' . implode(', ', $arLines),
if (!isset ($arBlockOpen[$strBlockName])) {
'short' => 'UNFINISHED_BLOCK',
'message' => 'Block "' . $strBlockName . '" is closed but not opened.',
* Check correct order (that begin comes before end)
foreach ($arBlockOpen as $strBlockName => $arLines) {
if (isset ($arBlockClose[$strBlockName])
&& $arLines[0 ] > $arBlockClose[$strBlockName][0 ]) {
'short' => 'WRONG_ORDER',
'message' => 'BEGIN of block "' . $strBlockName . '" defined after END.',
foreach ($arBlocks as $arBlock) {
$arStack[] = $arBlock['name'];
if (end($arStack) == $arBlock['name']) {
//closing block is not the expected one
$strStackName = end($arStack);
if ($strStackName === null ) {
//no open block defined -> we already handle this
'short' => 'WRONG_NESTING',
'message' => 'Block "' . $arBlock['name'] . '" closed,'
. ' but "' . $strStackName . '" is still open.',
'line' => $arBlock['line'],
'code' => $arBlock['code']
}//function checkBlockDefinitions($arLines)
* Checks if the variables defined are correct
* @param array $arLines Array of template content lines
* @return array Array of error messages.
$strAllowed = 'a-zA-Z0-9_-';
. '([' . $strAllowed . ']+)'
. '([^' . $strAllowed . ']|$)'
. '([^' . $strAllowed . ']|^)'
. '([' . $strAllowed . ']+)'
$arLineMatches = array ();
foreach ($arLines as $n => $strLine) {
$arLineMatches[$n + 1 ] = $arMatches;
foreach ($arLineMatches as $nLine => $arMatches) {
foreach ($arMatches[0 ] as $nId => $strFull) {
$chOpen = $arMatches[1 ][$nId];
$strVariable = $arMatches[2 ][$nId];
$chClose = $arMatches[3 ][$nId];
'short' => 'OPENING_BRACE_MISSING',
'message' => 'Variable "' . $strVariable . '" misses opening brace.',
} else if ($chClose != '}') {
'short' => 'CLOSING_BRACE_MISSING',
'message' => 'Variable "' . $strVariable . '" misses closing brace.',
}//function checkVariables($strContent)
* Sorts the given error array by line numbers
* @param array &$arErrors Error array
usort($arErrors, array (__CLASS__ , 'intcmpLine'));
}//function sortByLine(&$arErrors)
* Compares the two error arrays by line number
* @param array $arA Error array one
* @param array $arB Error array two
* @return integer -1, 0 or 1 if $arA is smaller, equal or bigger than $arB
return $arA['line'] - $arB['line'];
}//function intcmpLine($arA, $arB)
}//class HTML_Template_PHPLIB_Validator
Documentation generated on Mon, 11 Mar 2019 15:10:14 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|