warningLevel & E_YAPTER_ERROR) if ($this->warningLevel & E_YAPTER_DIE_ON_ERROR ) // if DIE_ON_ERROR is set, then do die on error! die("
\nYapter error: ".$msg."
\n"); // Die here! else // else just barf out the message echo "
\nYapter error: ".$msg."
\n"; } function warning($msg) { if ($this->warningLevel & E_YAPTER_WARNING) echo "
\nYapter warning: ".$msg."
\n"; } function notice($msg) { if ($this->warningLevel & E_YAPTER_NOTICE) echo "
\nYapter notice: ".$msg."
\n"; } function warn_var_not_set($varname) { if (!in_array($varname, $this->missing_list) && !($this->warningLevel & E_YAPTER_IGN_UNKNOWN_VARS)) { $this->missing_list[] = $varname; // Add it to the list... // ...and print a warning once. $this->warning('Variable '.htmlspecialchars($varname).' found, but never assigned a value. (This message is shown only once for each variable.)'); } } ///////////////////////////////////////////////////////////////////// function Template($file, $level = E_YAPTER_ALL) { if (is_bool($level)) { // // Rationale: // ========= // Older Yapter versions had the possibility of turning // on the so called "debug mode" with a bool parameter // as the second argument to this constructor. // However, since debug mode was dropped and the // warning level support was built in, it was a logical // step of replacing the second parameter. // // However, to prevent people from making mistakes, // we'll check if the user passed a boolean parameter. // If so, he or she is probably using debug mode, and // we'll issue a notice in these cases. // // Thanks to Ivo Koster. // $this->notice('Debug mode is not supported anymore since Yapter version 2.12.'); $this->warningLevel = E_YAPTER_ALL; } else $this->warningLevel = (int)$level; $this->startTime = $this->getmicrotime(); $this->addBlockFromFile($this->_ROOT, $file); $this->missing_list = array(); } /* setParseMode(): specifies to parse unknown variables or not */ function setParseMode($parseUnknownVars) { $this->parseUnknownVars = (bool)$parseUnknownVars; } /* setWarningLevel(): sets the level of verbosity which Yapter should obey */ function setWarningLevel($level) { $this->warningLevel = $level; } /* addBlock(): adds a new block to the blox-array */ function addBlock($blockname, $content) { $this->blox[$blockname]['content'] = $content; $this->blox[$blockname]['numlines'] = sizeof($this->blox[$blockname]['content']); $this->blox[$blockname]['parsed'] = ''; $this->prepare($blockname); } /* addBlockFromFile(): adds a new block, filling it with the specified's file contents */ function addBlockFromFile($blockname, $file) { $content = @file($file) or $this->error('Cannot open template file '.htmlspecialchars($file).'!'); //--- eliminate double block def mod -klp // if ($blockname != $this->_ROOT) // $this->addBlockDef($blockname, $content); $this->addBlock($blockname, $content); } /* addBlockDef(): adds a block definition to the block-definition array from which other blocks can be copied */ function addBlockDef($blockdef, $content) { /* if (isset($this->blockDefs[$blockdef])) $this->error('Block "'.htmlspecialchars($blockdef).'" allready exists. I cannot create it twice.'); else $this->blockDefs[$blockdef] = $content; */ $this->blockDefs[$blockdef] = $content; } /* addBlockFromDef(): copies a block from the block definition array */ function addBlockFromDef($blockname, $blockdef) { $this->addBlock($blockname, $this->blockDefs[$blockdef]); } /* prepare(): handles subprocessing of templates found in the main template file */ function prepare($blockname) { $currblockcontents = array(); $block = &$this->blox[$blockname]; for ($i = 0; $i < $block['numlines']; $i++) { if (isset($block['content'][$i])) $line = $block['content'][$i]; else continue; // Try to find a tag-definition on this line if (preg_match('/\[(INCLUDE|BLOCK|END|REUSE|SET) ([A-Za-z0-9_.\/-]+)( AS ([A-Za-z0-9_-]+))?]/', $line, $matches)) { $type = $matches[1]; $name = (!empty($matches[4])) ? $matches[4] : $matches[2]; if ($type == 'END' && !isset($currblockdef)) $this->error('"[END '.$name.']" found without matching "[BLOCK '.$name.']" or "[SET '.$name.']"'); if ($type == 'END' && $matches[2] == $currblockdef) { if (isset($matches[4])) $this->error('Given "AS"-parameter not allowed in END-tags!'); // End the current block definition: add the block to the blox-array //--- if wrapper mod -klp if (isset($currblockdef) && isset($currblockcontents) && isset($currblockname)) { $this->addBlockDef($currblockdef, $currblockcontents); $this->addBlockFromDef($currblockname, $currblockdef); } // Now, try to remove the block from the template definition, replacing it with a var for ($j = $i; $j >= $currblockstart; $j--) { if ($j == $currblockstart && $currblocktype == 'BLOCK') $block['content'][$j] = "{" . $currblockname . "}"; else unset($block['content'][$j]); } // unset these thingies for further preparing unset($currblocktype); unset($currblockstart); unset($currblockname); unset($currblockdef); $currblockcontents = array(); } elseif (($type == 'SET' || $type == 'BLOCK') && !isset($currblockname)) { if ($type == 'BLOCK') { // Start block definition $currblocktype = $type; $currblockstart = $i; $currblockname = $name; $currblockdef = $matches[2]; } else { // SET-tag // Start block definition if (isset($matches[4])) $this->error('Given "AS"-parameter not allowed in SET-tags!'); $currblocktype = $type; $currblockstart = $i; $currblockname = $matches[2]; $currblockdef = $matches[2]; } } elseif ($type == 'INCLUDE' && !isset($currblockname)) { // Make this line a variable... $block['content'][$i] = "{" . $name . "}\n"; // ...and include the given file... $this->addBlockFromFile($name, $matches[2]); } elseif ($type == 'REUSE' && !isset($currblockname)) { if (!isset($matches[4])) $this->error('Missing "AS"-parameter in [REUSE $name] tag!'); // Make this line a variable... $block['content'][$i] = "{" . $matches[4] . "}\n"; // ...and get this REUSE value from the block definition list... $this->addBlockFromDef($matches[4], $matches[2]); } elseif ($currblockname != $name) { if ($currblockname) $currblockcontents[] = $line; } } else { // No tag-definition... just normal text so do nothing here if (!empty($currblockname)) $currblockcontents[] = $line; } } } /* parse(): parses the specified block, filling variables and nested blockdefs */ function parse($blockname = '') { if (!$blockname) $blockname = $this->_ROOT; if (!isset($this->blox[$blockname])) $this->error('Block "'.htmlspecialchars($blockname).'" does not exist.'); $block = &$this->blox[$blockname]; $parsed = $block['content']; // Loop through all the lines of the template and parse variables one-by-one for ($i = 0; $i < $block['numlines']; $i++) { if (!isset($parsed[$i])) continue; $line = $parsed[$i]; // Look for variables in this line, processing it character-by-character unset($start); unset($buffer); for ($j = 0; $j < strlen($line); $j++) { $char = $line[$j]; if (!isset($start) && $char == '{') $start = $j; elseif (isset($start) && $char == '}') { // The sequence {} is not a valid variable value if (!isset($buffer)) { unset($start); continue; } else { // Gotcha! Now replace this variable with its contents // First, check to see if it's a variable or a block that has to be parsed if (isset($this->vars[$buffer])) $value = $this->vars[$buffer]; elseif (isset($this->blox[$buffer])) { if ($this->blox[$buffer]['parsed']) { // The value must be filled with the parsed data from the $buffer block $value = @implode('', $this->blox[$buffer]['parsed']); } elseif ($this->warningLevel & E_YAPTER_AUTO_HIDE_BLOCK) { // Automaticly hide unparsed bloks $value = ""; } else { // Make the recursive call now $value = @implode('', $this->parse($buffer)); } } else { // No variable or block name found by the name of $buffer // First, issue a warning! $this->warn_var_not_set($buffer); if ($this->parseUnknownVars) { // Unable to find variable, replace this one with an empty // string silently. $value = ''; } else { // Unable to find variable, leave this one alone... unset($start); unset($buffer); continue; } } $part1 = substr($line, 0, $start); $part2 = substr($line, $start + strlen($buffer) + 2); $line = $part1 . $value . $part2; $j += strlen($value) - (strlen($buffer) + 2); unset($start); unset($buffer); } } elseif (isset($start)) { // Check to see $char is a proper character (range: [A-Za-z0-9_./-]) // In Yapter 2.13b2, I've added the '/' char as well, to support inclusion // from Unix paths, like '../../foo.tpl' if (($char >= 'a' && $char <= 'z') || ($char >= '0' && $char <= '9') || ($char >= 'A' && $char <= 'Z') || ($char == '_') || ($char == '.') || ($char == '-') || ($char == '/')) { if (!empty($buffer)) $buffer .= $char; else $buffer = $char; } else { unset($start); unset($buffer); } } } $parsed[$i] = $line; } if (is_array($this->blox[$blockname]['parsed'])) { $this->blox[$blockname]['parsed'] = array_merge($this->blox[$blockname]['parsed'], $parsed); } else { //--- array cast mod -klp $this->blox[$blockname]['parsed'] = (array) $parsed; } return $this->blox[$blockname]['parsed']; } /* set(): assigns a value to a variabele inside curly brackets ('{' and '}') */ function set($varname, $value) { if (isset($value)) $this->vars[$varname] = $value; else $this->warning('Trying to set '.htmlspecialchars($varname).' to NULL. Variable not set.'); } /* setVars(): assigns values to variables for each element in the given array Contributed by: Raniz */ function setVars($variables) { if (!is_array($variables)) $this->error('Value passed to setVars is not an array.'); foreach($variables as $varname => $value) $this->vars[$varname] = $value; } /* setFile(): assigns the contents of a file to a variabele inside curly brackets ('{' and '}') */ function setFile($varname, $filename) { if (!file_exists($filename)) $this->error('Cannot open file "'.htmlspecialchars($filename).'" for inclusion in "'.htmlspecialchars($varname).'".'); $value = implode('', file($filename)); $this->set($varname, $value); } /* getVar(): returns the value of the 'varname' variable */ function getVar($varname) { if ($this->vars[$varname]) return $this->vars[$varname]; else return false; } /* getBlock(): returns the content of the 'blockname' block */ function getBlockContent($blockname) { if ($this->$blox[$blockname]['content']) return @implode('', $this->$blox[$blockname]['content']); else return false; } /* replace(): replaces the content of one block by another */ function replace($block, $byblock) { if (!isset($this->blox[$block])) $this->error('Block "'.htmlspecialchars($block).'" does not exist.'); if (!isset($this->blox[$byblock])) $this->error('Block "'.htmlspecialchars($block).'" does not exist.'); $this->blox[$block]['content'] = $this->blox[$byblock]['content']; $this->blox[$block]['numlines'] = $this->blox[$byblock]['numlines']; } /* hide(): hides all the contents of the given block */ function hide($block) { if (!isset($this->blox[$block])) $this->error('Block "'.htmlspecialchars($block).'" does not exist.'); $this->blox[$block]['content'] = array(); $this->blox[$block]['numlines'] = 0; } /* clear(): resets the parsed data to an empty string again and defines the block as 'unparsed' */ function clear($blockname) { if (!isset($this->blox[$blockname])) $this->error('Block "'.htmlspecialchars($blockname).'" does not exist.'); $this->blox[$blockname]['parsed'] = ''; unset($this->vars[$blockname]); // often, a variabele is set whenever a block should be discarded... // ...now reset such a variable to make sure the block is not overriden } /* getContents(): gets the final contents to be outputted on the screen */ function getContents($blockname = '') { if ($blockname == '') $blockname = $this->_ROOT; $parsed = $this->blox[$blockname]['parsed']; if ($parsed) return implode('', $parsed); else return false; } /* spit(): ouputs contents to screen */ function spit() { echo $this->getContents(); } function getmicrotime() { /* I got this getmicrotime()-function from the PHP.net website, but it seems to be buggy, while it sometimes displays a negative execution time when you substract the current time with the starting time of the script... I only noticed it at my Windows localhost machine, not on *nix servers. Is anybody familiar with this behaviour? Any information about this is welcome at nvie@users.sourceforge.net for your co-operation. */ list($usec, $sec) = explode(' ', microtime()); return ((float)$usec + (float)$sec); } function execTime() { return round($this->getmicrotime() - $this->startTime, 5); } function executionTime() { echo "

\n\nThe execution time is ".$this->execTime()." seconds.
\n"; } } ?>