PHP Classes

File: include/core/WATemplate.lib

Recommend this page to a friend!
  Classes of philippe thomassigny   Dominion   include/core/WATemplate.lib   Download  
File: include/core/WATemplate.lib
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Dominion
Build and execute portable SQL queries
Author: By
Last change:
Date: 12 years ago
Size: 18,217 bytes
 

Contents

Class file image Download
<?php /* WATemplate.lib, DomCore, the WebAbility(r) Core System Contains the basic class to compile an HTML/XML Template file to a PHP array/object (c) 2008-2012 Philippe Thomassigny This file is part of DomCore DomCore is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. DomCore is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DomCore. If not, see <http://www.gnu.org/licenses/>. */ /* @UML_Box |------------------------------------------------------------------| | WATemplate: Template compiler | |------------------------------------------------------------------| | - $template: string | | - $metaelements: array | | - $subtemplate: array | | - $elements: array | |------------------------------------------------------------------| | + new WATemplate($data: mixed) | | + getTemplate($id: string): WATemplate | | + getTemplates(): array | | + getClone(): WATemplate | | + metaElements($elements: array, $reverse: boolean): void | | + addElement($element: string, $value: string, $reverse: boolean): void| | + addElements($elements: array, $reverse: boolean): void | | + resolve(): string | | - dumpelements($elements: array, $level: int, $value: string): string| | - createkey(): string | | - compile($data: string, $interprete: boolean): void | | - separateSubTemplate($text: string, $itemnumber: int, $ID: string, $calcsubtemplates: boolean): array| | - getMetaElements($data): array | | # serial($data: array): void | | # unserial($data: array): void | | + __toString(): string | |------------------------------------------------------------------| @End_UML_Box */ // class to compile and keep a Template string /* A template is: %-- comments --% xml/html code %%SUBTEMPLATE(id)%% xml/html code %%SUBTEMPLATE(id)%% xml/html code indented %%ENDSUBTEMPLATE%% xml/html code %%ENDSUBTEMPLATE%% Meta elements: ??xx?? if/then/else @@xx@@ loops &&xx&& references !!xx!! debug */ // Template keywords __XX__ class WATemplate extends WAClass { private $template = ''; private $metaelements = array(); private $subtemplates = array(); private $elements = array(); public function __construct($data) { parent::__construct(); if (is_string($data)) { $this->compile($data); } else if (is_array($data)) { if (isset($data['template']) && is_string($data['template'])) $this->template = $data['template']; if (isset($data['metaelements']) && is_array($data['metaelements'])) $this->metaelements = $data['metaelements']; if (isset($data['subtemplates']) && is_array($data['subtemplates'])) $this->subtemplates = $data['subtemplates']; } } public function getTemplate($name = null) { if ($name === null) return $this->template; if (!isset($this->subtemplates[$name])) return null; if (is_string($this->subtemplates[$name])) return $this->subtemplates[$this->subtemplates[$name]]->getClone(); return $this->subtemplates[$name]->getClone(); } public function getTemplates() { return $this->subtemplates; } public function getClone() { $subt = array(); foreach($this->subtemplates as $id => $st) { if ($st instanceof WATemplate) $subt[$id] = $st->getClone(); else $subt[$id] = $st; } return new WATemplate(array('template' => $this->template, 'metaelements' => $this->metaelements, 'subtemplates' => $subt)); } public function metaElements($elements, $reverse = false) { foreach($this->metaelements as $e) { $done = false; $kval = $val = ''; if ($e[0] == '!') // it's a DEBUG ELEMENT { $kval = $e[1]; if ($e[2] == 'dump') { $tmp = $this->dumpelements($elements, 0, true); } if ($e[2] == 'list') { $tmp = $this->dumpelements($elements, 0, false); } $val = $tmp; } if ($e[0] == '&') // it's a SIMPLE SUBTEMPLATE { $kval = $e[1]; $entry = $e[2]; $id = $e[3]; $tmp = $this->getTemplate($id); if ($tmp && isset($elements[$entry])) { $tmp->metaElements(array_merge($elements, is_array($elements[$entry])?$elements[$entry]:array())); } $val = $tmp; } if ($e[0] == '@') // it's a LOOP { $kval = $e[1]; $entry = $e[2]; $id = $e[3]; $check = isset($e[4])?$e[4]:null; if (!isset($elements[$entry]) || !is_array($elements[$entry]) || sizeof($elements[$entry]) == 0) { $val = $this->getTemplate($id.'.none'); } else { $alt = false; foreach($elements[$entry] as $key => $values) { $tmp = $this->getTemplate($id.'.key.'.$key); if (!$tmp && isset($values[$check])) $tmp = $this->getTemplate($id.'.sel.'.$values[$check]); if (!$tmp && $alt) $tmp = $this->getTemplate($id.'.loopalt'); if (!$tmp) $tmp = $this->getTemplate($id.'.loop'); if (!$tmp) $tmp = $this->getTemplate($id); if ($tmp) { $tmp->metaElements(array_merge($elements, is_array($values)?$values:array())); if (!isset($this->elements[$kval])) $this->elements[$kval] = array(); if ($reverse) array_unshift($this->elements[$kval], $tmp); else $this->elements[$kval][] = $tmp; } $alt = !$alt; } $done = true; } } elseif ($e[0] == '?') // it's a IF/CASE/NONE { $kval = $e[1]; $entry = $e[2]; $id = $e[3]; $checkvalue = isset($elements[$entry])?$elements[$entry]:null; if (!$checkvalue) $tmp = $this->getTemplate($id.'.none'); else { $tmp = $this->getTemplate($id.'.'.$checkvalue); if (!$tmp) $tmp = $this->getTemplate($id); } if ($tmp && isset($elements[$entry])) $tmp->metaElements(array_merge($elements, is_array($elements[$entry])?$elements[$entry]:array())); $val = $tmp; } if (!$done) { if (!isset($this->elements[$kval])) $this->elements[$kval] = array(); if ($reverse) array_unshift($this->elements[$kval], $val); else $this->elements[$kval][] = $val; } } if (!$elements || !is_array($elements)) return; foreach($elements as $k => $e) { if (is_array($e)) // we only want normal values. arrays and objects are interpreted in another way continue; if (!isset($this->elements[$k])) $this->elements[$k] = array(); if ($reverse) array_unshift($this->elements[$k], $e); else $this->elements[$k][] = $e; } } public function addElement($element, $value, $reverse = false) { if (!$this->elements) $this->elements = array(); if (!is_array($element)) { $element = array($element); $value = array($value); } foreach($element as $k => $e) { if (!isset($this->elements[$e])) $this->elements[$e] = array(); if ($reverse) { if (is_array($value[$k])) foreach($value[$k] as $v) array_unshift($this->elements[$e], $v); else array_unshift($this->elements[$e], $value[$k]); } else { if (is_array($value[$k])) foreach($value[$k] as $v) $this->elements[$e][] = $v; else $this->elements[$e][] = $value[$k]; } } } public function addElements($elements, $reverse = false) { $this->metaElements($elements, $reverse); } public function resolve() { $temp = $this->template; // 1. parse the elements values if (!$this->elements) return $temp; $elementstmp = array(); $elementstxt = array(); foreach ($this->elements as $k => $el) { $value1 = ""; $hastemplate = false; foreach ($el as $k1 => $el1) { if ($el1 instanceof WATemplate) { $value1 .= $el1->resolve(); $hastemplate = true; } else $value1 .= $el1; } if ($hastemplate) $elementstmp[$k] = $value1; else $elementstxt[$k] = $value1; } // PASS 1: RESOLVE ALL SUB TEMPLATES $regin = array(); $regout = array(); foreach ($elementstmp as $k => $v) { $k = str_replace("?", "\\?", $k); $regin[] = "/".$k."/s"; $out = str_replace("\\", "\\\\", $v); $out = str_replace("$", "\\$", $out); $regout[] = $out; } $temp = preg_replace($regin, $regout, $temp); // PASS 2: REPLACE ALL TEXT $regin = array(); $regout = array(); foreach ($elementstxt as $k => $v) { $k = str_replace("?", "\\?", $k); $regin[] = "/".$k."/s"; $out = str_replace("\\", "\\\\", $v); $out = str_replace("$", "\\$", $out); $regout[] = $out; } $temp = preg_replace($regin, $regout, $temp); return $temp; } // ===================== PRIVATE COMPILER ============================== // meta element !! to dump the variables private function dumpelements($elements, $level, $value = false) { $txt = ''; if (is_array($elements)) { foreach($elements as $k => $v) { $txt .= str_repeat('&nbsp;&nbsp;', $level) . substr($k, 0, 1).'<span></span>'.substr($k, 1); if ($value) { $txt .= ' :: '; if (is_array($v)) { $txt .= "<br />"; $txt .= $this->dumpelements($v, $level + 1, $value); } else if (is_object($v)) $txt .= "{Object}<br />"; else $txt .= "$v<br />"; } else { $txt .= "<br />"; if (is_array($v)) $txt .= $this->dumpelements($v, $level + 1, $value); } } } return $txt; } // ===================== PRIVATE COMPILER ============================== // 8 a-z random key private function createkey() { srand((double)microtime()*1000000); $key = ''; for ($i=0;$i<8;$i++) $key .= chr(65+rand()%26); return $key; } private function compile($data, $interprete = true) { if ($interprete) { $data = rawurlencode($data); // ------------------------ // First remove all the comments $elem = array(); $regelement = '/%25--(.*?)--%25'. '/s'; preg_match_all($regelement, $data, $resultelement); if (!empty($resultelement[0])) { reset($resultelement); while (list($k, $E) = each($resultelement[0])) { // we ignore the comments $pos = strpos($data, $E); $data = substr_replace($data, '', $pos, strlen($E)); } } // Generate a unique key for our template $badkey = '1'; while ($badkey) { $ID = $this->createkey(); // check that key IS NOT INCLUDED into the template to avoid duplicate problems $badkey = strstr($data, $ID); } // Parse the sub templates $reg = '/%25%25(SUBTEMPLATE)%28(.*?)%29%25%25(%0D){0,1}(%0A){0,1}(.*?)%25%25ENDSUBTEMPLATE%25%25(%0D){0,1}(%0A){0,1}/s'; $regin = '/%25%25(SUBTEMPLATE)%28(.*?)%29%25%25(%0D){0,1}(%0A){0,1}(.*?)$/s'; $loop = true; $subt = array(); $itemnumber = 1; while($loop) { unset($result); preg_match_all($reg, $data, $result); if(!empty($result[0])) { while(list($k, $E) = each($result[0])) { $resultin = $result[5][$k]; $resultout = $result[0][$k]; $resulttemp = $result[2][$k]; $loopin = true; while ($loopin) { unset($subresult); preg_match($regin, $resultin, $subresult); if (!empty($subresult[0])) { // there are nested %%SUTEMP $resultin = $subresult[5]; $resultout = $subresult[0]; $resulttemp = $subresult[2]; } else $loopin = false; } if($result[5][$k] != $resultin) { $resultout .= '%25%25ENDSUBTEMPLATE%25%25'; } $pos = strpos($data, $resultout); $data = substr_replace($data, '___'.$ID.$itemnumber.'___', $pos, strlen($resultout)); $subt[$itemnumber++] = array(rawurldecode($resulttemp), rawurldecode($resultin)); } } else $loop = false; } $data = rawurldecode($data); $tmp = $this->separateSubTemplate($data, $itemnumber, $ID, $subt); $this->template = $tmp['template']; $this->subtemplates = $tmp['subtemplates']; $this->metaelements = $this->getMetaElements($tmp['template']); } else { $this->template = $data; $this->subtemplates = array(); $this->metaelements = $this->getMetaElements($data); } } private function separateSubTemplate($text, $itemnumber, $ID, $calcsubtemplates) { $subtemplates = array(); for ($i = 1; $i < $itemnumber; $i++) { if (strstr($text, '___'.$ID.$i.'___')) { // 1. Search of subtemplates of this one $subt = $this->separateSubTemplate($calcsubtemplates[$i][1], $itemnumber, $ID, $calcsubtemplates); // 2. replace text $pos = strpos($text, '___'.$ID.$i.'___'); $text = substr_replace($text, '', $pos, strlen('___'.$ID.$i.'___')); // 3. create Template object if (strpos($calcsubtemplates[$i][0], '|') !== false) // various subtemplates in the ID { $ids = explode('|', $calcsubtemplates[$i][0]); $firstid = null; foreach($ids as $id) { if (trim($id) == '') continue; if (!$firstid) { $firstid = $id; $subtemplates[$id] = new WATemplate($subt); } else { $subtemplates[$id] = $firstid; } } } else $subtemplates[$calcsubtemplates[$i][0]] = new WATemplate($subt); } } $template = array( 'template' => $text, 'subtemplates' => $subtemplates, 'metaelements' => $this->getMetaElements($text) ); return $template; } private function getMetaElements($data) { $data = rawurlencode($data); // separate meta elements $regelement = '/'. '%3F(%3F)(.*?)%3F%3F|'. // meta element ??xx?? '%40(%40)(.*?)%40%40|'. // meta element @@xx@@ '%26(%26)(.*?)%26%26|'. // meta element &&xx&& '%21(%21)(.*?)%21%21|'. // meta element !!xx!! debug '/s'; preg_match_all($regelement, $data, $resultelement); $metaelements = array(); if (!empty($resultelement[0])) { reset($resultelement); while (list($k, $E) = each($resultelement[0])) { if ($resultelement[2][$k]) { $xme = explode(':', rawurldecode($resultelement[2][$k])); if (!isset($xme[1])) $xme[1] = $xme[0]; $metaelements[] = array(rawurldecode($resultelement[1][$k]), rawurldecode($resultelement[0][$k]), $xme[0], $xme[1]); } elseif ($resultelement[4][$k]) { $xme = explode(':', rawurldecode($resultelement[4][$k])); if (!isset($xme[1])) $xme[1] = $xme[0]; if (!isset($xme[2])) $xme[2] = null; $metaelements[] = array(rawurldecode($resultelement[3][$k]), rawurldecode($resultelement[0][$k]), $xme[0], $xme[1], $xme[2]); } elseif ($resultelement[6][$k]) { $xme = explode(':', rawurldecode($resultelement[6][$k])); if (!isset($xme[1])) $xme[1] = $xme[0]; if (!isset($xme[2])) $xme[2] = null; $metaelements[] = array(rawurldecode($resultelement[5][$k]), rawurldecode($resultelement[0][$k]), $xme[0], $xme[1], $xme[2]); } elseif ($resultelement[8][$k]) { $xme = rawurldecode($resultelement[8][$k]); $metaelements[] = array(rawurldecode($resultelement[7][$k]), rawurldecode($resultelement[0][$k]), $xme); } } } return $metaelements; } protected function serial(&$data) { $data['template'] = $this->template; $data['metaelements'] = $this->metaelements; $data['subtemplates'] = $this->subtemplates; } protected function unserial($data) { $this->template = $data['template']; $this->metaelements = $data['metaelements']; $this->subtemplates = $data['subtemplates']; } public function __toString() { return $this->resolve(); } } ?>