[ Index ] |
|
Code source de Joomla 1.0.13 |
1 <?PHP 2 /** 3 * patTemplate 4 * 5 * $Id: patTemplate.php 1546 2005-12-23 07:01:01Z eddieajau $ 6 * 7 * powerful templating engine 8 * 9 * @version 3.1.0 10 * @package patTemplate 11 * @author Stephan Schmidt <schst@php.net> 12 * @license LGPL 13 * @link http://www.php-tools.net 14 */ 15 16 // ** Following line Joomla! specific ** 17 require_once( dirname( __FILE__ ) . '/patErrorManager.php' ); 18 19 /** 20 * template already exists 21 */ 22 define( 'PATTEMPLATE_ERROR_TEMPLATE_EXISTS', 5010 ); 23 24 /** 25 * template does not exist 26 */ 27 define ( 'PATTEMPLATE_WARNING_NO_TEMPLATE', 5011 ); 28 29 /** 30 * unknown type 31 */ 32 define ( 'PATTEMPLATE_WARNING_UNKNOWN_TYPE', 5012 ); 33 34 /** 35 * base class for module could not be found 36 */ 37 define( 'PATTEMPLATE_ERROR_BASECLASS_NOT_FOUND', 5050 ); 38 39 /** 40 * module could not be found 41 */ 42 define( 'PATTEMPLATE_ERROR_MODULE_NOT_FOUND', 5051 ); 43 44 /** 45 * array expected 46 */ 47 define( 'PATTEMPLATE_ERROR_EXPECTED_ARRAY', 5052 ); 48 49 /** 50 * No input 51 */ 52 define( 'PATTEMPLATE_ERROR_NO_INPUT', 6000 ); 53 /** 54 * Recursion 55 */ 56 define( 'PATTEMPLATE_ERROR_RECURSION', 6010 ); 57 58 /** 59 * patTemplate 60 * 61 * powerful templating engine 62 * 63 * @version 3.1.0 64 * @package patTemplate 65 * @author Stephan Schmidt <schst@php.net> 66 * @license LGPL 67 * @link http://www.php-tools.net 68 */ 69 class patTemplate 70 { 71 /** 72 * standard system vars that identify pat tools 73 * @var array 74 */ 75 var $_systemVars = array( 76 'appName' => 'patTemplate', 77 'appVersion' => '3.1.0', 78 'author' => array( 79 'Stephan Schmidt <schst@php.net>' 80 ) 81 ); 82 83 /** 84 * default attributes for new templates 85 * @access private 86 * @var array 87 */ 88 var $_defaultAttributes = array( 89 'type' => 'standard', 90 'visibility' => 'visible', 91 'loop' => 1, 92 'unusedvars' => 'strip', 93 'whitespace' => 'keep', 94 'autoclear' => 'off', 95 'autoload' => 'on' 96 ); 97 98 /** 99 * options for patTemplate 100 * 101 * Currently the following options are implemented: 102 * - maintainBc defines, whether patTemplate should be backwards compatible. 103 * This means, that you may use 'default' and 'empty' for subtemplates. 104 * 105 * @access private 106 * @var array 107 */ 108 var $_options = array( 109 'startTag' => '{', 110 'endTag' => '}', 111 'root' => array('__default' => '.'), 112 'namespace' => 'patTemplate', 113 'maintainBc' => true, 114 'defaultFunction' => false 115 ); 116 117 /** 118 * start tag 119 * 120 * @access private 121 * @var string 122 */ 123 var $_startTag = '{'; 124 125 /** 126 * end tag 127 * 128 * @access private 129 * @var string 130 */ 131 var $_endTag = '}'; 132 133 /** 134 * loaded modules 135 * 136 * Modules are: 137 * - Readers 138 * - Caches 139 * - Variable modifiers 140 * - Filters 141 * 142 * @access private 143 * @var array 144 */ 145 var $_modules = array(); 146 147 /** 148 * directories, where modules can be stored 149 * @access private 150 * @var array 151 */ 152 var $_moduleDirs = array(); 153 154 /** 155 * stores all template names 156 * @access private 157 * @var array 158 */ 159 var $_templateList = array(); 160 161 /** 162 * stores all template data 163 * @access private 164 * @var array 165 */ 166 var $_templates = array(); 167 168 /** 169 * stores all global variables 170 * @access private 171 * @var array 172 */ 173 var $_globals = array(); 174 175 /** 176 * stores all local variables 177 * @access private 178 * @var array 179 */ 180 var $_vars = array(); 181 182 /** 183 * stores the name of the first template that has been 184 * found 185 * 186 * @access private 187 * @var string 188 */ 189 var $_root; 190 191 /** 192 * output filters that should be used 193 * 194 * @access private 195 * @var array 196 */ 197 var $_outputFilters = array(); 198 199 /** 200 * input filters that should be used 201 * 202 * @access private 203 * @var array 204 */ 205 var $_inputFilters = array(); 206 207 /** 208 * template cache, that should be used 209 * 210 * @access private 211 * @var array 212 */ 213 var $_tmplCache = null; 214 215 /** 216 * placeholders, that have been discovered 217 * 218 * @access private 219 * @var array 220 */ 221 var $_discoveredPlaceholders = array(); 222 223 /** 224 * Create a new patTemplate instance. 225 * 226 * The constructor accepts the type of the templates as sole parameter. 227 * You may choose one of: 228 * - html (default) 229 * - tex 230 * 231 * The type influences the tags you are using in your templates. 232 * 233 * @access public 234 * @param string type (either html or tex) 235 */ 236 function patTemplate( $type = 'html' ) 237 { 238 if( !defined( 'PATTEMPLATE_INCLUDE_PATH' ) ) { 239 define( 'PATTEMPLATE_INCLUDE_PATH', dirname( __FILE__ ) . '/patTemplate' ); 240 } 241 242 $this->setType( $type ); 243 } 244 245 /** 246 * sets an option 247 * 248 * Currently, the following options are supported 249 * - maintainBc (true|false) 250 * - namespace (string) 251 * 252 * @access public 253 * @param string option to set 254 * @param string value of the option 255 */ 256 function setOption($option, $value) 257 { 258 $this->_options[$option] = $value; 259 } 260 261 /** 262 * gets an option 263 * 264 * @access public 265 * @param string option to get 266 * @return mixed value of the option 267 */ 268 function getOption( $option ) 269 { 270 if (!isset($this->_options[$option])) { 271 return null; 272 } 273 return $this->_options[$option]; 274 } 275 276 /** 277 * sets name of directory where templates are stored 278 * 279 * @access public 280 * @param string dir where templates are stored 281 * @deprecated please use patTemplate::setRoot() instead 282 */ 283 function setBasedir($basedir) 284 { 285 $this->setRoot($basedir); 286 } 287 288 /** 289 * sets root base for the template 290 * 291 * The parameter depends on the reader you are using. 292 * 293 * @access public 294 * @param string root base of the templates 295 */ 296 function setRoot($root, $reader = '__default') 297 { 298 $this->_options['root'][$reader] = $root; 299 } 300 301 /** 302 * gets name of root base for the templates 303 * 304 * @access public 305 * @return mixed root base 306 */ 307 function getRoot($reader = '__default') 308 { 309 return $this->_options['root'][$reader]; 310 } 311 312 /** 313 * sets namespace of patTemplate tags 314 * 315 * If you want to use more than one namespace, you may set this to 316 * an array. All tags in these namespaces will be treated as patTemplate 317 * tags. 318 * 319 * @access public 320 * @param string|array namespace(s) 321 */ 322 function setNamespace($ns) 323 { 324 $this->_options['namespace'] = $ns; 325 } 326 327 /** 328 * gets namespace of patTemplate tags 329 * 330 * @access public 331 * @return string|array namespace(s) 332 */ 333 function getNamespace() 334 { 335 return $this->_options['namespace']; 336 } 337 338 /** 339 * set default attribute 340 * 341 * @access public 342 * @param string attribute name 343 * @param mixed attribute value 344 */ 345 function setDefaultAttribute( $name, $value ) 346 { 347 $this->_defaultAttributes[$name] = $value; 348 } 349 350 /** 351 * set default attributes 352 * 353 * @access public 354 * @param array attributes 355 */ 356 function setDefaultAttributes( $attributes ) 357 { 358 $this->_defaultAttributes = array_merge( $this->_defaultAttributes, $attributes ); 359 } 360 361 /** 362 * get default attributes 363 * 364 * @access public 365 * @return return default attributes 366 */ 367 function getDefaultAttributes() 368 { 369 return $this->_defaultAttributes; 370 } 371 372 /** 373 * set the type for the templates 374 * 375 * @access public 376 * @param string type (html or tex) 377 * @return boolean true on success 378 */ 379 function setType( $type ) 380 { 381 switch( strtolower( $type ) ) 382 { 383 case "tex": 384 $this->setTags( '<{', '}>' ); 385 break; 386 case "html": 387 $this->setTags( '{', '}' ); 388 break; 389 default: 390 return patErrorManager::raiseWarning( 391 PATTEMPLATE_WARNING_UNKNOWN_TYPE, 392 "Unknown type '$type'. Please use 'html' or 'tex'." 393 ); 394 } 395 return true; 396 } 397 398 /** 399 * set the start and end tag for variables 400 * 401 * @access public 402 * @param string start tag 403 * @param string end tag 404 * @return boolean true on success 405 */ 406 function setTags( $startTag, $endTag ) 407 { 408 $this->_options['startTag'] = $startTag; 409 $this->_options['endTag'] = $endTag; 410 411 $this->_startTag = $startTag; 412 $this->_endTag = $endTag; 413 return true; 414 } 415 416 /** 417 * get start tag for variables 418 * 419 * @access public 420 * @return string start tag 421 */ 422 function getStartTag() 423 { 424 return $this->_options['startTag']; 425 } 426 427 /** 428 * get end tag for variables 429 * 430 * @access public 431 * @return string end tag 432 */ 433 function getEndTag() 434 { 435 return $this->_options['endTag']; 436 } 437 438 /** 439 * add a directory where patTemplate should search for 440 * modules. 441 * 442 * You may either pass a string or an array of directories. 443 * 444 * patTemplate will be searching for a module in the same 445 * order you added them. If the module cannot be found in 446 * the custom folders, it will look in 447 * patTemplate/$moduleType. 448 * 449 * @access public 450 * @param string module type 451 * @param string|array directory or directories to search. 452 */ 453 function addModuleDir( $moduleType, $dir ) 454 { 455 if( !isset( $this->_moduleDirs[$moduleType] ) ) 456 $this->_moduleDirs[$moduleType] = array(); 457 if( is_array( $dir ) ) 458 $this->_moduleDirs[$moduleType] = array_merge( $this->_moduleDirs[$moduleType], $dir ); 459 else 460 array_push( $this->_moduleDirs[$moduleType], $dir ); 461 } 462 463 /** 464 * Sets an attribute of a template 465 * 466 * supported attributes: visibilty, loop, parse, unusedvars 467 * 468 * @param string $template name of the template 469 * @param string $attribute name of the attribute 470 * @param mixed $value value of the attribute 471 * @access public 472 * @see setAttributes(),getAttribute(), clearAttribute() 473 */ 474 function setAttribute( $template, $attribute, $value ) 475 { 476 $template = strtolower( $template ); 477 if( !isset( $this->_templates[$template] ) ) 478 { 479 return patErrorManager::raiseWarning( 480 PATTEMPLATE_WARNING_NO_TEMPLATE, 481 "Template '$template' does not exist." 482 ); 483 } 484 485 $attribute = strtolower( $attribute ); 486 $this->_templates[$template]['attributes'][$attribute] = $value; 487 return true; 488 } 489 490 /** 491 * Sets several attribute of a template 492 * 493 * $attributes has to be a assotiative arrays containing attribute/value pairs 494 * supported attributes: visibilty, loop, parse, unusedvars 495 * 496 * @param string $template name of the template 497 * @param array $attributes attribute/value pairs 498 * @access public 499 * @see setAttribute(), getAttribute(), clearAttribute() 500 */ 501 function setAttributes( $template, $attributes ) 502 { 503 if( !is_array( $attributes ) ) 504 { 505 return patErrorManager::raiseError( PATTEMPLATE_ERROR_EXPECTED_ARRAY, 'patTemplate::setAttributes: Expected array as second parameter, '.gettype( $attributes ).' given' ); 506 } 507 508 $template = strtolower( $template ); 509 $attributes = array_change_key_case( $attributes ); 510 if( !isset( $this->_templates[$template] ) ) 511 { 512 return patErrorManager::raiseWarning( 513 PATTEMPLATE_WARNING_NO_TEMPLATE, 514 "Template '$template' does not exist." 515 ); 516 } 517 518 $this->_templates[$template]['attributes'] = array_merge( $this->_templates[$template]['attributes'], $attributes ); 519 return true; 520 } 521 522 /** 523 * Get all attributes of a template 524 * 525 * @param string name of the template 526 * @return array attributes 527 * @access public 528 */ 529 function getAttributes( $template ) 530 { 531 $template = strtolower( $template ); 532 if( !isset( $this->_templates[$template] ) ) 533 { 534 return patErrorManager::raiseWarning( 535 PATTEMPLATE_WARNING_NO_TEMPLATE, 536 "Template '$template' does not exist." 537 ); 538 } 539 return $this->_templates[$template]['attributes']; 540 } 541 542 /** 543 * Gets an attribute of a template 544 * 545 * supported attributes: visibilty, loop, parse, unusedvars 546 * 547 * @param string $template name of the template 548 * @param string $attribute name of the attribute 549 * @return mixed value of the attribute 550 * @access public 551 * @see setAttribute(), setAttributes(), clearAttribute() 552 */ 553 function getAttribute( $template, $attribute ) 554 { 555 $template = strtolower( $template ); 556 $attribute = strtolower( $attribute ); 557 if( !isset( $this->_templates[$template] ) ) 558 { 559 return patErrorManager::raiseWarning( 560 PATTEMPLATE_WARNING_NO_TEMPLATE, 561 "Template '$template' does not exist." 562 ); 563 } 564 return $this->_templates[$template]['attributes'][$attribute]; 565 } 566 567 /** 568 * Clears an attribute of a template 569 * 570 * supported attributes: visibilty, loop, parse, unusedvars 571 * 572 * @param string $template name of the template 573 * @param string $attribute name of the attribute 574 * @access public 575 * @see setAttribute(), setAttributes(), getAttribute() 576 */ 577 function clearAttribute( $template, $attribute ) 578 { 579 $template = strtolower( $template ); 580 $attribute = strtolower( $attribute ); 581 582 if( !isset( $this->_templates[$template] ) ) 583 { 584 return patErrorManager::raiseWarning( 585 PATTEMPLATE_WARNING_NO_TEMPLATE, 586 "Template '$template' does not exist." 587 ); 588 } 589 $this->_templates[$template]['attributes'][$attribute] = '';; 590 return true; 591 } 592 593 /** 594 * Prepare a template 595 * 596 * This can be used if you want to add variables to 597 * a template, that has not been loaded yet. 598 * 599 * @access public 600 * @param string template name 601 */ 602 function prepareTemplate( $name ) 603 { 604 $name = strtolower( $name ); 605 if( !isset( $this->_vars[$name] ) ) 606 { 607 $this->_vars[$name] = array( 608 'scalar' => array(), 609 'rows' => array() 610 ); 611 } 612 } 613 614 /** 615 * add a variable to a template 616 * 617 * A variable may also be an indexed array, but _not_ 618 * an associative array! 619 * 620 * @access public 621 * @param string $template name of the template 622 * @param string $varname name of the variable 623 * @param mixed $value value of the variable 624 */ 625 function addVar( $template, $varname, $value ) 626 { 627 $template = strtolower( $template ); 628 $varname = strtoupper( $varname ); 629 630 if( !is_array( $value ) ) { 631 $this->_vars[$template]['scalar'][$varname] = $value; 632 return true; 633 } 634 635 $cnt = count( $value ); 636 for ($i = 0; $i < $cnt; $i++) { 637 if (!isset( $this->_vars[$template]['rows'][$i] )) { 638 $this->_vars[$template]['rows'][$i] = array(); 639 } 640 $this->_vars[$template]['rows'][$i][$varname] = $value[$i]; 641 } 642 643 return true; 644 } 645 646 /** 647 * get the value of a variable 648 * 649 * @access public 650 * @param string name of the template 651 * @param string name of the variable 652 * @return string value of the variable, null if the variable is not set 653 */ 654 function getVar( $template, $varname ) 655 { 656 $template = strtolower( $template ); 657 $varname = strtoupper( $varname ); 658 659 if( isset( $this->_vars[$template]['scalar'][$varname] ) ) 660 return $this->_vars[$template]['scalar'][$varname]; 661 662 $value = array(); 663 664 $cnt = count( $this->_vars[$template]['rows'] ); 665 for( $i = 0; $i < $cnt; $i++ ) 666 { 667 if( !isset( $this->_vars[$template]['rows'][$i][$varname] ) ) 668 continue; 669 array_push( $value, $this->_vars[$template]['rows'][$i][$varname] ); 670 } 671 if( !empty( $value ) ) 672 return $value; 673 return null; 674 } 675 676 /** 677 * clear the value of a variable 678 * 679 * @access public 680 * @param string name of the template 681 * @param string name of the variable 682 * @return boolean 683 * @see clearVars(), clearTemplate() 684 */ 685 function clearVar( $template, $varname ) 686 { 687 $template = strtolower( $template ); 688 $varname = strtoupper( $varname ); 689 690 if (isset( $this->_vars[$template]['scalar'][$varname] )) { 691 unset ($this->_vars[$template]['scalar'][$varname]); 692 return true; 693 } 694 695 $result = false; 696 $cnt = count( $this->_vars[$template]['rows'] ); 697 for ($i = 0; $i < $cnt; $i++) { 698 if (!isset($this->_vars[$template]['rows'][$i][$varname])) { 699 continue; 700 } 701 unset($this->_vars[$template]['rows'][$i][$varname]); 702 $result = true; 703 } 704 return $result; 705 } 706 707 708 /** 709 * Adds several variables to a template 710 * 711 * Each Template can have an unlimited amount of its own variables 712 * $variables has to be an assotiative array containing variable/value pairs 713 * 714 * @param string $template name of the template 715 * @param array $variables assotiative array of the variables 716 * @param string $prefix prefix for all variable names 717 * @access public 718 * @see addVar(), addRows(), addGlobalVar(), addGlobalVars() 719 */ 720 function addVars( $template, $variables, $prefix = '' ) 721 { 722 $template = strtolower( $template ); 723 $prefix = strtoupper( $prefix ); 724 $variables = array_change_key_case( $variables, CASE_UPPER ); 725 726 foreach ($variables as $varname => $value) { 727 $varname = $prefix.$varname; 728 729 if (!is_array($value)) { 730 if (!is_scalar($value)) { 731 continue; 732 } 733 $this->_vars[$template]['scalar'][$varname] = $value; 734 continue; 735 } 736 737 $cnt = count( $value ); 738 for( $i = 0; $i < $cnt; $i++ ) { 739 if( !isset( $this->_vars[$template]['rows'][$i] ) ) 740 $this->_vars[$template]['rows'][$i] = array(); 741 742 $this->_vars[$template]['rows'][$i][$varname] = $value[$i]; 743 } 744 } 745 } 746 747 /** 748 * Clear all variables in a template 749 * 750 * This clears only variables, but does 751 * 752 * @access public 753 * @param string $template name of the template 754 * @return boolean 755 * @see clearVar(), clearTemplate() 756 */ 757 function clearVars( $template ) 758 { 759 $template = strtolower($template); 760 $this->_vars[$template] = array( 761 'scalar' => array(), 762 'rows' => array() 763 ); 764 return true; 765 } 766 767 768 /** 769 * Adds several rows of variables to a template 770 * 771 * Each Template can have an unlimited amount of its own variables 772 * Can be used to add a database result as variables to a template 773 * 774 * @param string $template name of the template 775 * @param array $rows array containing assotiative arrays with variable/value pairs 776 * @param string $prefix prefix for all variable names 777 * @access public 778 * @see addVar(), addVars(), addGlobalVar(), addGlobalVars() 779 */ 780 function addRows( $template, $rows, $prefix = '' ) 781 { 782 $template = strtolower( $template ); 783 $prefix = strtoupper( $prefix ); 784 785 $cnt = count( $rows ); 786 for( $i = 0; $i < $cnt; $i++ ) 787 { 788 if( !isset( $this->_vars[$template]['rows'][$i] ) ) 789 $this->_vars[$template]['rows'][$i] = array(); 790 791 $rows[$i] = array_change_key_case( $rows[$i], CASE_UPPER ); 792 793 foreach( $rows[$i] as $varname => $value ) 794 { 795 $this->_vars[$template]['rows'][$i][$prefix.$varname] = $value; 796 } 797 } 798 } 799 800 /** 801 * Adds an object to a template 802 * 803 * All properties of the object will be available as template variables. 804 * 805 * @access public 806 * @param string name of the template 807 * @param object|array object or array of objects 808 * @param string prefix for all variable names 809 * @param boolean ignore private properties (starting with _) 810 * @see addVar(), addRows(), addGlobalVar(), addGlobalVars() 811 */ 812 function addObject( $template, $object, $prefix = '', $ignorePrivate = false ) 813 { 814 if( is_array( $object ) ) { 815 $rows = array(); 816 foreach($object as $o) { 817 array_push( $rows, $this->getObjectVars($o, $ignorePrivate) ); 818 } 819 820 return $this->addRows( $template, $rows, $prefix ); 821 } elseif (is_object($object)) { 822 return $this->addVars( $template, $this->getObjectVars($object, $ignorePrivate), $prefix ); 823 } 824 return false; 825 } 826 827 /** 828 * get the vars from an object 829 * 830 * @access private 831 * @param object 832 * @param boolean ignore private properties (starting with _) 833 * @return array 834 */ 835 function getObjectVars($obj, $ignorePrivate = false) 836 { 837 if (method_exists($obj, 'getVars')) { 838 return $obj->getVars(); 839 } 840 $vars = get_object_vars($obj); 841 if ($ignorePrivate === false) { 842 return $vars; 843 } 844 foreach ($vars as $var => $value) { 845 if ($var{0} == '_') { 846 unset($vars[$var]); 847 } 848 } 849 return $vars; 850 } 851 852 /** 853 * Adds a global variable 854 * 855 * Global variables are valid in all templates of this object. 856 * A global variable has to be scalar, it will be converted to a string. 857 * 858 * @access public 859 * @param string $varname name of the global variable 860 * @param string $value value of the variable 861 * @return boolean true on success 862 * @see addGlobalVars(), addVar(), addVars(), addRows() 863 */ 864 function addGlobalVar( $varname, $value ) 865 { 866 $this->_globals[strtoupper( $varname )] = ( string )$value; 867 return true; 868 } 869 870 /** 871 * Clears a global variable 872 * 873 * @access public 874 * @param string $varname name of the global variable 875 * @return boolean true on success 876 * @see clearVar(), clearVars(), clearGlobalVars() 877 */ 878 function clearGlobalVar( $varname ) 879 { 880 $varname = strtoupper( $varname ); 881 if (!isset($this->_globals[$varname])) { 882 return false; 883 } 884 unset($this->_globals[$varname]); 885 return true; 886 } 887 888 /** 889 * Clears all global variables 890 * 891 * @access public 892 * @return boolean true on success 893 * @see clearVar(), clearVars(), clearGlobalVar() 894 */ 895 function clearGlobalVars() 896 { 897 $this->_globals = array(); 898 return true; 899 } 900 901 /** 902 * Adds several global variables 903 * 904 * Global variables are valid in all templates of this object. 905 * 906 * $variables is an associative array, containing name/value pairs of the variables. 907 * 908 * @access public 909 * @param array $variables array containing the variables 910 * @param string $prefix prefix for variable names 911 * @return boolean true on success 912 * @see addGlobalVar(), addVar(), addVars(), addRows() 913 */ 914 function addGlobalVars( $variables, $prefix = '' ) 915 { 916 $variables = array_change_key_case( $variables, CASE_UPPER ); 917 $prefix = strtoupper( $prefix ); 918 foreach( $variables as $varname => $value ) 919 { 920 $this->_globals[$prefix.$varname] = ( string )$value; 921 } 922 923 return true; 924 } 925 926 /** 927 * get all global variables 928 * 929 * @access public 930 * @return array global variables 931 */ 932 function getGlobalVars() 933 { 934 return $this->_globals; 935 } 936 937 /** 938 * checks wether a template exists 939 * 940 * @access public 941 * @param string name of the template 942 * @return boolean true, if the template exists, false otherwise 943 */ 944 function exists( $name ) 945 { 946 return in_array( strtolower( $name ), $this->_templateList ); 947 } 948 949 /** 950 * enable a template cache 951 * 952 * A template cache will improve performace, as the templates 953 * do not have to be read on each request. 954 * 955 * @access public 956 * @param string name of the template cache 957 * @param array parameters for the template cache 958 * @return boolean true on success, patError otherwise 959 */ 960 function useTemplateCache( $cache, $params = array() ) 961 { 962 if( !is_object( $cache ) ) 963 { 964 $cache = &$this->loadModule( 'TemplateCache', $cache, $params ); 965 } 966 if( patErrorManager::isError( $cache ) ) 967 return $cache; 968 969 $this->_tmplCache = &$cache; 970 return true; 971 } 972 973 /** 974 * enable an output filter 975 * 976 * Output filters are used to modify the template 977 * result before it is sent to the browser. 978 * 979 * They are applied, when displayParsedTemplate() is called. 980 * 981 * @access public 982 * @param string name of the output filter 983 * @param array parameters for the output filter 984 * @return boolean true on success, patError otherwise 985 */ 986 function applyOutputFilter( $filter, $params = array(), $template = null ) 987 { 988 if (!is_object($filter)) { 989 $filter = &$this->loadModule( 'OutputFilter', $filter, $params ); 990 } 991 if (patErrorManager::isError($filter)) { 992 return $filter; 993 } 994 995 if ($template === null) { 996 $this->_outputFilters[] = &$filter; 997 return true; 998 } 999 1000 $template = strtolower($template); 1001 if (!$this->exists($template)) { 1002 return patErrorManager::raiseWarning(PATTEMPLATE_WARNING_NO_TEMPLATE, 'The selected template does not exist'); 1003 } 1004 $this->_templates[$template]['attributes']['outputfilter'] = &$filter; 1005 return true; 1006 } 1007 1008 /** 1009 * enable an input filter 1010 * 1011 * input filters are used to modify the template 1012 * stream before it is split into smaller templates- 1013 * 1014 * @access public 1015 * @param string name of the input filter 1016 * @param array parameters for the input filter 1017 * @return boolean true on success, patError otherwise 1018 */ 1019 function applyInputFilter( $filter, $params = array() ) 1020 { 1021 if( !is_object( $filter ) ) 1022 { 1023 $filter = &$this->loadModule( 'InputFilter', $filter, $params ); 1024 } 1025 if( patErrorManager::isError( $filter ) ) 1026 return $filter; 1027 1028 $this->_inputFilters[] = &$filter; 1029 return true; 1030 } 1031 1032 /** 1033 * open a file and parse for patTemplate tags 1034 * 1035 * @access public 1036 * @param name of the file 1037 * @return true, if the template could be parsed 1038 * @deprecated Use patTemplate::readTemplatesFromInput() instead, as the method name is misleading 1039 * @see readTemplatesFromInput() 1040 */ 1041 function readTemplatesFromFile( $filename ) 1042 { 1043 return $this->readTemplatesFromInput( $filename, 'File' ); 1044 } 1045 1046 /** 1047 * open any input and parse for patTemplate tags 1048 * 1049 * @access public 1050 * @param string name of the input (filename, shm segment, etc.) 1051 * @param string driver that is used as reader, you may also pass a Reader object 1052 * @param array additional options that will only be used for this template 1053 * @param string name of the template that should be used as a container, should not be used by public 1054 * calls. 1055 * @return boolean true, if the template could be parsed, false otherwise 1056 */ 1057 function readTemplatesFromInput( $input, $reader = 'File', $options = null, $parseInto = null ) 1058 { 1059 if ((string)$input === '') { 1060 return patErrorManager::raiseError(PATTEMPLATE_ERROR_NO_INPUT, 'No input to read has been passed.'); 1061 } 1062 1063 if (is_array($options)) { 1064 $options = array_merge( $this->_options, $options ); 1065 } else { 1066 $options = $this->_options; 1067 } 1068 1069 if (!is_null($parseInto)) { 1070 $parseInto = strtolower( $parseInto ); 1071 } 1072 1073 $templates = false; 1074 if ($this->_tmplCache !== null) { 1075 /** 1076 * get the unique cache key 1077 */ 1078 $key = $this->_tmplCache->getKey($input, $options); 1079 1080 $templates = $this->_loadTemplatesFromCache( $input, $reader, $options, $key ); 1081 1082 /** 1083 * check for error returned from cache 1084 */ 1085 if (patErrorManager::isError($templates)) { 1086 return $templates; 1087 } 1088 } 1089 1090 /** 1091 * templates have not been loaded from cache 1092 */ 1093 if ($templates === false) { 1094 if (!is_object( $reader)) { 1095 $reader = &$this->loadModule('Reader', $reader); 1096 if (patErrorManager::isError($reader)) { 1097 return $reader; 1098 } 1099 } 1100 1101 if ($reader->isInUse()) { 1102 $reader = &$this->loadModule( 'Reader', $reader->getName(), array(), true); 1103 if( patErrorManager::isError( $reader ) ) { 1104 return $reader; 1105 } 1106 } 1107 1108 $reader->setOptions($options); 1109 1110 /** 1111 * set the root attributes 1112 */ 1113 if( !is_null( $parseInto ) ) 1114 { 1115 $attributes = $this->getAttributes( $parseInto ); 1116 if( !patErrorManager::isError( $attributes ) ) 1117 { 1118 $reader->setRootAttributes( $attributes ); 1119 } 1120 } 1121 1122 $templates = $reader->readTemplates( $input ); 1123 1124 /** 1125 * check for error returned from reader 1126 */ 1127 if( patErrorManager::isError( $templates ) ) 1128 return $templates; 1129 1130 /** 1131 * store the 1132 */ 1133 if( $this->_tmplCache !== null ) 1134 { 1135 $this->_tmplCache->write( $key, $templates ); 1136 } 1137 } 1138 1139 /** 1140 * traverse all templates 1141 */ 1142 foreach( $templates as $name => $spec ) 1143 { 1144 1145 /** 1146 * root template 1147 */ 1148 if( $name == '__ptroot' ) 1149 { 1150 if( $parseInto === false ) 1151 { 1152 continue; 1153 } 1154 if( !in_array( $parseInto, $this->_templateList ) ) 1155 continue; 1156 1157 $spec['loaded'] = true; 1158 $spec['attributes'] = $this->_templates[$parseInto]['attributes']; 1159 $name = $parseInto; 1160 } 1161 else 1162 { 1163 /** 1164 * store the name 1165 */ 1166 array_push( $this->_templateList, $name ); 1167 } 1168 1169 /** 1170 * if this is the first template that has been loaded 1171 * set it as the root template 1172 */ 1173 if( $this->_root === null && is_null( $parseInto ) && isset( $spec['isRoot'] ) && $spec['isRoot'] == true ) 1174 { 1175 $this->_root = $name; 1176 } 1177 1178 /** 1179 * set some default values 1180 */ 1181 $spec['iteration'] = 0; 1182 $spec['lastMode'] = 'w'; 1183 $spec['result'] = ''; 1184 $spec['modifyVars'] = array(); 1185 $spec['copyVars'] = array(); 1186 $spec['defaultVars'] = array(); 1187 1188 /** 1189 * store the template 1190 */ 1191 $this->_templates[$name] = $spec; 1192 1193 $this->prepareTemplate( $name ); 1194 1195 /** 1196 * store the default values of the variables 1197 */ 1198 foreach( $spec['varspecs'] as $varname => $varspec ) 1199 { 1200 if (isset($varspec['modifier'])) { 1201 $this->_templates[$name]['modifyVars'][$varname] = $varspec['modifier']; 1202 } 1203 1204 if( isset( $varspec['copyfrom'] ) ) 1205 { 1206 $this->_templates[$name]['copyVars'][$varname] = $varspec['copyfrom']; 1207 } 1208 1209 if( !isset( $varspec['default'] ) ) 1210 continue; 1211 1212 $this->_templates[$name]['defaultVars'][$varname] = $varspec['default']; 1213 1214 if( !is_null( $this->getVar( $name, $varname ) ) ) 1215 continue; 1216 1217 $this->addVar( $name, $varname, $varspec['default'] ); 1218 } 1219 1220 unset($this->_templates[$name]['varspecs']); 1221 1222 /** 1223 * autoload the template 1224 * 1225 * Some error management is needed here... 1226 */ 1227 if( isset( $this->_templates[$name]['attributes']['src'] ) && $this->_templates[$name]['attributes']['autoload'] == 'on' ) 1228 { 1229 if( $this->_templates[$name]['loaded'] !== true ) 1230 { 1231 if( $this->_templates[$name]['attributes']['parse'] == 'on' ) 1232 { 1233 $this->readTemplatesFromInput( $this->_templates[$name]['attributes']['src'], $this->_templates[$name]['attributes']['reader'], $options, $name ); 1234 } 1235 else 1236 { 1237 $this->loadTemplateFromInput( $this->_templates[$name]['attributes']['src'], $this->_templates[$name]['attributes']['reader'], null, $name ); 1238 } 1239 $this->_templates[$name]['loaded'] = true; 1240 } 1241 } 1242 } 1243 1244 return true; 1245 } 1246 1247 /** 1248 * load from template cache 1249 * 1250 * @access private 1251 * @param string name of the input (filename, shm segment, etc.) 1252 * @param string driver that is used as reader, you may also pass a Reader object 1253 * @param array options for the reader 1254 * @param string cache key 1255 * @return array|boolean either an array containing the templates, or false 1256 */ 1257 function _loadTemplatesFromCache( $input, &$reader, $options, $key ) 1258 { 1259 if( is_object( $reader ) ) 1260 $statName = $reader->getName(); 1261 else 1262 $statName = $reader; 1263 1264 $stat = &$this->loadModule( 'Stat', $statName ); 1265 $stat->setOptions( $options ); 1266 1267 /** 1268 * get modification time 1269 */ 1270 $modTime = $stat->getModificationTime( $input ); 1271 $templates = $this->_tmplCache->load( $key, $modTime ); 1272 1273 return $templates; 1274 } 1275 1276 /** 1277 * open any input and load content into template 1278 * 1279 * @access public 1280 * @param string name of the input (filename, shm segment, etc.) 1281 * @param string driver that is used as reader 1282 * @param string name of the template that should be used as a container, 1283 * @return boolean true, if the template could be parsed, false otherwise 1284 */ 1285 function loadTemplateFromInput( $input, $reader = 'File', $options = null, $parseInto = false ) 1286 { 1287 if( is_array( $options ) ) 1288 $options = array_merge( $this->_options, $options ); 1289 else 1290 $options = $this->_options; 1291 1292 if( !is_null( $parseInto ) ) 1293 $parseInto = strtolower( $parseInto ); 1294 1295 $reader = &$this->loadModule( 'Reader', $reader ); 1296 if( patErrorManager::isError( $reader ) ) 1297 { 1298 return $reader; 1299 } 1300 $reader->setOptions($options); 1301 1302 $result = $reader->loadTemplate( $input ); 1303 1304 if( patErrorManager::isError( $result ) ) 1305 { 1306 return $result; 1307 } 1308 1309 $this->_templates[$parseInto]['content'] .= $result; 1310 $this->_templates[$parseInto]['loaded'] = true; 1311 return true; 1312 } 1313 1314 /** 1315 * load a template that had autoload="off" 1316 * 1317 * This is needed, if you change the source of a template and want to 1318 * load it, after changing the attribute. 1319 * 1320 * @access public 1321 * @param string template name 1322 * @return boolean true, if template could be loaded 1323 */ 1324 function loadTemplate( $template ) 1325 { 1326 $template = strtolower( $template ); 1327 if( !isset( $this->_templates[$template] ) ) 1328 { 1329 return patErrorManager::raiseWarning( 1330 PATTEMPLATE_WARNING_NO_TEMPLATE, 1331 "Template '$template' does not exist." 1332 ); 1333 } 1334 1335 if( $this->_templates[$template]['loaded'] === true ) 1336 return true; 1337 1338 if( $this->_templates[$template]['attributes']['parse'] == 'on' ) 1339 { 1340 return $this->readTemplatesFromInput( $this->_templates[$template]['attributes']['src'], $this->_templates[$template]['attributes']['reader'], null, $template ); 1341 } 1342 else 1343 { 1344 return $this->loadTemplateFromInput( $this->_templates[$template]['attributes']['src'], $this->_templates[$template]['attributes']['reader'], null, $template ); 1345 } 1346 } 1347 1348 /** 1349 * loads a patTemplate module 1350 * 1351 * Modules are located in the patTemplate folder and include: 1352 * - Readers 1353 * - Caches 1354 * - Variable Modifiers 1355 * - Filters 1356 * - Functions 1357 * - Stats 1358 * 1359 * @access public 1360 * @param string moduleType (Reader|TemplateCache|Modifier|OutputFilter|InputFilter) 1361 * @param string moduleName 1362 * @param array parameters for the module 1363 * @return object 1364 */ 1365 function &loadModule( $moduleType, $moduleName, $params = array(), $new = false ) 1366 { 1367 if( !isset( $this->_modules[$moduleType] ) ) 1368 $this->_modules[$moduleType] = array(); 1369 1370 $sig = md5( $moduleName . serialize( $params ) ); 1371 1372 if( isset( $this->_modules[$moduleType][$sig] ) && $new === false ) { 1373 return $this->_modules[$moduleType][$sig]; 1374 } 1375 1376 if( !class_exists( 'patTemplate_Module' ) ) 1377 { 1378 $file = sprintf( "%s/Module.php", $this->getIncludePath() ); 1379 if( !@include_once $file ) 1380 return patErrorManager::raiseError( PATTEMPLATE_ERROR_BASECLASS_NOT_FOUND, 'Could not load module base class.' ); 1381 } 1382 1383 $baseClass = 'patTemplate_' . $moduleType; 1384 if( !class_exists( $baseClass ) ) 1385 { 1386 $baseFile = sprintf( "%s/%s.php", $this->getIncludePath(), $moduleType ); 1387 if( !@include_once $baseFile ) 1388 return patErrorManager::raiseError( PATTEMPLATE_ERROR_BASECLASS_NOT_FOUND, "Could not load base class for $moduleType ($baseFile)." ); 1389 } 1390 1391 $moduleClass = 'patTemplate_' . $moduleType . '_' .$moduleName; 1392 if( !class_exists( $moduleClass ) ) 1393 { 1394 if( isset( $this->_moduleDirs[$moduleType] ) ) 1395 $dirs = $this->_moduleDirs[$moduleType]; 1396 else 1397 $dirs = array(); 1398 array_push( $dirs, $this->getIncludePath() .'/'. $moduleType ); 1399 1400 $found = false; 1401 foreach( $dirs as $dir ) 1402 { 1403 $moduleFile = sprintf( "%s/%s.php", $dir, str_replace( '_', '/', $moduleName ) ); 1404 if (@include_once $moduleFile) { 1405 $found = true; 1406 break; 1407 } 1408 } 1409 1410 if( !$found ) { 1411 return patErrorManager::raiseError( PATTEMPLATE_ERROR_MODULE_NOT_FOUND, "Could not load module $moduleClass ($moduleFile)." ); 1412 } 1413 } 1414 1415 if( !class_exists( $moduleClass ) ) 1416 { 1417 return patErrorManager::raiseError( PATTEMPLATE_ERROR_MODULE_NOT_FOUND, "Module file $moduleFile does not contain class $moduleClass." ); 1418 } 1419 1420 $this->_modules[$moduleType][$sig] = &new $moduleClass; 1421 if( method_exists( $this->_modules[$moduleType][$sig], 'setTemplateReference' ) ) 1422 { 1423 $this->_modules[$moduleType][$sig]->setTemplateReference( $this ); 1424 } 1425 1426 $this->_modules[$moduleType][$sig]->setParams( $params ); 1427 1428 return $this->_modules[$moduleType][$sig]; 1429 } 1430 1431 /** 1432 * checks whether a module exists. 1433 * 1434 * Modules are located in the patTemplate folder and include: 1435 * - Readers 1436 * - Caches 1437 * - Variable Modifiers 1438 * - Filters 1439 * - Functions 1440 * - Stats 1441 * 1442 * @access public 1443 * @param string moduleType (Reader|TemplateCache|Modifier|OutputFilter|InputFilter) 1444 * @param string moduleName 1445 * @return boolean 1446 */ 1447 function moduleExists( $moduleType, $moduleName ) 1448 { 1449 if (isset($this->_moduleDirs[$moduleType])) { 1450 $dirs = $this->_moduleDirs[$moduleType]; 1451 } else { 1452 $dirs = array(); 1453 } 1454 array_push($dirs, $this->getIncludePath() .'/'. $moduleType); 1455 1456 foreach ($dirs as $dir) { 1457 $moduleFile = sprintf( "%s/%s.php", $dir, str_replace( '_', '/', $moduleName ) ); 1458 if (!file_exists($moduleFile)) { 1459 continue; 1460 } 1461 if (!is_readable($moduleFile)) { 1462 continue; 1463 } 1464 return true; 1465 } 1466 return false; 1467 } 1468 1469 /** 1470 * parses a template 1471 * 1472 * Parses a template and stores the parsed content. 1473 * mode can be "w" for write (delete already parsed content) or "a" for append (appends the 1474 * new parsed content to the already parsed content) 1475 * 1476 * @access public 1477 * @param string name of the template 1478 * @param string mode for the parsing 1479 */ 1480 function parseTemplate( $template, $mode = 'w' ) 1481 { 1482 $template = strtolower($template); 1483 1484 if (!isset($this->_templates[$template])) { 1485 return patErrorManager::raiseWarning( 1486 PATTEMPLATE_WARNING_NO_TEMPLATE, 1487 "Template '$template' does not exist." 1488 ); 1489 } 1490 1491 /** 1492 * template is not visible 1493 */ 1494 if ($this->_templates[$template]['attributes']['visibility'] == 'hidden') { 1495 $this->_templates[$template]['result'] = ''; 1496 $this->_templates[$template]['parsed'] = true; 1497 return true; 1498 } 1499 1500 /** 1501 * check, if the template has been loaded 1502 * and load it if necessary. 1503 */ 1504 if ($this->_templates[$template]['loaded'] !== true) { 1505 if ($this->_templates[$template]['attributes']['parse'] == 'on') { 1506 $result = $this->readTemplatesFromInput( $this->_templates[$template]['attributes']['src'], $this->_templates[$template]['attributes']['reader'], null, $template ); 1507 } else { 1508 $result = $this->loadTemplateFromInput( $this->_templates[$template]['attributes']['src'], $this->_templates[$template]['attributes']['reader'], null, $template ); 1509 } 1510 if (patErrorManager::isError($result)) { 1511 return $result; 1512 } 1513 } 1514 1515 /** 1516 * check for autoclear 1517 */ 1518 if( 1519 isset( $this->_templates[$template]['attributes']['autoclear'] ) && 1520 $this->_templates[$template]['attributes']['autoclear'] == 'yes' && 1521 $mode === 'w' && 1522 $this->_templates[$template]['lastMode'] != 'a' 1523 ) { 1524 $this->_templates[$template]['parsed'] = false; 1525 } 1526 1527 /** 1528 * template has been parsed and mode is not 'append' 1529 */ 1530 if ($this->_templates[$template]['parsed'] === true && $mode === 'w') { 1531 return true; 1532 } 1533 1534 $this->_templates[$template]['lastMode'] = $mode; 1535 1536 $this->_initTemplate( $template ); 1537 1538 if (!isset($this->_vars[$template]['rows'])) { 1539 $this->_vars[$template]['rows'] = array(); 1540 } 1541 $loop = count( $this->_vars[$template]['rows'] ); 1542 1543 /** 1544 * loop at least one times 1545 */ 1546 if ($loop < 1) { 1547 $loop = 1; 1548 } 1549 1550 if (isset($this->_templates[$template]['attributes']['maxloop'])) { 1551 $loop = ceil( $loop / $this->_templates[$template]['attributes']['maxloop'] ) * $this->_templates[$template]['attributes']['maxloop']; 1552 } 1553 1554 $this->_templates[$template]['loop'] = max( $this->_templates[$template]['attributes']['loop'], $loop ); 1555 1556 $start = 0; 1557 if (isset($this->_templates[$template]['attributes']['limit'])) { 1558 $p = strpos( $this->_templates[$template]['attributes']['limit'], ',' ); 1559 if ($p === false) { 1560 $this->_templates[$template]['loop'] = min( $this->_templates[$template]['loop'], $this->_templates[$template]['attributes']['limit'] ); 1561 $start = 0; 1562 } else { 1563 $start = substr( $this->_templates[$template]['attributes']['limit'], 0, $p ); 1564 $end = substr( $this->_templates[$template]['attributes']['limit'], $p+1 )+$start; 1565 1566 $this->_templates[$template]['loop'] = min( $this->_templates[$template]['loop'], $end ); 1567 } 1568 } 1569 1570 /** 1571 * template should be cleared before parsing 1572 */ 1573 if ($mode == 'w') { 1574 $this->_templates[$template]['result'] = ''; 1575 $this->_templates[$template]['iteration'] = $start; 1576 } 1577 1578 $loopCount = 0; 1579 for ($i = $start; $i < $this->_templates[$template]['loop']; $i++) { 1580 $finished = false; 1581 1582 unset( $this->_templates[$template]['vars'] ); 1583 1584 /** 1585 * fetch the variables 1586 */ 1587 $this->_fetchVariables( $template ); 1588 1589 /** 1590 * fetch the template 1591 */ 1592 $result = $this->_fetchTemplate($template); 1593 1594 if ($result === false) { 1595 $this->_templates[$template]['iteration']++; 1596 continue; 1597 } 1598 1599 /** 1600 * parse 1601 */ 1602 $this->_parseVariables( $template ); 1603 $result = $this->_parseDependencies( $template ); 1604 if (patErrorManager::isError($result)) { 1605 return $result; 1606 } 1607 1608 /** 1609 * store result 1610 */ 1611 $this->_templates[$template]['result'] .= $this->_templates[$template]['work']; 1612 1613 $this->_templates[$template]['iteration']++; 1614 1615 ++$loopCount; 1616 1617 /** 1618 * check for maximum loops 1619 */ 1620 if (isset($this->_templates[$template]['attributes']['maxloop'])) { 1621 if ($loopCount == $this->_templates[$template]['attributes']['maxloop'] && $i < ($loop-1)) { 1622 $loopCount = 0; 1623 $finished = true; 1624 $this->_templates[$template]['parsed'] = true; 1625 $this->parseTemplate( $this->_templates[$template]['attributes']['parent'], 'a' ); 1626 $this->_templates[$template]['parsed'] = false; 1627 $this->_templates[$template]['result'] = ''; 1628 } 1629 } 1630 } 1631 1632 if (!$finished && isset($this->_templates[$template]['attributes']['maxloop'])) { 1633 $this->_templates[$template]['parsed'] = true; 1634 $this->parseTemplate( $this->_templates[$template]['attributes']['parent'], 'a', false ); 1635 $this->_templates[$template]['parsed'] = false; 1636 $this->_templates[$template]['result'] = ''; 1637 $this->_templates[$this->_templates[$template]['attributes']['parent']]['work'] = ''; 1638 } 1639 1640 $this->_parseGlobals($template); 1641 1642 $this->_handleUnusedVars($template); 1643 1644 $this->_templates[$template]['parsed'] = true; 1645 1646 if (isset($this->_templates[$template]['attributes']['autoclear']) && $this->_templates[$template]['attributes']['autoclear'] == 'yes') { 1647 $this->_vars[$template] = array( 1648 'scalar' => array(), 1649 'rows' => array() 1650 ); 1651 } 1652 1653 if (isset($this->_templates[$template]['attributes']['outputfilter'])) { 1654 if (is_object($this->_templates[$template]['attributes']['outputfilter'])) { 1655 $filter = &$this->_templates[$template]['attributes']['outputfilter']; 1656 } else { 1657 $filter = &$this->loadModule('OutputFilter', $this->_templates[$template]['attributes']['outputfilter']); 1658 } 1659 1660 if (patErrorManager::isError($filter)) { 1661 return $filter; 1662 } 1663 1664 $this->_templates[$template]['result'] = $filter->apply($this->_templates[$template]['result']); 1665 } 1666 return true; 1667 } 1668 1669 /** 1670 * Initialize a template 1671 * 1672 * This method checks the variable specifications and 1673 * copys variables from other templates. 1674 * 1675 * @access private 1676 * @param string name of the template 1677 * @return boolean true on success 1678 */ 1679 function _initTemplate( $template ) 1680 { 1681 foreach( $this->_templates[$template]['copyVars'] as $dest => $src ) 1682 { 1683 /** 1684 * copy from the same template 1685 */ 1686 if( !is_array( $src ) ) 1687 { 1688 $srcTemplate = $template; 1689 $srcVar = $src; 1690 } 1691 else 1692 { 1693 $srcTemplate = $src[0]; 1694 $srcVar = $src[1]; 1695 } 1696 1697 $copied = false; 1698 1699 /** 1700 * copy from another template 1701 */ 1702 if( isset( $this->_vars[$srcTemplate] ) ) 1703 { 1704 if( isset( $this->_vars[$srcTemplate]['scalar'][$srcVar] ) ) 1705 { 1706 $this->_vars[$template]['scalar'][$dest] = $this->_vars[$srcTemplate]['scalar'][$srcVar]; 1707 continue; 1708 } 1709 1710 $rows = count( $this->_vars[$srcTemplate]['rows'] ); 1711 1712 for( $i = 0; $i < $rows; $i++ ) 1713 { 1714 if( !isset( $this->_vars[$srcTemplate]['rows'][$i][$srcVar] ) ) 1715 continue; 1716 if( !isset( $this->_vars[$template]['rows'][$i] ) ) 1717 $this->_vars[$template]['rows'][$i] = array(); 1718 $this->_vars[$template]['rows'][$i][$dest] = $this->_vars[$srcTemplate]['rows'][$i][$srcVar]; 1719 $copied = true; 1720 } 1721 } 1722 if( !$copied && isset( $this->_globals[$srcVar] )) 1723 { 1724 $this->_vars[$template]['scalar'][$dest] = $this->_globals[$srcVar]; 1725 } 1726 1727 } 1728 return true; 1729 } 1730 1731 /** 1732 * parse all variables in a template 1733 * 1734 * @access private 1735 * @param string 1736 */ 1737 function _parseVariables( $template ) 1738 { 1739 /** 1740 * modify variables before parsing 1741 */ 1742 $this->_applyModifers($template, $this->_templates[$template]['vars']); 1743 1744 foreach( $this->_templates[$template]['vars'] as $key => $value ) 1745 { 1746 if( is_array( $value ) ) 1747 { 1748 if( count( $this->_templates[$template]['currentDependencies'] ) == 1 ) 1749 { 1750 $child = $this->_templates[$template]['currentDependencies'][0]; 1751 } 1752 else 1753 { 1754 if( isset( $this->_templates[$template]['attributes']['child'] ) ) 1755 $child = $this->_templates[$template]['attributes']['child']; 1756 else 1757 continue; 1758 } 1759 1760 $this->setAttribute( $child, 'autoclear', 'yes' ); 1761 $this->addVar( $child, $key, $value ); 1762 continue; 1763 } 1764 1765 $var = $this->_startTag.$key.$this->_endTag; 1766 $this->_templates[$template]['work'] = str_replace( $var, $value, $this->_templates[$template]['work'] ); 1767 } 1768 return true; 1769 } 1770 1771 /** 1772 * parse global variables in the template 1773 * 1774 * @access private 1775 * @param string name of the template 1776 * @return boolean 1777 */ 1778 function _parseGlobals($template) 1779 { 1780 $globalVars = $this->_globals; 1781 $this->_applyModifers($template, $globalVars); 1782 1783 foreach( $globalVars as $key => $value ) 1784 { 1785 if( is_array( $value ) ) 1786 { 1787 continue; 1788 } 1789 1790 $var = $this->_startTag.$key.$this->_endTag; 1791 $this->_templates[$template]['result'] = str_replace( $var, $value, $this->_templates[$template]['result'] ); 1792 } 1793 return true; 1794 } 1795 1796 /** 1797 * apply variable modifiers 1798 * 1799 * The variables will be passed by reference. 1800 * 1801 * @access private 1802 * @param string name of the template (use modifiers from this template) 1803 * @param array variables to which the modifiers should be applied 1804 * @return boolean 1805 */ 1806 function _applyModifers($template, &$vars) 1807 { 1808 foreach ($this->_templates[$template]['modifyVars'] as $varname => $modifier) { 1809 if (!isset($vars[$varname])) { 1810 continue; 1811 } 1812 1813 if (($modifier['type'] === 'php' || $modifier['type'] === 'auto' ) && is_callable($modifier['mod'])) { 1814 $vars[$varname] = call_user_func($modifier['mod'], $vars[$varname]); 1815 continue; 1816 } 1817 1818 if ($modifier['type'] === 'php') { 1819 continue; 1820 } 1821 1822 $mod = &$this->loadModule( 'Modifier', ucfirst( $modifier['mod'] ) ); 1823 $vars[$varname] = $mod->modify( $vars[$varname], $modifier['params'] ); 1824 } 1825 1826 // apply the default modifier 1827 if (isset($this->_templates[$template]['attributes']['defaultmodifier'])) { 1828 1829 $defaultModifier = $this->_templates[$template]['attributes']['defaultmodifier']; 1830 if (is_callable($defaultModifier)) { 1831 $type = 'php'; 1832 } else { 1833 $type = 'custom'; 1834 $defaultModifier = &$this->loadModule('Modifier', ucfirst($defaultModifier)); 1835 } 1836 1837 1838 foreach (array_keys($vars) as $varname) { 1839 if (isset($this->_templates[$template]['modifyVars'][$varname])) { 1840 continue; 1841 } 1842 if ($type === 'php') { 1843 $vars[$varname] = call_user_func($defaultModifier, $vars[$varname]); 1844 } else { 1845 $vars[$varname] = $defaultModifier->modify($vars[$varname], array()); 1846 } 1847 } 1848 } 1849 1850 return true; 1851 } 1852 1853 /** 1854 * parse all dependencies in a template 1855 * 1856 * @access private 1857 * @param string 1858 */ 1859 function _parseDependencies($template) 1860 { 1861 $countDep = count( $this->_templates[$template]['currentDependencies'] ); 1862 for ($i = 0; $i < $countDep; $i++) { 1863 $depTemplate = $this->_templates[$template]['currentDependencies'][$i]; 1864 if ($depTemplate == $template) { 1865 return patErrorManager::raiseError(PATTEMPLATE_ERROR_RECURSION, 'You have an error in your template "' . $template . '", which leads to recursion'); 1866 } 1867 $this->parseTemplate($depTemplate); 1868 $var = $this->_startTag.'TMPL:'.strtoupper( $depTemplate) .$this->_endTag; 1869 $this->_templates[$template]['work'] = str_replace( $var, $this->_templates[$depTemplate]['result'], $this->_templates[$template]['work'] ); 1870 } 1871 return true; 1872 } 1873 1874 /** 1875 * fetch plain template 1876 * 1877 * The template content will be stored in the template 1878 * configuration so it can be used by other 1879 * methods. 1880 * 1881 * @access private 1882 * @param string template name 1883 * @return boolean 1884 */ 1885 function _fetchTemplate( $template ) 1886 { 1887 switch( $this->_templates[$template]['attributes']['type'] ) 1888 { 1889 /** 1890 * condition template 1891 */ 1892 case 'condition': 1893 $value = $this->_getConditionValue($template, $this->_templates[$template]['attributes']['conditionvar']); 1894 if ($value === false) { 1895 $this->_templates[$template]['work'] = ''; 1896 $this->_templates[$template]['currentDependencies'] = array(); 1897 } else { 1898 $this->_templates[$template]['work'] = $this->_templates[$template]['subtemplates'][$value]['data']; 1899 $this->_templates[$template]['currentDependencies'] = $this->_templates[$template]['subtemplates'][$value]['dependencies']; 1900 } 1901 break; 1902 1903 /** 1904 * condition template 1905 */ 1906 case 'simplecondition': 1907 foreach( $this->_templates[$template]['attributes']['requiredvars'] as $var ) 1908 { 1909 // different template scope 1910 if( $var[0] !== $template ) { 1911 $this->_fetchVariables($var[0]); 1912 } 1913 $value = null; 1914 // fetch the local variable 1915 if( isset( $this->_templates[$var[0]]['vars'][$var[1]] ) 1916 && strlen( $this->_templates[$var[0]]['vars'][$var[1]] ) > 0 ) { 1917 $value = $this->_templates[$var[0]]['vars'][$var[1]]; 1918 } 1919 if (isset($this->_templates[$template]['attributes']['useglobals'])) { 1920 if(isset($this->_globals[$var[1]]) && strlen($this->_globals[$var[1]]) > 1) { 1921 $value = $this->_globals[$var[1]]; 1922 } 1923 } 1924 if ($value !== null) { 1925 if ($var[2] === null) { 1926 continue; 1927 } else { 1928 // Joomla! addition 23-June-2005 1929 // value wrapped in ## uses regex for comparison 1930 $condition = $var[2]; 1931 if (substr( $condition, 0, 1 ) == '#' && substr( $condition, -1, 1 ) == '#' ) { 1932 if (preg_match( $condition, $value )) { 1933 continue; 1934 } 1935 } else if ($condition == $value) { 1936 continue; 1937 } 1938 /* Pat Original 1939 if ($var[2] == $value) { 1940 continue; 1941 } 1942 */ 1943 } 1944 } 1945 1946 $this->_templates[$template]['work'] = ''; 1947 $this->_templates[$template]['currentDependencies'] = array(); 1948 break 2; 1949 } 1950 $this->_templates[$template]['work'] = $this->_templates[$template]['content']; 1951 $this->_templates[$template]['currentDependencies'] = $this->_templates[$template]['dependencies']; 1952 break; 1953 1954 /** 1955 * modulo template 1956 */ 1957 case 'modulo': 1958 // check for empty template 1959 1960 if ($this->_hasVariables($template)) { 1961 $value = (string)($this->_templates[$template]['iteration'] + 1 ) % $this->_templates[$template]['attributes']['modulo']; 1962 } else { 1963 $value = '__empty'; 1964 } 1965 1966 $value = $this->_getConditionValue($template, $value, false); 1967 if ($value === false) { 1968 $this->_templates[$template]['work'] = ''; 1969 $this->_templates[$template]['currentDependencies'] = array(); 1970 } else { 1971 $this->_templates[$template]['work'] = $this->_templates[$template]['subtemplates'][$value]['data']; 1972 $this->_templates[$template]['currentDependencies'] = $this->_templates[$template]['subtemplates'][$value]['dependencies']; 1973 } 1974 break; 1975 1976 /** 1977 * standard template 1978 */ 1979 default: 1980 $this->_templates[$template]['work'] = $this->_templates[$template]['content']; 1981 $this->_templates[$template]['currentDependencies'] = $this->_templates[$template]['dependencies']; 1982 break; 1983 } 1984 return true; 1985 } 1986 1987 /** 1988 * check, whether a template contains variables 1989 * 1990 * @access private 1991 * @param string template name 1992 * @return boolean 1993 */ 1994 function _hasVariables($template) 1995 { 1996 if (!empty($this->_vars[$template]['scalar'])) { 1997 return true; 1998 } 1999 if (isset($this->_vars[$template]['rows'][$this->_templates[$template]['iteration']])) { 2000 return true; 2001 } 2002 return false; 2003 } 2004 2005 /** 2006 * fetch the value of a condition variable 2007 * 2008 * _fetchVariables() has to be called before this 2009 * method is being called. 2010 * 2011 * @access private 2012 * @param string template name 2013 * @param string condition value 2014 * @param boolean flag that indicates whether value is the name of the variable that should be resolved 2015 * 2016 * @todo split this method into smaller check methods that will be called according to 2017 * a priority list 2018 */ 2019 function _getConditionValue( $template, $value, $isVar = true ) 2020 { 2021 if ($isVar === true) { 2022 if (isset($this->_templates[$template]['attributes']['conditiontmpl'])) { 2023 $_template = $this->_templates[$template]['attributes']['conditiontmpl']; 2024 $this->_fetchVariables($_template); 2025 } else { 2026 $_template = $template; 2027 } 2028 2029 /** 2030 * get the value from the template variables 2031 */ 2032 if (!isset($this->_templates[$_template]['vars'][$value]) || strlen($this->_templates[$_template]['vars'][$value]) === 0) { 2033 if ($this->_templates[$template]['attributes']['useglobals'] == 'yes' || $this->_templates[$template]['attributes']['useglobals'] == 'useglobals') { 2034 if (isset( $this->_globals[$value] ) && strlen( $this->_globals[$value] ) > 0) { 2035 $value = $this->_globals[$value]; 2036 } else { 2037 $value = '__empty'; 2038 } 2039 } else { 2040 $value = '__empty'; 2041 } 2042 } else { 2043 $value = $this->_templates[$_template]['vars'][$value]; 2044 } 2045 } else { 2046 $_template = $template; 2047 } 2048 2049 // if value is empty and a template for empty has been defined, this 2050 // has priority 2051 if ($value === '__empty' && isset($this->_templates[$template]['subtemplates']['__empty'])) { 2052 return $value; 2053 } 2054 2055 // only one iteration (but not empty), use the __single condition 2056 if ($value !== '__empty' && $this->_templates[$_template]['loop'] === 1) { 2057 if( isset($this->_templates[$template]['subtemplates']['__single'])) { 2058 return '__single'; 2059 } 2060 } else { 2061 2062 // is __first? 2063 if( $this->_templates[$_template]['iteration'] == 0 ) { 2064 if( isset( $this->_templates[$template]['subtemplates']['__first'] ) ) { 2065 return '__first'; 2066 } 2067 } 2068 2069 /** 2070 * is __last? 2071 */ 2072 if (isset($this->_templates[$_template]['loop'])) { 2073 $max = $this->_templates[$_template]['loop'] - 1; 2074 if( $this->_templates[$_template]['iteration'] == $max ) { 2075 if( isset( $this->_templates[$template]['subtemplates']['__last'] ) ) { 2076 return '__last'; 2077 } 2078 } 2079 } 2080 } 2081 2082 // search for exact match 2083 foreach (array_keys($this->_templates[$template]['subtemplates']) as $key) { 2084 if (isset($this->_templates[$template]['subtemplates'][$key]['attributes']['var'])) { 2085 $var = $this->_templates[$template]['subtemplates'][$key]['attributes']['var']; 2086 if (isset($this->_templates[$template]['vars'][$var])) { 2087 $current = $this->_templates[$template]['vars'][$var]; 2088 } else { 2089 $current = null; 2090 } 2091 } else { 2092 $current = $key; 2093 } 2094 2095 if ((string)$value === (string)$current) { 2096 return $key; 2097 } 2098 } 2099 2100 /** 2101 * is __default? 2102 */ 2103 if( isset( $this->_templates[$template]['subtemplates']['__default'] ) ) { 2104 return '__default'; 2105 } 2106 2107 return false; 2108 } 2109 2110 /** 2111 * fetch variables for a template 2112 * 2113 * The variables will be stored in the template 2114 * configuration so they can be used by other 2115 * methods. 2116 * 2117 * @access private 2118 * @param string template name 2119 * @return boolean 2120 */ 2121 function _fetchVariables( $template ) 2122 { 2123 /** 2124 * variables already have been fetched 2125 */ 2126 if (isset($this->_templates[$template]['vars'])) { 2127 return true; 2128 } 2129 2130 $iteration = $this->_templates[$template]['iteration']; 2131 2132 $vars = array(); 2133 if( isset( $this->_templates[$template]['attributes']['varscope'] ) ) 2134 { 2135 if (!is_array($this->_templates[$template]['attributes']['varscope'])) { 2136 $this->_templates[$template]['attributes']['varscope'] = array($this->_templates[$template]['attributes']['varscope']); 2137 } 2138 foreach ($this->_templates[$template]['attributes']['varscope'] as $scopeTemplate) { 2139 if ($this->exists($scopeTemplate)) { 2140 $this->_fetchVariables( $scopeTemplate ); 2141 $vars = array_merge($this->_templates[$scopeTemplate]['vars'], $vars); 2142 } else { 2143 patErrorManager::raiseWarning(PATTEMPLATE_WARNING_NO_TEMPLATE, 'Template \''.$scopeTemplate.'\' does not exist, referenced in varscope attribute of template \''.$template.'\''); 2144 } 2145 } 2146 } else { 2147 $vars = array(); 2148 } 2149 2150 /** 2151 * get the scalar variables 2152 */ 2153 if( isset( $this->_vars[$template] ) && isset( $this->_vars[$template]['scalar'] ) ) 2154 { 2155 $vars = array_merge( $vars, $this->_vars[$template]['scalar'] ); 2156 } 2157 2158 /** 2159 * get the row variables 2160 */ 2161 if( isset( $this->_vars[$template]['rows'][$iteration] ) ) 2162 { 2163 $vars = array_merge( $vars, $this->_vars[$template]['rows'][$iteration] ); 2164 } 2165 2166 /** 2167 * add some system variables 2168 */ 2169 $currentRow = $iteration + $this->_templates[$template]['attributes']['rowoffset']; 2170 $vars['PAT_ROW_VAR'] = $currentRow; 2171 2172 if( $this->_templates[$template]['attributes']['type'] == 'modulo' ) 2173 { 2174 $vars['PAT_MODULO_REP'] = ceil( $currentRow / $this->_templates[$template]['attributes']['modulo'] ); 2175 $vars['PAT_MODULO'] = ( $this->_templates[$template]['iteration'] + 1 ) % $this->_templates[$template]['attributes']['modulo']; 2176 } 2177 2178 if( $this->_templates[$template]['attributes']['addsystemvars'] !== false ) 2179 { 2180 $vars['PATTEMPLATE_VERSION'] = $this->_systemVars['appVersion']; 2181 $vars['PAT_LOOPS'] = $this->_templates[$template]['loop']; 2182 2183 switch ($this->_templates[$template]['attributes']['addsystemvars']) 2184 { 2185 case 'boolean': 2186 $trueValue = 'true'; 2187 $falseValue = 'false'; 2188 break; 2189 case 'integer': 2190 $trueValue = '1'; 2191 $falseValue = '0'; 2192 break; 2193 default: 2194 $trueValue = $this->_templates[$template]['attributes']['addsystemvars']; 2195 $falseValue = ''; 2196 break; 2197 } 2198 2199 $vars['PAT_IS_ODD'] = ( $currentRow % 2 == 1 ) ? $trueValue : $falseValue; 2200 $vars['PAT_IS_EVEN'] = ( $currentRow % 2 == 0 ) ? $trueValue : $falseValue; 2201 $vars['PAT_IS_FIRST'] = ( $currentRow == 1 ) ? $trueValue : $falseValue; 2202 $vars['PAT_IS_LAST'] = ( $currentRow == $this->_templates[$template]['loop'] ) ? $trueValue : $falseValue; 2203 $vars['PAT_ROW_TYPE'] = ( $currentRow % 2 == 1 ) ? 'odd' : 'even'; 2204 } 2205 2206 $this->_templates[$template]['vars'] = $vars; 2207 return true; 2208 } 2209 2210 /** 2211 * handle all unused variables in a template 2212 * 2213 * This is influenced by the 'unusedvars' attribute of the 2214 * template 2215 * 2216 * @access private 2217 * @param string 2218 */ 2219 function _handleUnusedVars( $template ) 2220 { 2221 $regexp = '/([^\\\])('.$this->_startTag.'[^a-z]+[^\\\]'.$this->_endTag.')/U'; 2222 2223 switch( $this->_templates[$template]['attributes']['unusedvars'] ) 2224 { 2225 case 'comment': 2226 $this->_templates[$template]['result'] = preg_replace( $regexp, '<!-- \\1\\2 -->', $this->_templates[$template]['result'] ); 2227 break; 2228 case 'strip': 2229 $this->_templates[$template]['result'] = preg_replace( $regexp, '\\1', $this->_templates[$template]['result'] ); 2230 break; 2231 case 'nbsp': 2232 $this->_templates[$template]['result'] = preg_replace( $regexp, '\\1 ', $this->_templates[$template]['result'] ); 2233 break; 2234 case 'ignore': 2235 break; 2236 default: 2237 $this->_templates[$template]['result'] = preg_replace( $regexp, '\\1'.$this->_templates[$template]['attributes']['unusedvars'], $this->_templates[$template]['result'] ); 2238 break; 2239 } 2240 2241 // replace quoted variables 2242 $regexp = '/[\\\]'.$this->_startTag.'([^a-z]+)[\\\]'.$this->_endTag.'/U'; 2243 $this->_templates[$template]['result'] = preg_replace( $regexp, $this->_startTag.'\\1'.$this->_endTag, $this->_templates[$template]['result'] ); 2244 2245 return true; 2246 } 2247 2248 /** 2249 * returns a parsed Template 2250 * 2251 * If the template already has been parsed, it just returns the parsed template. 2252 * If the template has not been loaded, it will be loaded. 2253 * 2254 * @access public 2255 * @param string name of the template 2256 * @param boolean whether to apply output filters 2257 * @return string Content of the parsed template 2258 * @see displayParsedTemplate() 2259 */ 2260 function getParsedTemplate( $name = null, $applyFilters = false ) 2261 { 2262 if (is_null($name)) { 2263 $name = $this->_root; 2264 } 2265 2266 $name = strtolower( $name ); 2267 $result = $this->parseTemplate( $name ); 2268 2269 if (patErrorManager::isError( $result )) { 2270 return $result; 2271 } 2272 2273 if ($applyFilters === false) { 2274 return $this->_templates[$name]['result']; 2275 } 2276 2277 $result = $this->_templates[$name]['result']; 2278 2279 $cnt = count ($this->_outputFilters); 2280 for ($i = 0; $i < $cnt; $i++) { 2281 $result = $this->_outputFilters[$i]->apply( $result ); 2282 } 2283 2284 return $result; 2285 } 2286 2287 /** 2288 * displays a parsed Template 2289 * 2290 * If the template has not been loaded, it will be loaded. 2291 * 2292 * @see getParsedTemplate() 2293 * @param string name of the template 2294 * @param boolean whether to apply output filters 2295 * @return boolean true on success 2296 * @access public 2297 */ 2298 function displayParsedTemplate($name = null, $applyFilters = true) 2299 { 2300 $result = $this->getParsedTemplate($name, $applyFilters); 2301 2302 /** 2303 * error happened 2304 */ 2305 if (patErrorManager::isError($result)) { 2306 return $result; 2307 } 2308 2309 echo $result; 2310 return true; 2311 } 2312 2313 /** 2314 * parse a template and push the result into a variable of any other 2315 * template 2316 * 2317 * If the template already has been parsed, it will just be pushed into the variable. 2318 * If the template has not been loaded, it will be loaded. 2319 * 2320 * @access public 2321 * @param string name of the template 2322 * @return string Content of the parsed template 2323 * @param boolean if set to true, the value will be appended to the value already stored. 2324 * @see getParsedTemplate() 2325 * @see addVar() 2326 */ 2327 function parseIntoVar( $srcTmpl, $destTmpl, $var, $append = false ) 2328 { 2329 $srcTmpl = strtolower( $srcTmpl ); 2330 $destTmpl = strtolower( $destTmpl ); 2331 $var = strtoupper($var); 2332 2333 $result = $this->parseTemplate( $srcTmpl ); 2334 2335 if( patErrorManager::isError( $result ) ) 2336 return $result; 2337 2338 if( $append !== true || !isset( $this->_vars[$destTmpl]['scalar'][$var] ) ) 2339 $this->_vars[$destTmpl]['scalar'][$var] = ''; 2340 2341 $this->_vars[$destTmpl]['scalar'][$var] .= $this->_templates[$srcTmpl]['result']; 2342 2343 return true; 2344 } 2345 2346 /** 2347 * clears a parsed Template 2348 * 2349 * Parsed Content, variables and the loop attribute are cleared 2350 * 2351 * If you will not be using this template anymore, then you should 2352 * call freeTemplate() 2353 * 2354 * @access public 2355 * @param string name of the template 2356 * @param boolean set this to true to clear all child templates, too 2357 * @see clearAllTemplates() 2358 * @see freeTemplate() 2359 */ 2360 function clearTemplate( $name, $recursive = false ) 2361 { 2362 $name = strtolower( $name ); 2363 $this->_templates[$name]['parsed'] = false; 2364 $this->_templates[$name]['work'] = ''; 2365 $this->_templates[$name]['iteration'] = 0; 2366 $this->_templates[$name]['result'] = ''; 2367 $this->_vars[$name] = array( 2368 'scalar' => array(), 2369 'rows' => array() 2370 ); 2371 2372 if (!empty($this->_templates[$name]['defaultVars'])) { 2373 foreach ($this->_templates[$name]['defaultVars'] as $varname => $value) { 2374 $this->addVar($name, $varname, $value); 2375 } 2376 } 2377 2378 /** 2379 * clear child templates as well 2380 */ 2381 if( $recursive === true ) 2382 { 2383 $deps = $this->_getDependencies( $name ); 2384 foreach( $deps as $dep ) 2385 { 2386 $this->clearTemplate( $dep, true ); 2387 } 2388 } 2389 return true; 2390 } 2391 2392 /** 2393 * clears all templates 2394 * 2395 * @access public 2396 * @uses clearTemplate() 2397 */ 2398 function clearAllTemplates() 2399 { 2400 $templates = array_keys( $this->_templates ); 2401 $cnt = count( $templates ); 2402 for( $i = 0; $i < $cnt; $i++ ) 2403 { 2404 $this->clearTemplate( $templates[$i] ); 2405 } 2406 return true; 2407 } 2408 2409 /** 2410 * frees a template 2411 * 2412 * All memory consumed by the template 2413 * will be freed. 2414 * 2415 * @access public 2416 * @param string name of the template 2417 * @param boolean clear dependencies of the template 2418 * @see freeAllTemplates() 2419 */ 2420 function freeTemplate( $name, $recursive = false ) 2421 { 2422 $name = strtolower( $name ); 2423 $key = array_search( $name, $this->_templateList ); 2424 if( $key === false ) 2425 { 2426 return patErrorManager::raiseWarning( 2427 PATTEMPLATE_WARNING_NO_TEMPLATE, 2428 "Template '$name' does not exist." 2429 ); 2430 } 2431 2432 unset( $this->_templateList[$key] ); 2433 $this->_templateList = array_values( $this->_templateList ); 2434 2435 /** 2436 * free child templates as well 2437 */ 2438 if( $recursive === true ) 2439 { 2440 $deps = $this->_getDependencies( $name ); 2441 foreach( $deps as $dep ) 2442 { 2443 $this->freeTemplate( $dep, true ); 2444 } 2445 } 2446 2447 unset( $this->_templates[$name] ); 2448 unset( $this->_vars[$name] ); 2449 if (isset($this->_discoveredPlaceholders[$name])) { 2450 unset($this->_discoveredPlaceholders[$name]); 2451 } 2452 2453 return true; 2454 } 2455 2456 /** 2457 * frees all templates 2458 * 2459 * All memory consumed by the templates 2460 * will be freed. 2461 * 2462 * @access public 2463 * @see freeTemplate() 2464 */ 2465 function freeAllTemplates() 2466 { 2467 $this->_templates = array(); 2468 $this->_vars = array(); 2469 $this->_templateList = array(); 2470 } 2471 2472 /** 2473 * get _all_ dependencies of a template, 2474 * regardless of the subtemplates 2475 * 2476 * @access private 2477 * @param string template name 2478 * @return array list of all subtemplates 2479 */ 2480 function _getDependencies( $template ) 2481 { 2482 $deps = array(); 2483 if( isset( $this->_templates[$template]['dependencies'] ) ) 2484 $deps = $this->_templates[$template]['dependencies']; 2485 2486 if( isset( $this->_templates[$template]['subtemplates'] ) ) 2487 { 2488 foreach( $this->_templates[$template]['subtemplates'] as $sub ) 2489 { 2490 if( isset( $sub['dependencies'] ) ) 2491 $deps = array_merge( $deps, $sub['dependencies'] ); 2492 } 2493 } 2494 $deps = array_unique( $deps ); 2495 return $deps; 2496 } 2497 2498 /** 2499 * Displays useful information about all or named templates 2500 * 2501 * This method breaks BC, as it now awaits an array instead of 2502 * unlimited parameters. 2503 * 2504 * @param mixed array of templates that should be dumped, or null if you 2505 * want all templates to be dumped 2506 * @param string dumper 2507 * @access public 2508 */ 2509 function dump( $restrict = null, $dumper = 'Html' ) 2510 { 2511 if( is_string( $restrict ) ) 2512 $restrict = array( $restrict ); 2513 2514 $dumper = &$this->loadModule( 'Dump', $dumper ); 2515 2516 if( patErrorManager::isError( $dumper ) ) 2517 { 2518 return $dumper; 2519 } 2520 2521 if( is_null( $restrict ) ) 2522 { 2523 $templates = $this->_templates; 2524 $vars = $this->_vars; 2525 } 2526 else 2527 { 2528 $restrict = array_map( 'strtolower', $restrict ); 2529 2530 $templates = array(); 2531 $vars = array(); 2532 2533 foreach( $this->_templates as $name => $spec ) 2534 { 2535 if( !in_array( $name, $restrict ) ) 2536 continue; 2537 $templates[$name] = $spec; 2538 $vars[$name] = $this->_vars[$name]; 2539 } 2540 } 2541 2542 $dumper->displayHeader(); 2543 $dumper->dumpGlobals( $this->_globals ); 2544 $dumper->dumpTemplates( $templates, $vars ); 2545 $dumper->displayFooter(); 2546 2547 return true; 2548 } 2549 2550 /** 2551 * get the include path 2552 * 2553 * @access public 2554 * @return string 2555 */ 2556 function getIncludePath() 2557 { 2558 return PATTEMPLATE_INCLUDE_PATH; 2559 } 2560 2561 /** 2562 * apply input filters that have been set 2563 * 2564 * This is being called by the readers. 2565 * 2566 * @access public 2567 * @param string template 2568 * @return string filtered templeta 2569 */ 2570 function applyInputFilters( $template ) 2571 { 2572 $cnt = count( $this->_inputFilters ); 2573 for( $i = 0; $i < $cnt; $i++ ) 2574 { 2575 $template = $this->_inputFilters[$i]->apply( $template ); 2576 } 2577 return $template; 2578 } 2579 2580 /** 2581 * checks, whether a placeholder exists in a template 2582 * 2583 * @access public 2584 * @param string name of the placeholder 2585 * @param string name of the template 2586 * @param boolean whether to use the cached result of a previous call 2587 */ 2588 function placeholderExists($placeholder, $tmpl, $cached = true) 2589 { 2590 $tmpl = strtolower($tmpl); 2591 $placeholder = strtoupper($placeholder); 2592 2593 if (!$this->exists($tmpl)) { 2594 return false; 2595 } 2596 2597 if ($cached === true) { 2598 if (isset($this->_discoveredPlaceholders[$tmpl]) && isset($this->_discoveredPlaceholders[$tmpl][$placeholder])) { 2599 return $this->_discoveredPlaceholders[$tmpl][$placeholder]; 2600 } 2601 } 2602 2603 if (isset($this->_templates[$tmpl]['subtemplates'])) { 2604 $content = ''; 2605 foreach ($this->_templates[$tmpl]['subtemplates'] as $temp) { 2606 if (!isset($temp['data'])) { 2607 continue; 2608 } 2609 $content .= $temp['data']; 2610 } 2611 } else { 2612 $content = $this->_templates[$tmpl]['content']; 2613 } 2614 2615 $search = $this->_startTag . $placeholder . $this->_endTag; 2616 if (strstr($content, $search) !== false) { 2617 $this->_discoveredPlaceholders[$tmpl][$placeholder] = true; 2618 return true; 2619 } 2620 $this->_discoveredPlaceholders[$tmpl][$placeholder] = false; 2621 return false; 2622 } 2623 2624 /** 2625 * Convert the template to its string representation. 2626 * 2627 * This method allows you to just echo the patTemplate 2628 * object in order to display the template. 2629 * 2630 * Requires PHP5 2631 * 2632 * <code> 2633 * $tmpl = new patTemplate(); 2634 * $tmpl->readTemplatesFromFile( 'myfile.tmpl' ); 2635 * echo $tmpl; 2636 * </code> 2637 * 2638 * @access private 2639 * @return string 2640 */ 2641 function __toString() 2642 { 2643 return $this->getParsedTemplate(); 2644 } 2645 } 2646 2647 /** 2648 * @package Joomla 2649 */ 2650 class patFactory { 2651 /** 2652 * @param array An array of additional files to include from the root folder 2653 * @return object 2654 */ 2655 function &createTemplate( $files=null ) { 2656 global $mainframe; 2657 $tmpl = new patTemplate; 2658 2659 // patTemplate 2660 if ($GLOBALS['mosConfig_caching']) { 2661 $tmpl->useTemplateCache( 'File', array( 2662 'cacheFolder' => $GLOBALS['mosConfig_cachepath'], 'lifetime' => 20 )); 2663 } 2664 2665 $tmpl->setNamespace( 'mos' ); 2666 2667 // load the wrapper and common templates 2668 $tmpl->setRoot( dirname( __FILE__ ) . '/tmpl' ); 2669 $tmpl->readTemplatesFromFile( 'page.html' ); 2670 $tmpl->applyInputFilter('ShortModifiers'); 2671 2672 if (is_array( $files )) { 2673 foreach ($files as $file) { 2674 $tmpl->readTemplatesFromInput( $file ); 2675 } 2676 } 2677 //echo $this->basePath() . '/components/' . $option . '/tmpl'; 2678 2679 $tmpl->addGlobalVar( 'option', $GLOBALS['option'] ); 2680 $tmpl->addGlobalVar( 'self', $_SERVER['PHP_SELF'] ); 2681 $tmpl->addGlobalVar( 'itemid', $GLOBALS['Itemid'] ); 2682 $tmpl->addGlobalVar( 'siteurl', $GLOBALS['mosConfig_live_site'] ); 2683 $tmpl->addGlobalVar( 'adminurl', $GLOBALS['mosConfig_live_site'] . '/administrator' ); 2684 $tmpl->addGlobalVar( 'templateurl', $GLOBALS['mosConfig_live_site'] . '/templates/' . $mainframe->getTemplate() ); 2685 $tmpl->addGlobalVar( 'admintemplateurl', $GLOBALS['mosConfig_live_site'] . '/administrator/templates/' . $mainframe->getTemplate() ); 2686 $tmpl->addGlobalVar( 'sitename', $GLOBALS['mosConfig_sitename'] ); 2687 $tmpl->addGlobalVar('treecss', 'dtree.css'); 2688 $tmpl->addGlobalVar('treeimgfolder', 'img'); 2689 2690 $iso = split( '=', _ISO ); 2691 $tmpl->addGlobalVar( 'page_encoding', $iso[1] ); 2692 $tmpl->addGlobalVar( 'version_copyright', $GLOBALS['_VERSION']->COPYRIGHT ); 2693 $tmpl->addGlobalVar( 'version_url', $GLOBALS['_VERSION']->URL ); 2694 2695 $tmpl->addVar( 'form', 'formAction', $_SERVER['PHP_SELF'] ); 2696 $tmpl->addVar( 'form', 'formName', 'adminForm' ); 2697 2698 // tabs 2699 $turl = $GLOBALS['mosConfig_live_site'] .'/includes/js/tabs/'; 2700 $tmpl->addVar( 'includeTabs', 'taburl', $turl ); 2701 2702 return $tmpl; 2703 } 2704 } 2705 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 14:43:32 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |