** * OUTLINE * -------- * Basically, this is a theme system. You open a theme using: * * $var = new theme("themes/dir/theme.thm"); * $var->block("block"); * $var->set("block","variable","value"); * $var->parse("block"); * $var->parse(); * * Then you can do whatever with the $var->output or use the $var->write(); * function to echo the output of the theme. */ class theme { var $output; // raw data of the theme file, messed with like crazy var $thm; // not quite sure what it's for! haha! var $blocks; // an array of blocks being used var $blocknames; // block names for cleaning later var $error_count = 0; // error count, incremented with each error var $debug = false; // turn debug on or off var $errors; // error report // boolean response if the themename is allowed or not function is_valid($val) { if (preg_match("/^[a-zA-Z0-9\_\-]+$/",$val)) { return 1; // all characters are alphanumeric + underscore, yay } else { return 0; // i think a robot tried to trick you .. AGAIN } } function error($message,$die = 0) { $this->error_count++; // update error count $this->errors .= "- $message\n"; /* if ($die) { // output report die("
".$this->errors.""); } */ } // select a block from the theme and load it into $this->blocks[$section] function block($section,$autoparse = false) { // is it a valid theme? if ($this->is_valid($section)) { if (preg_match("/\[{$section}\](.*?)\[\/{$section}\]/s",$this->output,$tmp)) { // found the block, loading it into the $this->blocks variable $this->blocks["$section"] = $tmp[1]; // If autoparse is toggled on, parse this block automatically.. if ($autoparse) $this->block_parse($section); } elseif ($this->debug) $this->error("Block ($section) not found in theme. [Warning]"); } elseif ($this->debug) $this->error("Invalid block name ($section)."); } // place data in the block variable function block_var($section,$variables,$values,$autoparse = false) { if (is_array($variables)) { // Function was called using arrays, meaning that all the values will be the // same or there will be an array to correspond accordingly.. foreach($variables as $key => $variable) if (is_array($values)) $this->block_var($section,$variable,$values[$key]); // $val is an array, corresponding values.. else $this->block_var($section,$variable,$values); // All values are the same.. // All array values have been completed, autoparse? if ($autoparse) // Autoparse makes it automatically parse after the values have been set.. $this->block_parse($section); } else { if ($this->is_valid($variables)) { if (empty($this->blocks[$section])) // block does not exist, make it $this->block($section); if (preg_match("/\{{$variables}\}/",$this->blocks[$section])) { // replace a variable in a block $this->blocks[$section] = preg_replace("/\{{$variables}\}/",$values,$this->blocks["$section"]); if ($autoparse) $this->block_parse($section); } elseif ($this->debug) $this->error("Variable ($variables) not found in block ($section) [Warning].",0); } elseif ($this->debug) // invalid themename $this->error("Invalid variable name ($variables)."); } } /* block_parse($section) * * Check the $blocks variable for things to put int */ function block_parse($section) { // if it does not exist, create it with no variable values if (empty($this->blocks[$section])) $this->block($section); if (count($this->blocks)) { // reverse order so that shit gets parsed from deepest to shallowest krsort($this->blocks); // pattern for the blocks (eg. [block].*?[/block] to be replaced $parse_pattern = "/\[{$section}\](.*?)\[\/{$section}\]/s"; $parse_output = "{$this->blocks[$section]}\\0"; $block_found = 0; // not found in blocks foreach ($this->blocks as $k => $v) { if (!$block_found) { // try to find the pattern in any of the blocks if (preg_match($parse_pattern,$this->blocks[$k])) { $block_found = 1; // search the other blocks for this block to parse it out $this->blocks[$k] = preg_replace($parse_pattern,$parse_output,$this->blocks[$k]); } } } // it wasn't in other blocks, therefore, it's only in the output if (!$block_found) $this->output = preg_replace($parse_pattern,$parse_output,$this->output); unset($this->blocks[$section]); // return order to near-normality (is coding ever normal?) krsort($this->blocks); } else { // empty blocks var $this->error("There are no unparsed blocks during an attempt ($section). [Warning]"); } } /* block_replace($block,$replace) * * Replace a block placeholder for objects like flash. * Not really efficient, but might be useful sometime down the road. */ function block_replace($block,$replace) { // reverse order so that shit gets parsed from deepest to shallowest krsort($this->blocks); // pattern for the replace block [[block]] $parse_pattern = "/\[\[{$block}\]\]/"; $parse_output = "{$replace}\\0"; $block_found = 0; // not found in blocks foreach ($this->blocks as $k => $v) { if (!$block_found) { // try to find the pattern in any of the blocks if (preg_match($parse_pattern,$this->blocks[$k])) { $block_found = 1; // search the other blocks for this block to parse it out $this->blocks[$k] = preg_replace($parse_pattern,$parse_output,$this->blocks[$k]); } } } // it wasn't in other blocks, therefore, it's only in the output if (!$block_found) $this->output = preg_replace($parse_pattern,$parse_output,$this->output); // return order to near-normality (is coding ever normal?) krsort($this->blocks); } // parse output for finished job function parse($section = "") { if ($section != "") { $this->block_parse($section); return; } if (!empty($this->output)) { // replace out the variable blocks $replace = array( "/\<\?php(.*?)\?\>/s", // php code in the theme /s", // same as above "/\{\w+\}/", // variable placeholders {variable} "/\[\[[a-zA-Z0-9\_\-]+?\]\]/", // block_replaceholders [[replace]] "/\/s", // comments ); foreach($this->blocknames as $k => $v) { // add all the block names to the $replace array $replace[] = "/\[{$v}\](.*?)\[\/{$v}\]/s"; } $this->output = preg_replace($replace,"",$this->output); } if ($this->debug) { // if there were errors, put them at the beginning if ($this->errors) $this->output = "
This website is currently in debug mode set by the webmaster.\n--------------------------------------------------------------------\n{$this->errors}".$this->output;
else
$this->output = "This website is currently in debug mode set by the webmaster.".$this->output; } } // output $this->output function output() { // finalized command for output echo $this->output; } function write() { echo $this->output; } function __construct($src,$autoparse = false) { $src = str_replace("//","/",$src); if (file_exists($src)) { $file = fopen($src,"r"); $this->output = ""; while (!feof($file)) $this->output .= fgets($file); fclose($file); $this->error("Successfully loaded theme (\"$src\")!"); // file loaded, get a list of all blocks preg_match_all("/\[([a-zA-Z\_]*?)\]/",$this->output,$tmp); $this->blocknames = $tmp[1]; if ($autoparse) { $this->parse(); } } else echo ("Theme (\"$src\") could not be found."); } // OLDER VERSIONS OF PHP WILL NOT AUTOMATICALLY USE __CONSTRUCT, USE THIS TO COUNTERACT IT function theme($src,$autoparse = false) { $this->__construct($src,$autoparse); } /* Shortcut functions */ function set($section,$variables,$values,$autoparse = false) { $this->block_var($section,$variables,$values,$autoparse); } function variable($section,$variables,$values,$autoparse = false) { $this->block_var($section,$variables,$values,$autoparse); } } ?>