PHP Classes

File: AT.php

Recommend this page to a friend!
  Classes of Naoki Shima   avantemplate   AT.php   Download  
File: AT.php
Role: ???
Content type: text/plain
Description: AvanTemplate Ver. 1.2.2 stable
Class: avantemplate
Author: By
Last change:
Date: 21 years ago
Size: 21,441 bytes
 

Contents

Class file image Download
<?php /* vim: set expandtab tabstop=4 shiftwidth=4: */ // +----------------------------------------------------------------------+ // | PHP version 4.0 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Naoki Shima <naoki@avantexchange.com> | // | | // +----------------------------------------------------------------------+ // // $Id$ require_once 'PEAR.php'; /** * todo: * parse template once, store and use parsed template * php generated template support - use ob_* function * documentation * variable declaration * error code CONSTANTS * error code to err text mapping * ALT BLOCK support for multi-depth loop * error handling * argument checking * example * Utilize Cache from PEAR */ define('ALT', 'ALT'); define('END', '_END'); define('START', '_START'); class AvanTemplate extends PEAR { // {{{ properties /** * location or directory where template files reside * @var string * @access private */ var $_location; /** * contents of template file being parsed * @var string * @access private */ var $_working; /** * Which block to show, or hide * @var array * @access private */ var $_block; // }}} // {{{ constructor /** * Initialize variable used by this class * * @param string (optional) root directory of the template file(s) * defaults to the same directory of the calling php script * @param boolean (optional) if string is needed to be handled multi-byte * safe. defaults to false * @access public * @return void */ function AvanTemplate($dir = '', $multi_byte = false) { $this->_hide_unset = true; $this->_prepend = '[%'; $this->_append = '%]'; $this->_cs = array('BLOCK_','LOOP_'); $this->_idx = '1'; $this->_location = $dir; $this->_multi_byte = $multi_byte; $this->PEAR(); } // }}} // {{{ destructor /** * Does nothing right now * * @access public * @return void */ function _AvanTemplate() { $this->_PEAR(); } // }}} // {{{ showUnset() /** * Show unset entity of template in finished content * * @access public * @return void */ function showUnset() { $this->_hideUnset = false; } // }}} // {{{ hideBlock() /** * Hide named block from finished content * * @param string Name of the block to hide * @access public * @return void */ function hideBlock($name) { $this->_block[$name] = false; } // }}} // {{{ showBlock() /** * Show named block from finished content * * @param string Name of the block to show * @access public * @return void */ function showBlock($name) { $this->_block[$name] = true; } // }}} // {{{ _generateUniqueId() /** * Generate random unique number * * @access private * @return int */ function _generateUniqueId() { return $this->_idx++; } // }}} // {{{ _getParentName() /** * Find name of the Parent entity * * @param int ID of entity * @access private * @return string */ function _getParentName($id) { return $this->_parent_name[$id]; } // }}} // {{{ setChildValue() /** * Set value to the child of entity * * @param int Id of the parent entity * @param string Name of the entity * @param mixed Value to be set * @param boolean (optional) Whether to append the value to the existing * value or override * @access public * @return boolean TRUE for success and FALSE for fail */ function setChildValue($parent_id, $name, $value, $append = false) { if(!$this->_validateArray(&$value) && !$name) { return FALSE; } $id = $this->_generateUniqueId(); $parent_name = $this->_getParentName($parent_id); if($this->_argument[$parent_name][$parent_id][$name] && $append) { $this->_argument[$parent_name][$parent_id][$name][$id] = $value; } else { $this->_argument[$parent_name][$parent_id][$name] = array($id => $value); } return $id; } // }}} // {{{ setValue() /** * Set value for variable interporation * * @param : string name of the variable to replace * @param : mixed value to replace the variable * @param : boolean (optional) whether to replace or append the value * * @return: integer ID of the entry. False is returned when params * are invalid * @access: public */ function setValue($name, $value, $append = false) { $id = TRUE; $this->_validateArray(&$value); if($name && $value) { if(is_array($value)) { $id = $this->_generateUniqueId(); if($this->_argument[$name] && $append) { $this->_argument[$name][$id] = $value; } else { $this->_argument[$name] = array($id => $value); } $this->_parent_name[$id] = $name; } else { $this->_argument[$name] = $value; } return $id; } else { return FALSE; } } // }}} // {{{ setList() /** * under development * * * @return: void * @access: public */ function setList($name,$list) { if($name && is_array($list)) { $this->_argument[$name] = $list; } } // }}} // {{{ setList() /* * under development */ function setValues($list) { if(is_array($list)) { foreach($list AS $key => $value) { $this->setValue($key,$value); } } } // }}} function setAppend($new) { $old = $this->_append; $this->_append = $new; return $old; } function setPrepend($new) { $old = $this->_prepend; $this->_prepend = $new; return $old; } function format($file, $vals = '') { $is_vals = $this->_validateArray(&$vals); if($this->_argument) { if($is_vals) { // merge them if both exists $this->_argument = array_merge_recursive($vals,$this->_argument); } } elseif(!$is_vals) { // none set, so raise error //return $this->raiseError($errstr, $errno); return; } else { // only $vals exists, then assign it to $this->_argument $this->_argument = $vals; } $this->_loadTemplate($file); $this->_loadExternalTemplate(); $this->_apply(); $this->_updateContents(); return $this->_getContents(); } /* * Cast parameter $val to array if it is an object, and then checks if * $val is an array. If it is not, returns FALSE. * Otherwise, this returns TRUE; */ function _validateArray(&$val) { if(is_object($val)) { $val = (array) $val; } if(is_array($val)) { return true; } else { return FALSE; } } /** * */ function _split($string, $prepend, $append, $offset = '0') { $length = $this->_strlen($prepend); $append_length = $this->_strlen($append); if($pos = $this->_strpos($string,$prepend,$offset)){ $result['head'] = $this->_substr($string, $start, $pos); $end = $pos+$length; $pos = $this->_strpos($string, $append, $pos); $result['inside'] = $this->_substr($string, $end ,($pos-$end)); $end = $pos+$append_length; $result['tail'] = $this->_substr($string, $end); $result['pos'] = $end; return $result; } return FALSE; } /** * Look for include statement in template file and substitute * include statement with the contents of template file specified. * * @return void * @access private */ function _loadExternalTemplate() { $string = $this->_working; // load file whose name specified in template $prepend = $this->_prepend.'INCLUDE_'; while($result = $this->_split($string,$prepend,$this->_append,$offset)){ $offset = $result['pos']; $tmp = $this->_readFile($this->_location.$result['inside']); $string = $result['head'].$tmp.$result['tail']; } // load file whose name specified by includeFile() if($this->_includeFiles) { foreach($this->_includeFiles AS $handle => $name) { $needle = $this->_prepend.'INCLUDE:'.$handle.$this->_append; $length = $this->_strlen($needle); while($pos = $this->_strpos($string,$needle)){ $tmp = $this->_readFile($this->_location.$name); $string = $this->_substr($string,0,$pos).$tmp.$this->_substr($string,($pos+$length)); } } } $this->_setWorking($string); } /** * Update contents(result) with processed template. * Final processing is done in this function. * * @return void * @access private */ function _updateContents() { if($this->_hide_unset){ $this->_hideUnsetEntity(); } $this->_setContents($this->_working); } function _getAltBlock($string) { $alt = $this->_prepend.ALT.$this->_append; $alt_length = $this->_strlen($alt); if($alt_pos = $this->_strpos($string,$alt)) { $alt_start = $alt_pos + $alt_length; return $this->_substr($string,$alt_start); } return FALSE; } function _hideUnsetEntity() { $string = $this->_working; $append = START.$this->_append; foreach($this->_cs AS $val) { $prepend = $this->_prepend.$val; while($tmp = $this->_split($string,$prepend,$append)){ $name = $tmp['inside']; //name of block $needle = $prepend.$name.END.$this->_append; $pos = $this->_strpos($string,$needle,$tmp['pos']); $offset = $pos + $this->_strlen($needle); $str = $this->_substr($string,$tmp['pos'],($pos-$tmp['pos'])); $alt_str = $this->_getAltBlock($str); $string = $tmp['head'].$alt_str.$this->_substr($string, $offset); } } // end foreach $offset = 0; while($pos = $this->_strpos($string, $this->_prepend, $offset)) { $head = $this->_substr($string, 0, $pos); $pos = $this->_strpos($string, $this->_append, $pos); $length = $this->_strlen($this->_append); $tail = substr($string, ($pos+$length)); $offset = $pos; $string = $head.$tail; } $this->_setWorking($string); } function _apply() { if(is_array($this->_block)) { foreach($this->_block AS $key => $value) { $this->_formatBlock($key,$value); } } foreach($this->_argument AS $key => $value) { if(is_array($value)) { $this->_setWorking($this->_formatLoop($key,$value)); } else { $needle = $this->_prepend.$key.$this->_append; $this->_setWorking($this->_strReplace($needle, $value)); } } } /** * Process BLOCK * * @param : string Name of the Block * @param : boolean Whether to show or hide the BLOCK * * @return: void * @access: private */ function _formatBlock($name, $is_shown) { while($arr = $this->_getControlStructure($name,'BLOCK')){ if($is_shown) { $arr['inside'] = $this->_stripAltBlock($arr['inside']); } else { $arr['inside'] = $this->_getAltBlock($arr['inside']); } $this->_setWorking($arr['head'].$arr['inside'].$arr['tail']); } } /** * Process LOOP * * @param : string Name of the loop * @param : mixed Value to replace(interporate) the variable * @param : string (optional) string in which it looks for LOOP * * @return: string Processed string * @access: private */ function _formatLoop($item, $vals, $string='') { if(!$string) { $string = $this->_working; } while($arr = $this->_getControlStructure($item,'LOOP',$string)){ unset($result); foreach($vals AS $val) { if($this->_validateArray(&$val)) { unset($tmp); foreach($val AS $key => $value) { if(!$tmp) { $tmp = $arr['inside']; } if(is_array($value)) { $tmp = $this->_formatLoop($item.'.'.$key,$value,$tmp); continue 1; } $needle = $this->_prepend.$item.'.'.$key.$this->_append; $tmp = $this->_stripAltBlock($tmp); $tmp = $this->_strReplace($needle,$value,$tmp); } $result .= $tmp; } } $string = $arr['head'].$result.$arr['tail']; } return $string; } /** * Strip ALT BLOCK from passed string * @access: private */ function _stripAltBlock($string) { $alt = $this->_prepend.ALT.$this->_append; $pos = $this->_strrpos($string, END.$this->_append); if(($alt_pos = $this->_strrpos($string,$alt)) && (!$pos || ($pos && ($pos < $alt_pos)))) { return $this->_substr($string,0,$alt_pos); } return $string; } function _setWorking($val) { $old = $this->_working; $this->_working = $val; return $old; } function _getControlStructure($item,$type,$string = '') { if(!$string) { $string = $this->_working; } $needle = $this->_prepend.$type.'_'.$item.START.$this->_append; $length = $this->_strlen($needle); if($pos = $this->_strpos($string,$needle)){ $result['head'] = $this->_substr($string, 0, $pos); $end = $pos+$length; $needle = $this->_prepend.$type.'_'.$item.END.$this->_append; $pos = $this->_strpos($string, $needle, $pos); $result['inside'] = $this->_substr($string, $end ,($pos-$end)); $end = $pos+$this->_strlen($needle); $result['tail'] = $this->_substr($string, $end); return $result; } else { return FALSE; } } /** * Get contents stored in the object * * @access private * @return string */ function _getContents() { if(!$this->_contents) { return; // return $this->raiseError($errstr, $errno); } return $this->_contents; } /** * Wrapper function for str_replace(). Multi-byte safe. * Exactly the same API as str_replace() * Refer manual for str_replace() * @param mixed * @param mixed * @param mixed * * @access private * @return mixed */ function _strReplace($search, $replace, $subject = '') { if(!$subject) { $subject = $this->_working; } if(!$this->_multi_byte) { return str_replace($search, $replace, $subject); } if(is_array($subject)) { foreach($subject AS $sub) { if(is_array($search)) { for($i=0; count($search) >$i; $i++) { $s = $search[$i]; if(is_array($replace)) { $r = $replace[$i]; } else { $r = $replace; } $result[] = $this->_strReplaceLtd($s,$r,$sub); } } else { $result[] = $this->_strReplaceLtd($search,$replace,$sub); } } } else { $result = $this->_strReplaceLtd($search,$replace,$subject); } return $result; } /* * only used by _strReplace * @access private */ function _strReplaceLtd($search, $replace, $subject) { $offset = 0; if(!($length = @mb_strlen($search))){ return; // return $this->raiseError($errstr, $errno); } while($pos = @mb_strpos($subject,$search,$offset)) { $end = $pos+$length; $subject = mb_substr($subject, 0, $pos).$replace .$this->_substr($subject,$end); $offset = $end; } return $subject; } //wrapper function -- for multi_byte function _strpos($string,$needle,$offset = 0) { if($this->_multi_byte) { return @mb_strpos($string, $needle, $offset); } return @strpos($string, $needle, $offset); } /** * Wraps strrpos function so that it calls mb_strrpos when multi-byte is * specified and handle string as its needle. PHP native function only * handle single character as needle. * * @param : string Heystack * @param : string Needle * * @return: int * @access: private */ function _strrpos($heystack, $needle) { if($this->_multi_byte) { return @mb_strrpos($heystack, $needle); } $tmp = 0; while($pos = strpos($heystack, $needle, $tmp)) { $tmp = $pos + 1; } return ($tmp - 1); } //wrapper function -- for multi_byte function _strlen($value) { if($this->_multi_byte) { return @mb_strlen($value); } return strlen($value); } //wrapper function -- for multi_byte function _substr($string, $start, $length = '') { if($this->_multi_byte) { if($length) { return mb_substr($string,$start,$length); } return mb_substr($string,$start); } else { if($length) { return substr($string,$start,$length); } return substr($string,$start); } } function _loadTemplate($file) { $this->_template = $this->_readFile($this->_location.$file); $this->_setWorking($this->_template); } function _readFile($file) { $fp = fopen($file, 'r-'); if(!is_resource($fp)) { return; } while($data = fread($fp, 2048)) { $contents .= $data; } fclose($fp); return $contents; } function _setContents($val) { $old = $this->_contents; $this->_contents = $val; return $old; } function includeFile($handle, $filename) { $this->_includeFiles[$handle] = $filename; } } ?>