+++ /dev/null
-<?php
-/*
-+-------------------------------------------------------------------------+
-| Copyright (C) 2004-2005 Juan Luis Frances Jiminez |
-| |
-| This program 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 2 |
-| of the License, or (at your option) any later version. |
-| |
-| This program 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. |
-+-------------------------------------------------------------------------+
-*/
-require_once "config.inc.php";
-
-class Bweb extends DB {
-
- var $StartDate;
- var $EndDate;
-
- var $driver;
-
- public $tpl;
- public $db_link; // Database link
-
- private $config_file; // Config filename
- private $config; // Loaded config from bacula.conf
- private $catalogs = array(); // Catalog array
- public $catalog_nb;
- private $bwcfg;
-
- function __construct()
- {
- $this->bwcfg = new BW_Config();
- $dsn = array();
-
- // Checking if config file exist and is readable
- if( !$this->bwcfg->Check_Config_File() )
- die( "Unable to load configuration file" );
- else {
- $this->bwcfg->Load_Config();
- $this->catalog_nb = $this->bwcfg->Count_Catalogs();
- }
-
- // Select which catalog to connect to
- if( isset( $_POST['catalog_id'] ) )
- $dsn = $this->bwcfg->Get_Dsn( $_POST['catalog_id'] );
- else
- $dsn = $this->bwcfg->Get_Dsn( 0 );
-
- // Connect to the database
- $this->db_link = $this->connect( $dsn );
-
- if (DB::isError($this->db_link)) {
- die( 'Unable to connect to catalog <br />' . $this->db_link->getMessage());
- }else {
- $this->driver = $dsn['phptype'];
- register_shutdown_function(array(&$this,'close') );
- }
-
- // Initialize smarty template classe
- $this->init_tpl();
- // Initialize smarty gettext function
- $this->init_gettext();
-
- // Catalog selection
- if( $this->catalog_nb > 1 ) {
- // Set current catalog in header template
- if(isset( $_POST['catalog_id'] ) )
- $this->tpl->assign( 'catalog_current', $_POST['catalog_id'] );
-
- $this->tpl->assign( 'catalogs', $this->bwcfg->Get_Catalogs() );
- }else
- {
-
- }
- }
-
- // Initialize Smarty template classe
- function init_tpl()
- {
- $this->tpl = new Smarty();
-
- $this->tpl->compile_check = true;
- $this->tpl->debugging = false;
- $this->tpl->force_compile = true;
-
- $this->tpl->template_dir = "./templates";
- $this->tpl->compile_dir = "./templates_c";
- $this->tpl->config_dir = "./configs";
- }
-
- function init_gettext()
- {
- global $smarty_gettext_path;
-
- if ( function_exists("gettext") ) {
- require_once( BW_SMARTY_GETTEXT . "smarty_gettext.php" );
- $this->tpl->register_block('t','smarty_translate');
-
- $language = $this->bwcfg->Get_Config_Param("lang");
- $domain = "messages";
- putenv("LANG=$language");
- setlocale(LC_ALL, $language);
- bindtextdomain($domain,"./locale");
- textdomain($domain);
- }
- else {
- function smarty_translate($params, $text, &$smarty) {
- return $text;
- }
- $smarty->register_block('t','smarty_translate');
- }
- }
-
- function close()
- {
- $this->db_link->disconnect();
- }
-
- // Return humanized size with default unit of GB
- // if auto provide for unit argument, automaticaly decide which unit
- function human_file_size( $size, $decimal = 2, $unit = 'auto' )
- {
- $unit_id = 0;
- $lisible = false;
- $units = array('B','KB','MB','GB','TB');
- $hsize = $size;
-
- switch( $unit )
- {
- case 'auto';
- while( !$lisible ) {
- if ( $hsize >= 1024 ) {
- $hsize = $hsize / 1024;
- $unit_id += 1;
- }
- else
- $lisible = true;
- } // end while
- break;
-
- default:
- $p = array_search( $unit, $units);
- $hsize = $hsize / pow(1024,$p);
- break;
- } // end switch
-
- $hsize = sprintf("%." . $decimal . "f", $hsize);
- $hsize = $hsize . ' ' . $units[$unit_id];
- return $hsize;
- } // end function
-
-
- function GetDbSize()
- {
- $database_size = 0;
- $query = "";
-
- switch( $this->driver )
- {
- case 'mysql':
- $query = "SELECT table_schema AS 'database', sum( data_length + index_length) AS 'dbsize' ";
- $query .= "FROM information_schema.TABLES ";
- $query .= "WHERE table_schema = 'bacula' ";
- $query .= "GROUP BY table_schema";
- break;
- case 'pgsql':
- $query = "SELECT pg_database_size('bacula') AS dbsize";
- break;
- case 'sqlite':
- // Not yet implemented
- return "0 MB";
- break;
- }
-
- $result = $this->db_link->query( $query );
-
- if(! PEAR::isError( $result ) )
- {
- $db = $result->fetchRow( DB_FETCHMODE_ASSOC );
- $database_size =+ $db['dbsize'];
- }else
- die( "Unable to get database size<br />" . $result->getMessage() );
-
- return $this->human_file_size( $database_size );
- } // end function GetDbSize()
-
- public function Get_Nb_Clients()
- {
- $clients = $this->db_link->query("SELECT COUNT(*) AS nb_client FROM Client");
- if( PEAR::isError($clients) )
- die( "Unable to get client number" );
- else
- return $clients->fetchRow( DB_FETCHMODE_ASSOC );
- }
-
- // Return an array of volumes ordered by poolid and volume name
- function GetVolumeList() {
-
- $volumes = array();
- $query = "";
- $debug = false;
-
- // Get the list of pools id
- $query = "SELECT Pool.poolid, Pool.name FROM Pool ORDER BY Pool.poolid";
-
- //$this->db_link->setFetchMode(DB_FETCHMODE_ASSOC);
- $pools = $this->db_link->query( $query );
-
- if( PEAR::isError( $pools ) )
- die("Error: Failed to get pool list <br />SQL Query: $query<br />" . $pools->getMessage() );
-
- while( $pool = $pools->fetchRow( DB_FETCHMODE_ASSOC ) ) {
- switch( $this->driver )
- {
- case 'mysql':
- $query = "SELECT Media.volumename, Media.volbytes, Media.volstatus, Media.mediatype, Media.lastwritten, Media.volretention
- FROM Media LEFT JOIN Pool ON Media.poolid = Pool.poolid
- WHERE Media.poolid = '". $pool['poolid'] . "' ORDER BY Media.volumename";
- break;
- case 'pgsql':
- $query = "SELECT media.volumename, media.volbytes, media.volstatus, media.mediatype, media.lastwritten, media.volretention
- FROM media LEFT JOIN pool ON media.poolid = pool.poolid
- WHERE media.poolid = '". $pool['poolid'] . "' ORDER BY media.volumename";
- break;
- case 'sqlite':
- $query = ""; // not yet implemented
- break;
- default:
- break;
- } // end switch
-
- $medias = $this->db_link->query( $query );
-
- if( PEAR::isError( $medias ) ) {
- die( "Failed to get media list for pool $volume[0] <br /> " . $medias->getMessage() );
- }else {
- if( $debug ) echo "Found " . $medias->numRows() . " medias for pool " . $pool['name'] . " <br />";
-
- // Create array key for each pool
- if( !array_key_exists( $pool['name'], $volumes) )
- {
- $volumes[ $pool['name'] ] = array();
- }
- while( $media = $medias->fetchRow( DB_FETCHMODE_ASSOC ) ) {
- if( $debug ) {
- var_dump( $media );
- }
- // If the pool is empty (no volumes in this pool)
- if( $medias->numRows() == 0 ) {
- if( $debug ) echo "No media in pool " . $pool['name'] . "<br />";
- } else {
- if( $media['lastwritten'] != "0000-00-00 00:00:00" ) {
- // Calculate expiration date if the volume is Full
- if( $media['volstatus'] == 'Full' ) {
- $expire_date = strtotime($media['lastwritten']) + $media['volretention'];
- $media['expire'] = strftime("%Y-%m-%d", $expire_date);
- }else {
- $media['expire'] = 'N/A';
- }
- // Media used bytes in a human format
- $media['volbytes'] = $this->human_file_size( $media['volbytes'] );
- } else {
- $media['lastwritten'] = "N/A";
- $media['expire'] = "N/A";
- $media['volbytes'] = "0 KB";
- }
-
- // Odd or even row
- if( count( $volumes[ $pool['name'] ] ) % 2)
- $media['class'] = 'odd';
-
- // Add the media in pool array
- array_push( $volumes[ $pool['name']], $media);
- }
- } // end while
- } // end if else
- } // end while
- return $volumes;
- } // end function GetVolumeList()
-
- public function CountJobsbyLevel( $delay = LAST_DAY, $level = 'F' )
- {
- $end_date = mktime();
- $start_date = $end_date - $delay;
-
- $start_date = date( "Y-m-d H:i:s", $start_date );
- $end_date = date( "Y-m-d H:i:s", $end_date );
-
- $query = "SELECT COUNT(JobId) as jobs FROM Job ";
- $query .= "WHERE (EndTime BETWEEN '$start_date' AND '$end_date') AND ";
- $query .= "Level = '$level' ";
-
- $result = $this->db_link->query( $query );
-
- if (PEAR::isError( $result ) ) {
- die( "Unable to get number of jobs with $level status from catalog <br />" . $result->getMessage() );
- }else {
- $jobs = $result->fetchRow( DB_FETCHMODE_ASSOC );
- return $jobs['jobs'];
- }
-
- }
-
- public function CountJobs( $delay = LAST_DAY, $status = 'any' )
- {
- $query = "SELECT COUNT(JobId) AS job_nb FROM Job ";
- $where_delay = "";
- $where_status = "";
-
- // Interval condition for SQL query
- if( $delay != ALL ) {
- $end_date = mktime();
- $start_date = $end_date - $delay;
-
- $start_date = date( "Y-m-d H:i:s", $start_date );
- $end_date = date( "Y-m-d H:i:s", $end_date );
-
- $where_delay = "WHERE EndTime BETWEEN '$start_date' AND '$end_date' ";
- }
-
- if( $status != 'any' ) {
- switch( $status )
- {
- case 'completed':
- $where_status = "JobStatus = 'T' ";
- break;
- case 'failed':
- $where_status = "JobStatus IN ('f','E') ";
- break;
- case 'canceled':
- $where_status = "JobStatus = 'A' ";
- break;
- case 'waiting':
- $where_status = "JobStatus IN ('F','S','M','m','s','j','c','d','t') ";
- break;
- } // end switch
- }
-
- if( !empty($where_delay) )
- $query = $query . $where_delay . 'AND ' . $where_status;
- else {
- if( !empty($where_status) )
- $query = $query . 'WHERE ' . $where_status;
- }
-
- $jobs = $this->db_link->query( $query );
-
- if (PEAR::isError( $jobs ) ) {
- die( "Unable to get last $status jobs number from catalog <br />" . $jobs->getMessage() );
- }else {
- $jobs = $jobs->fetchRow( DB_FETCHMODE_ASSOC );
- return $jobs['job_nb'];
- }
- }
-
- // Return the list of Pools in a array
- public function Get_Pools_List()
- {
- $pool_list = array();
- $result = "";
-
- $query = "SELECT Name, PoolId FROM Pool";
-
- $result = $this->db_link->query ( $query );
-
- if( PEAR::isError( $result ) ) {
- die( "Unable to get the pool list from catalog" );
- }else {
- while( $pool = $result->fetchRow(DB_FETCHMODE_ASSOC) ) {
- array_push( $pool_list, array( $pool['Name'] => $pool['PoolId'] ) );
- }
- return $pool_list;
- }
- }
-
- public function Get_BackupJob_Names()
- {
- $query = "SELECT Name FROM Job GROUP BY Name";
- $backupjobs = array();
-
- $result = $this->db_link->query( $query );
-
- if (PEAR::isError( $result ) ) {
- die("Unable to get BackupJobs list from catalog" );
- }else{
- while( $backupjob = $result->fetchRow( DB_FETCHMODE_ASSOC ) ) {
- array_push( $backupjobs, $backupjob["Name"] );
- }
- return $backupjobs;
- }
- }
-
- // Return elasped time string for a job
- function Get_ElapsedTime( $start_time, $end_time )
- {
- $diff = $end_time - $start_time;
-
- $daysDiff = sprintf("%02d", floor($diff/60/60/24) );
- $diff -= $daysDiff*60*60*24;
-
- $hrsDiff = sprintf("%02d", floor($diff/60/60) );
- $diff -= $hrsDiff*60*60;
-
- $minsDiff = sprintf("%02d", floor($diff/60) );
- $diff -= $minsDiff*60;
- $secsDiff = sprintf("%02d", $diff );
-
- if( $daysDiff > 0 )
- return $daysDiff . 'day(s) ' . $hrsDiff.':' . $minsDiff . ':' . $secsDiff;
- else
- return $hrsDiff . ':' . $minsDiff . ':' . $secsDiff;
- }
-
- public function Get_ElapsedTime_Job( $delay = LAST_DAY )
- {
- $query = "";
- $total_elapsed = 0;
-
- // Interval calculation
- $end_date = mktime();
- $start_date = $end_date - $delay;
-
- $start_date = date( "Y-m-d H:i:s", $start_date );
- $end_date = date( "Y-m-d H:i:s", $end_date );
-
- switch( $this->driver )
- {
- case 'mysql':
- $query = "SELECT UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime) AS elapsed from Job ";
- $query .= "WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
- break;
- }
- $result = $this->db_link->query( $query );
-
- if( PEAR::isError($result) ){
- die( "Unable to get elapsed time for jobs from catalog<br />query = $query <br />" . $result->getMessage() );
- }else {
- while( $time = $result->fetchRow( DB_FETCHMODE_ASSOC ) ) {
- //echo 'elapsed = ' . $time['elapsed'] . '<br />';
- $total_elapsed += $time['elapsed'];
- }
- // Verify if elapsed time is more than 1 day
- if ( $total_elapsed > LAST_DAY ) {
- return date("%d days H:i:s", $total_elapsed );
- }else {
- return date("H:i:s", $total_elapsed );
- }
- }
- }
-
- // Return Jobs statistics for a specific interval such as
- // - Completed jobs number
- // - Failed jobs number
- // - Waiting jobs number
- // The returned values will be used by a Bgraph classe
- public function GetJobsStatistics( $type = 'completed', $delay = LAST_DAY )
- {
- $query = "";
- $where = "";
- $jobs = "";
- $label = "";
- $res = "";
-
- // Interval calculation
- $end_date = mktime();
- $start_date = $end_date - $delay;
-
- $start_date = date( "Y-m-d H:i:s", $start_date );
- $end_date = date( "Y-m-d H:i:s", $end_date );
-
- $interval_where = "(EndTime BETWEEN '$start_date' AND '$end_date') AND ";
-
- // Job status
- switch( $type )
- {
- case 'completed':
- $where = $interval_where . "JobStatus = 'T' ";
- $label = "Completed";
- break;
- case 'terminated_errors':
- $where = $interval_where . "JobStatus = 'E' ";
- $label = "Terminated with errors";
- break;
- case 'failed':
- $where = $interval_where . "JobStatus = 'f' ";
- $label = "Failed";
- break;
- case 'waiting':
- $where = "JobStatus IN ('F','S','M','m','s','j','c','d','t') ";
- $label = "Waiting";
- break;
- case 'created':
- $where = "JobStatus = 'C' ";
- $label = "Created but not running";
- break;
- case 'running':
- $where = "JobStatus = 'R' ";
- $label = "Running";
- break;
- case 'error':
- $where = $interval_where . "JobStatus IN ('e','f') ";
- $label = "Errors";
- break;
- }
-
- $query = 'SELECT COUNT(JobId) AS ' . $type . ' ';
- $query .= 'FROM Job ';
- $query .= "WHERE $where ";
-
- //echo 'query = ' . $query . '<br />';
-
- $jobs = $this->db_link->query( $query );
-
- if (PEAR::isError( $jobs ) ) {
- die( "Unable to get last $type jobs status from catalog<br />" . $status->getMessage() );
- }else {
- $res = $jobs->fetchRow();
- return array( $label , current($res) );
- }
- } // end function GetJobsStatistics()
-
- public function GetPoolsStatistics( $pools )
- {
- foreach( $pools as $pool_name => $pool ) {
- //var_dump( $pool );
- $query = "SELECT COUNT(*) AS nb_vol FROM Media WHERE PoolId = '$pool'";
- //echo $query . '<br />';
- //echo 'Pool name ' . $pool_name . '<br />';
- $result = $this->db_link->query( $query );
-
- if( PEAR::isError( $result ) ) {
- die("Unable to get volume number from catalog");
- }else{
- $nb_vol = $result->fetchRow(DB_FETCHMODE_ASSOC);
- return array( $pool_name, $nb_vol['nb_vol'] );
- }
- }
- }
-
- public function GetStoredFiles( $delay = LAST_DAY )
- {
- $totalfiles = 0;
-
- $query = "SELECT SUM(JobFiles) AS stored_files FROM Job ";
-
- // Interval calculation
- $end_date = mktime();
- $start_date = $end_date - $delay;
-
- $start_date = date( "Y-m-d H:i:s", $start_date );
- $end_date = date( "Y-m-d H:i:s", $end_date );
-
- if( $delay != ALL )
- $query .= "WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
-
- $result = $this->db_link->query( $query );
-
- if( !PEAR::isError($result) ) {
- $nbfiles = $result->fetchRow(DB_FETCHMODE_ASSOC);
- $totalfiles = $totalfiles + $nbfiles['stored_files'];
- }else{
- die("Unable to get protected files from catalog <br />" . $result->getMessage() );
- }
-
- return $totalfiles;
- }
-
- public function GetStoredBytes( $delay = LAST_DAY )
- {
- $query = "SELECT SUM(JobBytes) as stored_bytes FROM Job ";
-
- // Interval calculation
- $end_date = mktime();
- $start_date = $end_date - $delay;
-
- $start_date = date( "Y-m-d H:i:s", $start_date );
- $end_date = date( "Y-m-d H:i:s", $end_date );
-
- if( $delay != ALL )
- $query .= "WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
-
- $result = $this->db_link->query( $query );
-
- if( PEAR::isError( $result ) ) {
- die( "Unable to get Job Bytes from catalog" );
- }else{
- return $result->fetchRow( DB_FETCHMODE_ASSOC );
- }
- }
-
- public function GetStoredBytesByInterval( $start_date, $end_date )
- {
- $query = "SELECT SUM(JobBytes) as stored_bytes, EndTime FROM Job WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
-
- $result = $this->db_link->query( $query );
-
- if( PEAR::isError( $result ) ) {
- die( "Unable to get Job Bytes from catalog" );
- }else{
- $stored_bytes = 0;
- $tmp = $result->fetchRow( DB_FETCHMODE_ASSOC );
-
- $day = date( "D d", strtotime($end_date) );
-
- if( isset( $tmp['stored_bytes'] ) ) {
- $hbytes = $this->human_file_size( $tmp['stored_bytes'], 3, 'GB');
- $hbytes = explode( " ", $hbytes );
- $stored_bytes = $hbytes[0];
- }
-
- return array( $day, $stored_bytes );
- }
- }
-
- public function GetStoredBytesByJob( $jobname, $start_date, $end_date )
- {
- $query = "SELECT SUM(JobBytes) as stored_bytes, EndTime FROM Job ";
- $query .= "WHERE ( EndTime BETWEEN '$start_date' AND '$end_date' ) AND ";
- $query .= "Name = '$jobname'";
-
- $result = $this->db_link->query( $query );
-
- if( PEAR::isError( $result ) ) {
- die( "Unable to get Job Bytes from catalog" );
- }else{
- $stored_bytes = 0;
- $tmp = $result->fetchRow( DB_FETCHMODE_ASSOC );
-
- $day = date( "D d", strtotime($end_date) );
-
- if( isset( $tmp['stored_bytes'] ) ) {
- $hbytes = $this->human_file_size( $tmp['stored_bytes'], 3, 'GB');
- $hbytes = explode( " ", $hbytes );
- $stored_bytes = $hbytes[0];
- }
-
- return array( $day, $stored_bytes );
- }
- }
-
- public function GetStoredFilesByJob( $jobname, $start_date, $end_date )
- {
- $query = "SELECT SUM(JobFiles) as stored_files, EndTime FROM Job ";
- $query .= "WHERE ( EndTime BETWEEN '$start_date' AND '$end_date' ) AND ";
- $query .= "Name = '$jobname'";
-
- $result = $this->db_link->query( $query );
-
- if( PEAR::isError( $result ) ) {
- die( "Unable to get Job Files from catalog" );
- }else{
- $stored_bytes = 0;
- $tmp = $result->fetchRow( DB_FETCHMODE_ASSOC );
-
- $day = date( "D d", strtotime($end_date) );
- $stored_files = $tmp['stored_files'];
-
- return array( $day, $stored_files );
- }
- }
-} // end class Bweb
-?>
+++ /dev/null
-<?php
-
- class BW_Config {
-
- private $config_params;
- private $config;
- private $catalogs = array();
-
- function __construct()
- {
- global $config;
- $this->config = $config;
- }
-
- public function Check_Config_file()
- {
- // Check if config file exist and is readable
- return is_readable( CONFIG_FILE );
- }
-
- public function Load_Config()
- {
- global $config;
-
- if( is_array($config) && !empty($config) ) {
- // Loading database connection information
- foreach( $config as $parameter => $value )
- {
- if( is_array($value) ) // Parsing database section
- array_push( $this->catalogs, $value );
- }
- return true;
- }else {
- return false;
- }
- }
-
- public function Get_Config_Param( $param )
- {
- if( isset( $config[$param] ) )
- return $config[$param];
- }
-
- public function Get_Catalogs()
- {
- $result = array();
- foreach( $this->catalogs as $db )
- array_push( $result, $db['label']);
-
- return $result;
- }
-
- public function Count_Catalogs()
- {
- return count( $this->catalogs );
- }
-
- public function Get_Dsn( $catalog_id )
- {
- // Construct a valid dsn
- $dsn = array();
- $dsn['hostspec'] = $this->catalogs[$catalog_id]["host"];
- $dsn['username'] = $this->catalogs[$catalog_id]["login"];
- $dsn['password'] = $this->catalogs[$catalog_id]["password"];
- $dsn['database'] = $this->catalogs[$catalog_id]["db_name"];
- $dsn['phptype'] = $this->catalogs[$catalog_id]["db_type"];
- return $dsn;
- }
-
- function __destruct()
- {
-
- }
-
- } // end classe BW_Config
-
-?>
+++ /dev/null
-<?php
-
-?>
+++ /dev/null
-<?php
-
-?>
+++ /dev/null
-<?php
-
-?>
+++ /dev/null
-<?php
-
-?>
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-\f
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
+++ /dev/null
-This is the Change Log for PHPlot.
-The project home page is http://sourceforge.net/projects/phplot/
------------------------------------------------------------------------------
-
-2011-01-15 (lbayuk) ===== Released as 5.3.1 =====
- * phplot.php: Updated version
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
-
-2011-01-09
- * Fixed some style / indent errors, and 1 redundant test.
-
-2011-01-03
- * For bug 3143586 "Multiple plots per image - fixes & docs":
- Make sure there is a documented way to reset PHPlot feature
- settings, especially those for which the default settings result
- in automatic calculated values. Where possible, calling a Set*()
- function with no arguments should reset the feature to defaults.
-
- + Changed SetLegendPixels() arguments to be optional with default
- NULL meaning reset to automatic positioning.
-
- + Fixed SetXAxisPosition() and SetYAxisPosition() to accept empty
- string '' to mean reset to default automatic positioning.
- Make arguments optional, defaulting to empty string.
-
- + Changed SetNumXTicks() and SetNumYTicks() arguments to be
- optional with default empty string '' meaning reset to
- of automatic calculation.
-
- * Changed SetPointShapes() to use CheckOptionArray(). This
- simplifies the function with no change in operation.
-
- * Extend copyright years to 2011.
-
-2010-12-30
- * Fix for bug 3147397 "Data colors missing with multiple plots":
- + Do not truncate the data_colors and related arrays, so the full
- set of colors will be available for subsequent plots on the image.
- (Color indexes are still allocated in the image only as needed.)
- + New internal functions GetColorIndexArray() and
- GetDarkColorIndexArray(), replacing previous use of array_map().
- + Removed internal function truncate_array() - no longer used.
- + Changed SetColorIndexes(), NeedDataDarkColors(), and
- NeedErrorBarColors() to only allocate the color indexes that will
- be needed (instead of allocating all colors in the truncated color
- descriptor arrays).
-
-2010-12-28
- * Instead of throwing an error, SetLegend(NULL) now clears the legend
- array. This can be useful with multiple plots on an image. Before
- this change, only SetLegend(array()) did that (possibly by accident).
-
-2010-12-27
- * Do not have SetDefaultStyles() call deprecated SetLabelColor().
-
- * Fixes for bug 3143586 "Multiple plots per image - fixes & docs":
- + Fix DrawLegend so it doesn't forget that the legend position
- was specified in world coordinates. This fixes the legend
- position for plots after the first.
- + Don't draw the image border more than once (although this would
- probably have no impact on the resulting image). This parallels
- the behavior for the main plot title and the image background.
- Replaced member variables background_done and title_done with a new
- member array done[] which will track when these elements were done.
-
-2010-12-06
- * Fix comments above CalcPlotAreaWorld(). Deleted incorrect information
- from before data-data-yx existed, and before DecodeDataType rewrite.
-
-2010-12-04 (lbayuk) ===== Released as 5.3.0 =====
- * phplot.php: Updated version
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
-
-2010-12-03
- * Feature request 3127005 "Ability to suppress X/Y axis lines":
- Added SetDrawXAxis() and SetDrawYAxis() to control flags which
- will suppress drawing the X or Y axis lines. (These lines were
- probably the only PHPlot elements that could not be turned off.)
- Changed DrawXAxis() and DrawYAxis() to conditionally draw the
- axis lines.
-
-2010-11-28
- * Feature request 3117873 "Data value labels in more plot types":
- Implemented Data Value Labels for plot types points, lines,
- linepoints, and squared. Added 2 class variables which can be
- set to control the distance and angle of the labels from points.
- New internal function CheckDataValueLabels() calculates position
- and text alignment for these labels.
-
- * Updated comments for Set[XY]DataLabelPos to match the text in
- the manual, which was rewritten to clarify label types.
-
-2010-11-23
- * Code cleanup. Moved some functions around to group "plot drawing
- helpers" separately from "plot drawing". No changes to operation.
-
-2010-11-21
- * Feature request 3111166 "Control legend colorbox width":
- Added a class variable legend_colorbox_width which can be changed
- to make the colorboxes wider or narrower.
-
-2010-11-16
- * Feature request 3093483 "Investing support chart types":
- Added 3 new plot types: Basic OHLC (Open/High/Low/Close), Candlesticks,
- and Filled Candlesticks. Implemented with one new function to handle the
- 3 new plot types: ohlc, candlesticks, and candlesticks2.
-
-2010-11-11
- * Moved information about plot types into a new static member array
- plots[]. (This is an internal change with no impact on usage, but will
- make it easier to add new plot types.) SetPlotType() no longer needs a
- list of plot types to check, FindDataLimits() does not need to check for
- specific plot types to to process the data array, and DrawGraph() uses
- data from the array rather than knowing about all the plot types.
-
-2010-10-31
- * Changed internal CalcBarWidths() to take two arguments which indicate
- how it should calculate bar widths, rather than having it check the
- plot_type directly. (Taken from another, experimental change. This
- minimizes places where plot_type is directly used.)
-
-2010-10-03 (lbayuk) ===== Released as 5.2.0 =====
- * phplot.php: Updated version
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
- * Makefile: Removed HorizontalBars.txt from release. This is now all
- documented in the reference manual.
-
-2010-10-01
- * Rewrite color handling. Default and specified colors are now validated,
- converted to RGBA arrays, and saved. The colors indexes are not
- allocated until graph drawing time. Unneeded colors are not allocated.
-
- Fix bug 3045131 "SetTransparentColor problems": Transparency setup is
- deferred to graph drawing time, after most other colors are allocated.
- Fixes SetTransparentColor order dependency, and works with data colors.
-
- Fix bug 3049726 "Optimize color allocation": Colors allocation is
- deferred to graph drawing time, and colors for most elements are only
- allocated if needed. In particular, the data colors and dark colors,
- which used 32 slots, now only get defined as needed.
-
- Feature request (partial) 3077554 "Finer control over plot element
- colors": The colors of the main, X, and Y titles can now be controlled
- separately.
-
- Change details:
- New internal functions:
- GetColorIndex(), GetDarkColorIndex()
- Allocate pre-parsed colors for elements.
- SetColorIndexes()
- Does the deferred color allocation and defaults.
- NeedDataDarkColors(), NeedErrorBarColors()
- Called by graph drawing functions if those colors are needed.
- GetDataColor(), GetDataErrorColors(), GetBarColors()
- Custom or standard data color assignment for most plot types.
- truncate_array()
- Shorten an array. Used to limit data color allocation.
-
- Removed internal functions:
- SetIndexColor(), SetIndexDarkColor()
- Unneeded. Color handling is now in two separate phases.
-
- Removed internal member variable:
- data_colors_alpha
- PHPlot no longer calls SetDataColors before plotting, so this
- variable is not needed to preserve the default alpha.
-
- New internal member variables:
- transparent_color
- Saves color value from SetTransparentColor. For bug 3045131.
- x_title_color, y_title_color, ndx_x_title_color, ndx_y_title_color
- For title colors. DrawXTitle and DrawYTitle use them now.
-
- Changed internal member variables:
- i_border, plot_bg_color, bg_color, label_color, text_color, etc.
- All variables for colors now always hold a parsed 4-component
- (RGBA) color specification as an array, and are no longer
- statically initialized to a color name.
-
- New public functions:
- SetXTitleColor(), SetYTitleColor()
- These can be used to make the 3 titles have different colors.
-
-2010-09-26
- * Don't let SetXDataLabelPos() accept 'xaxis' or 'all' as valid.
- Don't let SetXTickLabelPos(), SetYTickLabelPos() accept 'all' as valid.
- These were never implemented and never documented.
-
-
- * Feature request #3073679 "Stacked bar plots with negative values":
- Allow stacked bar plots (vertical and horizontal) to work with negative
- values. Changed FindDataLimits() to not take abs() values for
- stackedbar when calculating the data range. Changed DrawStackedBars()
- and DrawHorizStackedBars() to handle negative values, including proper
- label positions. The first non-zero value in a row sets the direction
- of the bar. Mixing positive and negative values within a row works but
- the results are not useful.
-
- * New internal DrawBar() moves common code from 4 bars and stackedbars
- drawing functions and makes it easier to deal with shading vs bar
- direction.
-
-2010-09-24
- * Fix bug 3074402 "Fix Y axis default for horizontal plots":
- Make the default axis positions symmetrical for vertical plots
- (X and Y) and horizontal plots (Y and X). This fixes the problem
- with horizontal bar/thinbarline plots that have negative data,
- where the Y axis stayed on the left and the bars went rightward.
-
-2010-09-01
- * Fix bug 3056991 "Internal methods should be 'protected'":
- Changed CheckDataArray(), number_format(), FindDataLimits(), and
- DrawBackground() to be 'protected'. The test suite no longer calls
- these directly. For SetIndexColor(), SetRGBColor(), DrawText(),
- SizeText(), xtr(), and ytr(), left these as public with a comment
- indicating they should be treated as protected.
-
- * Fix bug 3057000 "Review 'deprecated' methods":
- + Changed deprecated method SetNewPlotAreaPixels() to just call
- SetPlotAreaPixels(). It was suspicious as coded, and was found
- to be equivalent to SetPlotAreaPixels().
- + Removed SetColor(), which didn't do anything. It was calling
- SetRGBColor and discarding the result. After reviewing the
- history of this in all CVS versions, it does not seem to have
- ever been coded correctly, so there is no harm in removing it.
- + All other deprecated methods seem OK and are left as is.
-
-2010-08-30 (lbayuk) ===== Released as 5.1.3 =====
- * phplot.php: Updated version
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
-
-2010-08-27
- * Fix bug 3051832 "Let PHP/GD find the font file":
- Instead of checking for file existence, PHPlot now uses a non-drawing GD
- operation to validate a TrueType font in SetFontTTF(). This allows GD to
- use its internal search path, making it likely that fonts can be found
- without needing a platform-dependent path in your script. Full paths
- will still work, so there is no compatibility issue.
-
- * Fix bug 3051906 "Better choice for default TT font":
- Removed "benjamingothic.ttf" as the default TT font setting. This has
- not been included in PHPlot since 2004. Changed SetFontTTF() to call
- new GetDefaultFontTTF(), which will try a number of sans-serif font
- names the first time it needs a default TT font. Considering the above
- fix to finding fonts, this has a good chance of finding a working
- font. It is known to work on Windows and some Linux distributions.
-
-2010-08-19
- * Makefile: Removed phplot_data.php from list of files to release.
- Reference bug report 3048267. This file has not been maintained or
- tested, and has bugs. It will remain in CVS, but not be included
- in PHPlot releases.
-
-2010-08-17
- * Change new DrawLinePoints(). It does not have to check and
- handle error bar plots, as DrawDots and DrawLines will do that.
-
-2010-08-16
- * Rewrote DecodeDataType(). Previous implementation was hard to
- extend and inefficient. Now it uses new class variables (not a
- returned array) and is only called once, by DrawGraph. Changed all
- users of data_type to use the new variables.
-
- In CheckDataArray(), calculate data_columns properly for
- text-data-single data type (pie chart) too. Simplify DrawPie
- to use this, and merge 2 of the 3 cases.
-
- Have a single function handle each plot type, so it can properly
- check the data type and report a correct error message showing
- all supported types. For example, DrawBars is now the entry point
- for both bars and horizontal bars; DrawGraph does not directly
- call DrawHorizBars. Similar for DrawStackedBars and
- DrawHorizStackedBars. Lines, Points, and Linepoints also now
- have a single function each, dispatching to others as needed.
- (These changes were split off from an upcoming, larger change.)
-
-2010-08-14
- * Fixes to SetDataValues: need to clear out the 2 arrays before
- setting values in a loop, else if the function is used more than
- once then old values will remain.
- Move records_per_group calculation outside the loop.
- (These were split off from upcoming, larger changes.)
-
- * Part 4 of horizontal plots: implement horizontal thinbarline plots.
- Added new data type 'data-data-yx' (label, Y, X1, X2, ...).
- DrawThinBarLines() now draws either vertical or horizontal plots, and
- supports data types text-data, data-data, text-data-yx, data-data-yx.
-
- Fixed DecodeDataType() to handle text-data-single too, for completeness.
-
- * Fix for over-padding style and color arrays. These were padded to
- records_per_group, but that is the maximum data array row size.
- The number of actual data sets is less, and depends on the data type.
- Calculate the correct number as data_columns at the top of DrawGraph,
- and use that to pad the arrays. Also moved early error checking in
- DrawGraph() into new CheckDataArray().
-
-2010-08-09
- * Code cleanup. This is a large change to unify the comment and
- coding stye used in PHPlot. The PEAR style guide is being used
- as a reference, but PHPlot will never be 100% compliant.
- This patch introduces no functional changes at all.
- - Limit line length to 110.
- - Remove obsolete, partially implemented Doxygen comments.
- - Add descriptive comment above functions where missing.
- - Use consistent comment markers and control structure spacing.
- - Remove ctags-confusing end of function comments.
- - Rewrote a few if/else blocks for cleaner logic.
- - Re-order some functions for consistency (X, then Y).
-
-2010-08-04
- * Implemented horizontal stacked bar plots:
- Use the same data type introduced for horizontal bars, 'text-data-yx',
- and the same plot type 'stackedbars', to make a horizontal stacked bar
- plot. Data value labels, both at the ends of the bars and within the
- bars ('plotstack' labels) are available with horizontal stacked bars.
-
- * Internal function DrawDataLabel() is replaced by DrawDataValueLabel(),
- with different usage. The new function can also check to see if a label
- fits in the allocated space.
-
- * Fixed the text size check in stacked bar plots for data value labels
- within the bars. The check only worked correctly for 0 degree labels. It
- now works with any text angle. It suppresses the label if it is too high
- (for vertical stacked bar plots) or too wide (for horizontal stacked bar
- plots) to fit in the bar segment to which it belongs. Note that it only
- checks in the bar direction. If the text is too wide (for vertical bars),
- or too high (for horizontal bars), it will still be plotted, but will
- cross the sides of the bar.
-
-2010-07-28
- * Allow callbacks to return a value (to support new data_color callback).
- * Feature request 3034164 "Extended control of data colors":
- Define new callback 'data_color' for picking the data color.
- Changed internal plot drawing functions DrawDots, DrawLines, DrawSquared,
- DrawBars, DrawStackedBars, DrawDotsError, DrawThinBarLines,
- DrawLinesError, and DrawHorizBars to use the data_color callback
- (if defined) to select the data colors.
- * SetRGBArray code cleanup (no functional changes).
-
-2010-07-27
- * Fixes for error bars:
- Code cleanup in DrawYErrorBar(), with no functional change.
- Suppress duplicate drawing of error bars with 'linepoints' error plots.
- This was already fixed for data labels. Now error bars will only be
- drawn by the 'points' part, not the 'lines' part. There should be no
- visible changes to plots. (This is needed for a future change).
-
-2010-07-26
- * Horizontal bar charts (still an experimental feature) can now have data
- value labels.
- * HorizontalBars.txt: Fix incorrect description of bar direction. Add
- text explaining the new data value labels.
-
-2010-06-29 (lbayuk) ===== Released as 5.1.2 =====
- * phplot.php: Updated version
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
-
-2010-06-26
- * Feature request 2885930 "Horizontal Bars":
- Horizontal bar charts are implemented, as an experimental feature.
- A new data type 'text-data-yx' was added, which works with
- 'bars' plot type to produce a horizontal bar chart from a data
- array with X values for each Y value. Changes were made to
- FindDataLimits, CalcMargins, CalcPlotAreaWorld, CalcBarWidths,
- and CalcMaxDataLabelSize to handle the new data type. Other
- changes were made to handle label position defaults and grid
- defaults. New drawing functions were added for horizontal bars.
-
- * HorizontalBars.txt: new documentation file for experimental feature.
- * Makefile: List new documentation file.
-
-2010-06-25
- * Each plot-type drawing function now checks that it is getting a data
- type that it knows how to handle. A new internal function unifies the
- checking and error message. (This is associated with an upcoming,
- bigger change.)
-
- Compatibility: If you were using an invalid data type for a plot type
- whose function did not check, will now get an error.
-
- * Removed some dubious code from DrawLines() and DrawSquared() and
- rewrote comments there. The code initialized lastx[0] and lasty[0],
- but lasty was mapped using the X (rather than Y) function. This was
- obviously wrong, but closer inspection showed that the values were
- never, used so the code was removed.
-
-2010-06-13
- * Truecolor.txt: removed
- * Makefile, README.txt: Removed reference to Truecolor.txt. Full
- documentation for truecolor images is now in the Reference Manual.
-
-2010-06-02
- * Fix bug 3010116 "Bad rendering of title in multi-plot image
- when using TTF":
- Make sure the main title is drawn only once. (If drawn multiple
- times with TrueType font text, the anti-aliasing effects result
- in poor quality text.)
-
-2010-05-31
- * Improvements to truecolor support (from feature request 2947679):
- Truecolor support is now better integrated. The derived class only
- has the constructor now, and the base class itself provides the alpha
- color component support through the internal functions SetIndexColor(),
- SetIndexDarkColor(), and SetRGBColor(). This means alpha channel
- works with palette images too (in so far as GD supports this).
-
- * Truecolor.txt: Updated per changes to truecolor support.
-
- * Image tiling with mode 'scale' in tile_img(), used with image and
- plot area backgrounds, now uses imagecopyresampled() rather than
- imagecopyresized(). They are the same with palette images, but the
- resampled copy gets better results with truecolor images.
-
-2010-05-29
- * Feature request 3002606 "Add to plot and image border options":
- Added options 'right', 'top', and 'bottom' to SetPlotBorderType()
- (existing options are 'left', 'sides', 'none', and 'full'). This
- now also accepts an array of the above options, giving complete
- control over which sides to draw.
- Added option 'solid' to SetImageBorderType() to use the actual
- color set with SetImageBorderColor(), rather than the darker
- shade as type 'plain' does (for some reason).
- New function SetImageBorderWidth() sets the width of the image
- border. The image border width is now accounted for in margin
- calculations, although existing plots will not change.
-
-2010-04-04 (lbayuk) ===== Released as 5.1.1 =====
- * phplot.php: Updated version
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
-
-2010-04-01
- * Remove & from argument in SetDataValues(). The data array is not
- modified and does not need to be passed by reference. (There is
- no performance advantage, either.)
-
-2010-03-29
- * Feature request 2947679 "Support for alpha blending/Truecolor":
- Implemented truecolor image support with a new class
- PHPlot_truecolor, extended color specifications to allow
- specification of an alpha value, and added a new optional parameter
- to SetDataColors for a default alpha value for all data colors.
- This feature is *EXPERIMENTAL* (see next item).
-
- * Truecolor.txt: New file, documentation for the new truecolor capability.
- (The Truecolor feature is experimental, which means it is subject to
- change in incompatible ways and the documentation has not yet been
- incorporated into the PHPlot Reference Manual.)
-
- * Makefile: Include new documentation file in release.
-
-2010-03-26
- Fixed bug 2976735 "Improvements and fixes for 'area' plots":
- Rewrote DrawArea() function which handles 'area' plot.
- Part 1: This is related to feature request 2947679, Truecolor support
- with transparency. The area plot function was filling each area from the X
- axis up to the Y value, resulting in area overlaps. This wasn't a problem
- with opaque colors, but with transparency, the overlapping areas resulted
- in changed colors. The rewritten function fills the area between each line
- instead of from each line down to the X axis. Plots with opaque colors
- will not change.
- Part 2: Area plots now work when the X axis is moved up with
- SetXAxisPosition().
- Part 3: Fixed FindDataLimits() for area (and stackedbars too) to
- take absolute values of Y values. The drawing function was doing this,
- but not FindDataLimits, resulting in incorrect limits if any Y<0.
- Part 4: The rewritten DrawArea() also handles a new plot type
- 'stackedarea'. This is an area plot where the Y values are stacked,
- similar to 'stackedbars'.
- Note: As part of the changes, it is now an error to try an area plot
- with an unequal number of Y points for each X.
-
-2010-03-23
- * Feature request 2973995 "Add y-Data to Stackedbars":
- Implemented Y Data Labels for Stacked Bar charts (stackedbars).
- The labels are enabled with SetYDataLabelPos, same as with bar charts.
- There are two types of labels: above the stack with the total, and
- within the bars at each segment. 'plotin' turns on the upper ones, and
- 'plotstack' turns both on.
-
- * Other changes:
- + Removed unimplemented second argument to SetYDataLabelPos.
- + Fixed questionable logic in SetYDataLabelPos when given an argument
- that belongs with SetYTickLabelPos.
- + Fix comments at top of plot-type Draw functions.
-
- * Fix for bug 2974639 "Stacked bars plot breaks with X axis != 0":
- Stacked bar plots with non-zero X axis position no longer break apart
- into segments with gaps. The bars are drawn up from the X axis, and
- any segments or partial segments below the X axis are not drawn.
-
-2010-03-22
- * Change related to feature request 2947679 - Fix 'dot' point shape:
- Use imagefilledellipse(), not imagefilledarc(), when drawing the 'dot'
- point shape. The fix was needed for future support of truecolor images
- with transparency, but filled dots from imagefilledellipse() look
- better (rounder) with regular images and opaque colors.
- Credit to mvaldez for identifying the problem and providing the fix.
-
-2010-03-04
- * Fix for bug 2963757 "point_counts undefined error in 5.1.0":
- Fixed CheckPointParams so it sets point_counts even when the point shape
- and point size arrays are already the same size and do not need padding.
-
-2010-01-26
- * Fix for bug 2938219 "Bars go in wrong direction":
- Fixed CalcAxisPositions() to be consistent in positioning the X axis.
- When all Y values are <0 and the Y=0 line is not part of the plot range,
- PHPlot will now default the X axis to the top of the plot, not the
- bottom. This fixes the problem with bars to negative Y values being
- drawn downward if Y=0 is visible, but upward if Y=0 is not visible.
- This also affects thinbarline plots.
- Credit to lauryn1298 for finding the bug.
-
-2009-12-24 (lbayuk) ===== Released as 5.1.0 =====
-
-2009-12-18
- * Change for bug 1795971 "Fix default data colors":
- The default Data Color and Error Bar Color arrays now have 16
- different colors, no duplicates, and nothing so light that it
- is invisible.
- Using '' or False as the argument to SetDataColors, SetErrorBarColors,
- and SetDataBorderColors now re-initializes the map to the defaults.
- This was previously undocumented, and in some cases set the map to
- something different from the default.
-
-2009-12-15
- * Cleanup: Remove DrawAxisLegend() - empty function marked TODO,
- not really clear what it was meant to do.
-
-2009-12-14
- * Fix for bug 2914403 "Pie + X/Y titles: Undefined property error":
- In DrawGraph(), don't try to draw X or Y titles for pie charts.
-
- * Feature request 2899921: "allow different format for data and tick
- labels"; Bug 2906436: "Fixes for X Tick Labels vs X Data Labels",
- and partial implementation of changes from user 'adoll' regarding
- tick vs data labels:
-
- New public functions:
- + SetXDataLabelType() : Sets formatting for X Data Labels
- + SetYDataLabelType() : Sets formatting for Y Data Labels (bar charts)
- + SetXDataLabelAngle() : Sets text angle for X Data Labels
- + SetYDataLabelAngle() : Sets text angle for Y Data Label (bar charts)
- The defaults for these are set up to be fully backward compatible
- with previous releases of PHPlot (except see the next item).
-
- Re-used function name SetXDataLabelAngle():
- + This has been deprecated and undocumented since 2003-12-07, and
- used to just call SetXLabelAngle(). For new behavior, see above.
-
- Changes to public functions:
- + SetXDataLabelPos() and SetXTickLabelPos() no longer cancel each
- other out (set the other control variable to 'none'). Instead,
- they are both considered before plot drawing.
-
- Changes to internal functions:
- + DrawDataLabel() now uses the font, angle, and color arguments as
- provided, and does not substitute values if they are empty.
- + SetLabelType() now takes mode='xd' and 'yd' for X Data and Y Data
- label formatting; 'x' and 'y' are for tick labels only now.
- + Functions that work on Data labels now call FormatLabel() with the
- new mode parameter value 'xd' or 'yd, and use the new
- data_label_angle variables.
- + New CheckLabels(), used by DrawGraph to process label parameters.
- + CalcMargins() - Rewritten to handle changes to Tick and Data labels.
-
- Changes to internal class variables:
- + New: x_data_label_angle, y_data_label_angle
- + Do not initialize x_tick_label_pos or x_data_label_pos, so that
- CheckLabels() can tell if they were set or not and apply defaults.
- + Initialize y_data_label_pos to 'none', not 'plotleft'.
- + Add 2 more indexes to label_format[] array: 'xd' and 'yd'.
-
- * Cleanup:
- + Delete unused internal class variable: draw_y_data_label_lines
- + Delete unused function SetDrawYDataLabelLines()
-
-2009-12-07
- * Fix bug 1795972 "Fix default point shapes":
- + Added 10 new point shapes to the existing 10 shapes.
- + Changed the default point shape from all 'diamond' to a
- selection of up to 10 different shapes.
- + Fixed bug in the code that tried to set the point shapes
- and sizes arrays to be the same size. This was not working,
- resulting in unexpected point sizes.
- + Changed default point size to 6 for all shapes. It was trying
- to be "5, 5, 3" but due to several bugs this was not working.
- + Do not adjust shape sizes to even numbers (was done for only two
- shapes). Instead, consistently truncate size/2 when needed.
- NOTE: These may change the look of 'points' and 'linepoints' plots.
-
- * Changed startup initialization code:
- + SetDefaultStyles() was doing some odd things using a variable
- called "session_set", with comments referring to non-existent
- session support code. This has been removed. There should be
- no visible changes from this. PHPlot does not use PHP sessions.
-
-2009-12-04
- * Fix for bug 2908256, errors in pie charts with bad data array:
- (From a Drupal contrib module report by thekevinday.)
- With pie charts only, a data array with no valid Y values resulted
- in PHP error messages. All other plot types handle this by producing
- an image without a graph.
- Fixed DrawPieChart to behave this way too. If there are no valid Y
- values, or if the sum of all Y values is 0, do not error out, but
- don't draw a pie chart either.
- Also, pie charts now ignore non-numeric Y values, like other plot types.
-
-2009-11-20 (lbayuk)
- * Fix for bug 2900914 "Problem with display of 0 on Y axis":
- Changed how X and Y values are stepped by tick intervals, to avoid
- cumulative round-off error. This fixes the problem when Y crosses 0 with
- a tick step such as 0.1 resulting in a long label for a very small but
- non-zero number. Fixed DrawXTicks, DrawYTicks, and CalcMaxTickLabelSize.
- (Originally reported by cncnet)
-
-2009-11-19 (lbayuk)
- * Improve support for using callbacks to annotate plots:
- Added new callback 'draw_all', called after all drawing.
- Supply plot_area[] as argument to some drawing callbacks.
- Added new method GetDeviceXY() to translate from world coordinates.
- Allow NULL or '' for $font in DrawText() internal method, meaning to
- use the generic font. If callbacks want to use DrawText, this
- avoids them having to reference the internal fonts[] array.
-
-2009-11-01 (lbayuk)
- * Address bug report 2886365 "Declare all functions and variables in
- PHP5 style"
- PHP5 deprecates the use of 'var' to declare a class member variable.
- All initialized class member variables are now declared 'public'.
- (It was tempting to make most or all 'protected' or 'private', but
- that would likely break too much, including the PHPlot Test Suite.)
-
- Most class member functions which are meant for internal use only are
- now declared 'protected', so they cannot be called from scripts
- (except in child classes). (Note PHP5 does not deprecate the use of
- just 'function' to mean public, so public functions were not changed.)
- Internal functions are those documented in the manual under Developer's
- Guide, Internal Functions. If your code breaks because you are using
- a method which is now protected, please post the details on the help
- forum.
-
- Some member variables which were set in the constructor are now
- initialized with the class instead. (No impact.)
-
- Removed commented-out, FIXME-noted code for interim labels.
-
-2009-10-12 (lbayuk)
- * Bug report 2839547, allow SetImageBorderType('none') to reset the image
- border type. Also checked for other cases where there is no reset;
- found one that exists (Set[XY]LabelType) but needs to be documented.
-
-2009-07-09 (lbayuk)
- * Added a hook $plot->locale_override which can be set to True to prevent
- PHPlot from loading locale settings from the environment with
- setlocale(LC_ALL, ''). This is necessary for testing PHPlot on Windows,
- where you cannot force a locale with an environment variable. It might
- also be needed for people who want PHPlot's locale to differ from the
- web server's locale.
-
-2009-06-12 (lbayuk) ===== Released as 5.0.7 =====
-
-2009-06-11 (lbayuk)
- * Change PHPlot license to LGPL, per Afan.
- phplot.php, phplot_data.php - Change license notice.
- rgb.inc.php - Change top comments and remove bottom marker.
- COPYING - new file, text of LGPL.
- LICENSE.* - removed files - old licenses.
- Makefile - change list of distributed files.
-
- * Fix for bug 2803900: SetRGBArray('large') does not work. The include
- file defined a different array name than the main script expected.
- (This bug seems to have happened over 8 years ago.) Fixed the array
- names to match. Also removed the ./ prefix from the included filename
- so it will be found if on the include path but not in the script
- directory. Also added error check if the rgb.inc.php include file
- is needed and not found.
-
-2009-05-25 (lbayuk)
- * Added new feature to allow partial margin or plot area specification.
- You can omit, or specify as NULL, any of the 4 arguments to
- SetMarginsPixels() or SetPlotAreaPixels(), and this means PHPlot
- should use the automatically calculated margin on that side.
- Credit to adoll for this feature.
-
-2009-05-17 (lbayuk)
- * Fix for bug 2791502 "Error plots treat missing Y values as 0":
- Plots with data type data-data-error now support missing Y values,
- instead of treating them as 0. This works with lines, points,
- and linepoints plot types, and also honors SetDrawBrokenLines.
-
-
- * Fix for bug 2792860 "Wrong DataLabelLines with missing Y":
- Do not draw X Data Label Lines at points with missing Y values.
-
-
- * Fix for bug 2786350 "Missing Y data results in bad auto-range":
- Rewrote FindDataLimits to ignore missing Y values, rather than
- treating them as if 0, for calculating range.
- Bug report and analysis by mrten.
-
- * Fix for bug 2786354 "Incorrect auto-range for data-data-error":
- For data-data-error data type, apply the positive and negative error
- amounts for each Y point to that point only, rather than applying the
- largest errors to the overall minimum and maximum Y value for the row.
-
- Note: The two fixes above can change existing plots which rely on
- automatic Y range calculation. The first fix affects plots with
- missing Y values and min(Y)>0. The second fix can affect plots using
- data-data-error data type and different error values for different
- points. In both cases the new Y range can be smaller than before.
-
-2009-01-20 (lbayuk) ===== Released as 5.0.6 =====
-
-2009-01-18 (lbayuk)
- * Fix for bug 1891636 "Misaligned TTF X Labels":
- PHPlot was using the actual bounding box of each line of text
- to allocate space and set the text positioning, but was ignoring the
- fact that the text baseline is not the same as the bottom of the
- bounding box. This resulted in uneven alignment of the X labels if
- they had different heights (for example, month names Jul and Aug).
-
- PHPlot now calculates the size of text for allocation (SizeText) using
- the descenders on the last line, and calculates the size for drawing
- (DrawText) only to the baseline. PHPlot also now uses a fixed line
- spacing for each line of text in a font, rather than the actual text
- height. This allows separately drawn multi-line labels to align.
-
- * Changes to line spacing when using multi-line labels:
- PHPlot was using the class variable line_spacing to mean the
- number of pixels between lines of multi-line labels. This made the
- spacing too small for larger fonts, and it was not possible to adjust
- line spacing for different types of text.
-
- PHPlot now interprets line_spacing as the number of pixels only
- for GD text, and as a scale factor for the font's built-in line
- spacing for TrueType text. In addition, a new optional argument is
- added to SetFont, SetFontGD, and SetFontTTF to set a line spacing
- specific to that type of text.
-
- * Changes had to be made to the legend drawing code to accommodate the
- changes to font handling.
-
- Note: The line spacing change results in slightly looser spacing on
- multi-line TrueType text labels, and slightly taller legends, compared
- to version 5.0.5.
-
-2008-09-21 (lbayuk)
- * Interim fix for bug 1932571 "Data-Data Plot fails with same X values".
- PHPlot will no longer hang when the range of X values is 0 (that is, when
- x_min == x_max). It will arbitrarily set an X range of 1, so the
- calculated tick step is not 0. This is a temporary fix. Work on a smarter
- X and Y range calculation is in progress, which will handle edge cases
- like this better, but it isn't ready and this bug has been open too long.
- Credit to andyl for finding the bug.
-
- * Fix font path: Use DIRECTORY_SEPARATOR constant not '/'.
-
- Extended the label formatting capabilities, adding 'printf' and 'custom'
- types, added a prefix and suffix for 'data' type, and allow format controls
- to be included in SetXLabelType and SetYLabelType.
-
- External changes:
- * Added 'printf' label type. The caller specifies the print format as the
- 2nd argument to SetXLabelType or SetYLabelType (default '%e').
- $plot->SetXLabelType('printf', '%5.2f');
-
- * Added 'custom' label type. The caller supplies a callback (typically a
- function name) and optional pass-through argument as the 2nd and 3rd
- arguments to Set[XY]LabelType. The function is called as $f($value, $arg)
- to return the formatted $value.
- $plot->SetXLabelType('custom', 'myfunction', $arg_value);
-
- * In addition to Set[XY]TimeFormat, the format string for type 'time' can
- now be set as the 2nd argument to Set[XY]LabelType.
- $plot->SetXLabelType('time', '%H:%M');
-
- * In addition to SetPrecision[XY], the precision for type 'data' can now be
- set as the 2nd argument to Set[XY]LabelType. A 3rd and 4th argument
- can supply a prefix and suffix for 'data' formatting. (All optional)
- $plot->SetXLabelType('data', 2, '$', 'US');
-
- Internal changes:
- * Class variables x_precision, y_precision, x_label_type, y_label_type,
- x_time_format, and y_time_format have been removed.
-
- * New class array variable label_format[], with elements 'x' and 'y' which
- are arrays for label formatting. Elements in the sub-arrays are not
- initialized until needed.
-
- * New function SetLabelType, which implements Set[XY]LabelType now.
-
- * FormatLabel() was rewritten to support the new label formatting.
-
- Compatibility:
- * Any code that directly references class variables related to label
- formatting will break, except for data_units_text. Use the documented
- function methods instead. Setting data_units_text as a suffix is
- deprecated but still works.
-
- * The 'data' type precision for 'Y' is still used for pie chart labels.
-
-2008-07-12 (lbayuk)
- Multiple comment spelling error fixes. No functional changes.
-
-2008-07-06 (lbayuk)
- Changes to allow mixing GD fixed-font text and TrueType Font (TTF) text
- on the same plot.
- (This change came from work done trying to fix TTF text positioning,
- where it looks like additional information needs to be stored for TrueType
- fonts. The old font data structure was awkward to extend, and allowing
- mixed GD/TTF text was on the to-do list anyway.)
-
- External changes:
- * SetFontGD(), SetFontTTF(): New functions to set a font, with type.
- * SetFont(): Now calls SetFontGD or SetFontTTF depending on $use_ttf.
- These changes should be fully compatible with existing programs.
-
- Internal changes:
- * Updated comments explaining SetUseTTF() now sets the default type
- (not the only type) of text used.
- * Put all the font data into a class array. (Replaces $this->generic_font
- with $this->fonts['generic'], etc.)
- * ProcessTextGD() and ProcessTextTTF() now take the font array as one
- argument, rather than separate arguments for font path and size.
-
-2008-01-13 (lbayuk) ===== Released as 5.0.5 =====
- * phplot.php: Updated version
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
- * Makefile: Remove 'Callbacks' from release target, as this material is
- now in the reference manual.
-
-2008-01-07 (lbayuk)
- Copyright updated to 2008 and PHP4 no longer listed as supported.
-
- Major rewrite of the margin calculation functions to address multiple
- problems. Fixes for bugs 1856207 "Margin error with 'xaxis'/'yaxis'
- position, 1843012 "Make margins, drawing consistent", and 945439
- "x_tick_label_height not set correctly".
-
- Note: These changes are inter-dependent and cannot be split up.
-
- * Defer all calculations to DrawGraph time, to eliminate order dependencies.
- These functions now just store their arguments in the object, and all
- calculations happen later:
- + SetXAxisPosition, SetYAxisPosition
- + SetMarginsPixels
- + SetPlotAreaPixels (Stores margins, not area, now.)
- + SetPlotAreaWorld
- + SetXTickIncrement, SetYTickIncrement
-
- * A new callback 'debug_scale' was added to trace the margin and scale
- calculations.
-
- * CalcMargins was rewritten. Actual sizes of tick and data labels are now
- used, rather than guesses like "use size of biggest Y value". A minimum
- value (3 x safe_margin, or 15 pixels) applies to each margin.
-
- * FindDataLimits no longer needs to find the longest data label, since
- CalcMargins now does that more precisely.
-
- * DrawXTitle and DrawYTitle now use position offsets calculated by
- CalcMargins. Note: These titles are now offset from the plot area,
- not the image area. The titles will move if you had set the plot area
- or margins.
-
- * DrawYTick, DrawXTick rewritten to use pre-calculated offsets, and common
- code moved to new CalcTicks().
-
- * DrawXDataLabel: Use pre-calculated offsets for text.
-
- * DrawGraph: Rewrote top section (before drawing anything) to do the
- calculations in the proper order, unconditionally.
-
- * Class variables removed:
- x_label_inc, y_label_inc, _x_label_cnt : These were never used.
- title_height, x_title_height, y_title_width : Now internal to CalcMargins.
- data_limits_done : No more need to remember if FindDataLimits called.
-
- * New class variables added:
- plot_margins_set : Keeps track of user-set plot area or automatic.
- x_label_top_offset, x_label_bot_offset, x_offset_axis_offset,
- y_label_left_offset, y_label_right_offset, y_label_axis_offset,
- x_title_top_offset, x_title_bot_offset,
- y_title_left_offset, y_title_left_offset : Label offsets
-
- * New internal functions:
- CalcPlotAreaPixels : Deferred calculations taken out of SetPlotAreaPixels
- and SetMarginsPixels.
- CalcPlotAreaWorld : Deferred calculations taken out of SetPlotAreaWorld.
- CalcAxisPositions : Calculate axis positions, moved from CalcTranslation.
- CalcTicks : Calculate X and Y tick interval. This still uses the
- same simple method (basically range/10), but now we could drop in a new
- algorithm much more easily. This is now also used by CalcMargins.
- Code taken out of DrawXTicks and DrawYTicks.
- CalcMaxTickLabelSize : So CalcMargins can use the exact tick label sizes.
- CalcMaxDataLabelSize : So CalcMargins can use the exact data label sizes.
- DrawXTick : Code split out from DrawXTicks for symmetry with DrawYTick.
-
-
-2007-12-13 (lbayuk)
- * Changed ProcessTextTTF() so SizeText() will return integers. It rounds
- the calculated values up, so the bounding box really contains the text.
- This also prevents unneeded float calculations in derived values.
-
-2007-12-09 (lbayuk)
- Major rewrite of the text drawing functions to address multiple problems.
- Note: These changes are inter-dependent and cannot be split up.
-
- * Fixed bug 1813070 "Bad position for multi-line TrueType text":
- TTF text is now drawn line-by-line, not as a block, for proper
- alignment and positioning.
-
- * Fixed bug 1813071 "Wrong title height for multi-line TTF text":
- Corrected miscalculation of overall height of multi-line TTF titles.
- This bug resulted in over-sized margins.
- The height is now computed line-by-line, including the inter-line spacing.
-
- * Fixed bug 1813474 "DrawText alignment arguments wrong":
- Corrected meaning of 'top' vs 'bottom' alignment. PHPlot now follows
- the usual conventions: 'top' alignment means top of text to reference.
- DrawText default for vertical alignment is still 'bottom', but the
- meaning was corrected. All callers of DrawText were fixed.
-
- * Fixed bug 1816844 "Fix order dependency for setting titles":
- Defer processing titles strings until DrawGraph(), so there is no
- more order dependency (no need to set font before setting title strings).
-
- * Fixed bug 1819668 "Horiz. align multi-line text: GD vs TTF":
- The new text routines draw TTF text line-by-line and correctly do
- right-, center-, and left- alignment of each line within a text block.
-
- * Fixed bug 1826513 "FIXME in DrawLegend: Max label length":
- Use actual width of widest legend line to calculate legend box size.
-
- * Partial fix for bug 945439 "x_tick_label_height not set correctly":
- In FindDataLimits(), save the longest data label, not just its length,
- and use the actual rendered size of that string in CalcMargins() for
- the margin calculations.
- Also take into account which of the tick or data labels are visible.
- This is not a complete fix, but is a significant improvement.
-
- The following changes were made related to the above fixes:
-
- + Replaced internal function TTFBBoxSize(), which didn't work right, with
- SizeText(). It returns the orthogonal bounding box of a block of text,
- and works with both GD and TTF text.
-
- + DrawText() and SizeText() call a single function ProcessText(), which is
- the only place GD text and TTF text are distinguished. (So eventually
- we will be able to mix GD and TTF text on a plot.)
-
- + New internal functions ProcessTextGD() and ProcessTextTTF() draw (or size)
- GD and TTF text respectively. These are only called by ProcessText().
- These are re-implementations which properly position and align text.
-
- + Removed class variables title_angle, x_title_angle, and y_title_angle. The
- titles only work at their fixed angles anyway (0, 0, and 90 respectively).
-
- + Line spacing set with SetLineSpacing() now affects TTF text as well as
- GD text. Previously, it only affected GD text. The default line spacing
- happens to be usable for TTF text.
-
- + Added new callback hook 'debug_textbox' for developing, testing, and
- documenting. It provides access to the text area bounding box.
-
- + Removed unneeded class variables x_tick_label_height, y_tick_label_width,
- x_tot_margin, y_tot_margin.
-
-2007-11-25
- * Improve error handling:
- Internal functions PrintError() and DrawError() are now the same. Both
- will draw the error message into the image and output it, and then
- trigger a user-level error. If no error handler has been set, it will
- exit, as before. But now the error message should also get logged, or
- written to the standard error stream, depending on the SAPI in use.
- You can now establish an error handler to catch most PHPlot errors and
- do some cleanup before exit.
-
- This fix also covers bug #1823774 "Default Font Path and Error Message
- Output".
-
- Fixed the return value of most PHPlot functions, to return False on
- error, else True. Since uncaught errors are fatal anyway, this only
- affects code with an error handler that returns, which is not
- recommended and unsupported at this time. These changes are for
- possible future error handling options.
-
-2007-11-22
- * Fix bug 1836528 "Insufficient checking of parameter values":
- Rewrote CheckOption to correctly validate option choices.
- (It previously accepted substrings and other incorrect values.)
- PHPlot methods that use CheckOption now must be called with valid option
- values. Empty strings are also no longer accepted.
-
-2007-11-17 (lbayuk)
- * Change to callbacks to support extra arguments.
- The PHPlot class can now pass extra arguments to a callback function.
- Callback functions now take the following form:
- my_callback($img, $passthru_arg, ...)
- Where '...' is zero or more additional arguments supplied by PHPlot to
- the callback. Each implemented callback reason will define any
- additional arguments it uses. The existing defined callbacks have not
- changed and do not currently pass any extra arguments.
-
-2007-11-10 (lbayuk)
- * Fix bug 1827263 "Spoiled up pie-chart if $val is close to zero":
- Skip pie slices which would result in an integer angle of zero
- degrees, because the GD arc filling function will draw a complete
- circle for that case.
- Credit to Viacheslav <webdeveloper.ua at gmail.com> for finding this.
-
- * Removed 8 of the functions (class methods) marked 'deprecated'. Only
- deprecated functions which seem to have been for internal use have
- been removed. Even old scripts shouldn't be using them, and they are
- becoming a problem to maintain.
- Removed: SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights()
- CalcYWidths() DrawLabels() InitImage() DrawDashedLine().
-
-2007-10-20 (lbayuk) ===== Released as 5.0.4 =====
- * phplot.php: Updated copyright, version, and authors comments at top.
- * README.txt: Updated for new release
- * NEWS.txt: Add text for new release
-
-2007-10-18 (lbayuk)
- * Add callbacks - experimental feature:
- New functions SetCallback, GetCallback, RemoveCallback.
- New internal function DoCallback.
- Added callback hooks to DrawGraph.
-
- Re-arranged code in DrawGraph to bring pie chart drawing into the main
- switch on plot type, rather than a special case in its own block. This
- makes it easier to follow and easier to add callback hooks.
-
- * Callbacks: New file, documentation for the new callbacks feature.
- (This won't be in the manual while it is an experimental feature.)
-
-2007-10-15 (lbayuk)
- * Fix for bug 1813021: Miss-positioned right-justified vertical GD text.
- Fixed DrawText() to correctly position 90 degree right-justified text
- drawn in a fixed GD font. This could be seen with 90 degree Y tick
- labels. (Found by accident while working on TrueType text problems.)
- Also some code cleanup in DrawText: use elseif where appropriate.
-
-2007-10-09 (lbayuk)
- * Code cleanup: Simplify SetIndexColor() and SetIndexDarkColor().
- There is no need to first try ImageColorExact, then ImageColorResolve
- if that fails. ImageColorResolve does all that for us.
-
- Code cleanup: Rewrite SetRGBColor(). It now detects if an unrecognized
- color name or color value form is used, and draws an error message.
- Before this it would get a PHP index error and "headers already sent"
- condition.
-
- * Code cleanup: Remove duplicated code for loading image files.
- Added new class-private function GetImage() which loads an image based
- on the image type, and also returns the image size. This replaces
- duplicated code in tile_img() and SetInputFile().
- Also fixed comment at top of SetImageFile which said it was deprecated.
- It isn't - it is used by the constructor. Moved the function out of the
- 'deprecated' area up to below where it is used.
-
- * Code cleanup: PHPlot should not define or affect anything outside its
- own class.
- - Removed the check for __FUNCTION__ (PHP 4.3 and up). This is obsolete.
- - Do not set error_reporting to E_ALL. Although it is recommended that
- scripts do this, it is not the place of loaded classes to do it.
- - Remove unused global constant TOTY.
- - Removed constants MAXY and MINY. Global constants like this are bad.
- These were used as magic index values into data[] to hold min and max Y
- values for the row. Instead, put them in separate arrays which are
- named data_miny[] and data_maxy[]. (This seems to be only used by the
- data line drawing function.)
-
- Comment cleanup: Remove one commented-out partial function DrawPlotLabel,
- and fix another commented-out code fragment in DrawYErrorBar. Both of
- these had unmatched braces in them which caused a balance-braces check
- to fail.
-
- * Code cleanup, array padding: Get rid of functions outside the class
- and remove the interim fix for PHP 5 (which changed the behavior of
- array_merge). Rewrote external function array_pad_array() as a new
- class function pad_array(). It does not need access to the class,
- but I don't think PHPlot should add to the global namespace more
- than necessary. The third argument (array to use for padding) was
- never used, so it was removed. It always pads the array with itself.
- It now only works on 'usual integer indexed' arrays (0-based
- sequential integer index). The was previously required but
- undocumented for some of the arrays (like line_widths); now it is
- required for all style arrays and will be documented. Now we can pad
- the array to the required length, not just N times its previous
- length, and we don't need array_merge. Deleted external function
- array_merge_php4() as it is no longer used.
-
- Deleted PHP end marker ?>. You don't need this and it can cause
- problems with extra whitespace in your output.
-
-2007-09-24 (lbayuk)
- * Code cleanup: Fix ternary operator misuse. This doesn't change
- behavior, but it was annoying me so I fixed it.
- Replaced all cases of code like this: $a = ($a > $b) ? $b : $a
- With just: if ($a > $b) $a = $b
-
- * Fix Makefile 'release' target to set owner/group when creating
- the tar file. This avoids having to run it as root, but it needs
- GNU tar to work.
-
-2007-09-08 (lbayuk)
- * Fix for bug 1790441: Removed the PHPlot quasi-destructor function and
- the register_shutdown_function() call which arranged for it to be used.
- This was preventing release of memory when a PHPlot object was unset,
- because the registered shutdown function held a reference to it.
- So rather than improving memory use, it had the opposite effect.
- Note: It is no longer necessary or recommended to use reference
- assignment ($plot =& new PHPlot) for PHPlot object creation.
- Thanks to annajilly for the thorough analysis, bug report, and fix.
-
-2007-09-05 (lbayuk)
- * Rewrote FormatLabel() to ignore blank label values. Adapted from a
- patch and feature request submitted by Gerhard Reithofer (exgerhardr).
- Blank labels used to produce an error if the LabelType was set to
- 'time', and zero if set to 'data'. Now they are just ignored. This
- provides a simple way to have labels only at selected intervals when
- using time or data formats. For example, you can have a date/time
- label at every 10th data point by setting the labels for the other 9
- to be empty strings. Also: Removed $which_pos values 'plotx' and
- 'ploty'. These were unused by PHPlot and this is an internal-only
- function so there is no compatibility issue. Removed error checking on
- $which_pos for the same reason; the error message used an undefined
- variable anyway so it wouldn't have worked.
-
-2007-08-26 (lbayuk)
- * Allow SetLegendStyle colorbox_align argument to be 'none', to suppress
- the colorboxes in the legend.
-
- Fix comment on $legend_text_align: empty means right, not left.
-
- Rewrote DrawLegend layout code to make it easier to understand. The
- result should be within 1 or 2 pixels of the previous size and position.
-
- * Fixes for bug 1779115: SetLegendWorld() fails on undefined vars
- Store the given coordinates and remember that they need to be converted
- from world to pixel coordinates, but defer trying to actually convert
- them until it is time to draw the legend. This way, there are no
- problems with the scale having to being set up first (which is nearly
- impossible to do). Made the following changes:
-
- Changed legend class variables to be uninitialized, and unset (rather
- than empty string) means use the defaults. Added a new variable:
- $legend_xy_world. If it is set, (legend_x_pos, legend_y_pos) need to
- be converted to pixel coords. If it is unset, they are already pixel
- coords (or undefined, meaning defaults).
-
- Changed usage of internal function DrawLegend(): removed all arguments.
- X and Y were always the class variables anyway, and now it needs to
- also use the new flag to tell it if X and Y are world or pixel coords.
- The third argument was unused.
-
- Removed third, unused, default NULL argument from SetLegendPixels and
- SetLegendWorld.
-
- Changes to DrawLegend to convert x, y coords to pixel coordinates
- if they came from SetLegendWorld. Also account for new usage of
- the class variables: Test for unset to mean use default.
-
-2007-08-04 (lbayuk)
- * New feature: control legend text and color box alignment.
- Adds a new function SetLegendStyle to adjust the alignment of the
- text and the color boxes inside the legend.
- Based on part of bug 1208054, contributed by David Hernández Sanz.
-
-2006-12-02 (lbayuk)
- * Fixes for bug 1605555: Y Data Labels use wrong font and not formatted.
- Use y_label_font (not x_label_font) for Y Data Labels.
- Use the formatted value for the label, not the original text.
- (This applies to bar charts only, with the new Y data labels.)
-
- * One fix for bug 1208054: Localization of number format.
- If number formatting is enabled with 'data' format type, PHPlot previously
- used dot for decimal point and comma for thousands separator, and there
- was no way to change it.
-
- This fix adds a new function:
- SetNumberFormat($decimal_point, $thousands_separator)
- to set the separators. In addition, if that function is not used,
- PHPlot will now try to use locale-dependent separators. If locale
- information is not available, it will fall back to the old defaults
- of dot and comma.
-
- Note: This change may have some negative effects. 1) If your locale is
- "C" or "Posix", you might not get a thousands separator now by default.
- You should be using a more specific locale. 2) If your PHP script is
- forcing a specific locale with setlocale(), PHPlot will probably undo
- that because it uses setlocale(LC_ALL, '') to import locale information
- from the environment. We have to do that, or a locale set through
- the environment is ignored. But it will override a manually set locale.
-
- * Fix for bug 937944: X/Y Tick Counts
- PHPlot could draw one too few Y tick marks, and one too many X tick marks.
-
- Changed the code to stop drawing X (Y) tick marks when the current X (Y)
- value exceeds the maximum X (Y) value plus a small fudge factor. The fudge
- factor accounts for cumulative error when repeatedly adding a delta to
- the X (Y) value.
-
- Notes: The bug report was writing about Y tick counts only, but X tick
- counts can also be wrong. The proposed fix in the bug report does not
- work in all cases.
-
- This fix changes the appearance of many plots which were missing the
- top-most Y tick mark. The extra X-tick mark problem is less common.
-
-===== Released as 5.0rc3 =====
-
-2006-11-13 (lbayuk)
- * Fix for bug 1437912: x-axis label misalignment [bar charts]
- The calculations were redone from scratch.
- New control variable 'bar_extra_space', which works in addition to
- 'group_frac_width' to control how much extra space is around the bars.
- Made bar widths match for 'stackedbars' and 1-bar-per-group 'bars'.
-
- NOTE: This changes the appearance of charts. bars in 'stackedbars'
- will now be thinner, and bars in 'bars' graphs will be thicker. I
- saw no reason for them being different before.
-
- This fix required fixing the positioning on the new bar data labels,
- which was off before. The bar data labels will now be centered.
- Additional fixes to bar chart data labels:
- For negative values, the label will center under the bar.
- Fixed X-adjustment to account for shading.
- Fixed to not suppress the data label if the value is 0.
-
-
-2006-11-10 (lbayuk)
- * Fix for bug 1594457: DrawError text wrap and background fix
- Do error image white background correctly, and word-wrap the text.
-
- * Fix for bug 1594458: Suppress lines or points in 'linepoints'
- Don't draw X data labels twice for 'linepoints'.
- Allow SetPointShapes value 'none' to suppress points, and allow
- SetLineStyles value 'none' to suppress lines. This allows a 'linepoints'
- graph to mix lines only, points only, and both on the same graph.
-
-
-2006-11-09 (lbayuk)
- * Fixes for bug 1446523:
- + Wrong variable name in deprecated SetAxisFontSize()
- + Fails to properly handle error if SetDataValues() was never
- called, or not called with a data array.
-
- * Fix for bug 1117122: Pie Chart ignores SetPlotAreaPixels
- Don't let DrawGraph recalculate the plot area for pie charts if the
- user already set it with SetPlotAreaPixels.
-
- NOTE: This fix may slightly change the appearance of some pie charts,
- whether or not they use SetPlotAreaPixels.
-
- * Fix for bug 1103992: Wrong max Y calculated for stackedbars
- Changes FindDataLimits to calculate max Y correctly. It was counting
- the first Y value in each record twice, which is always wrong but
- only affected stackedbars because the Y values are summed.
-
- * Fix for bug 1096199: Wrong error bar colors in DrawDotsError.
- Rewrites DrawDotsError to make it work like DrawLinesError to
- correctly increment the record and color indexes.
- Also fixes uninitialized x_now_pixels.
-
- * Fix for bug 1096197: No borders on unshaded Draw[Stacked]Bars
- Unshaded Bars and StackedBars covered the border with the rectangle.
- The fix is to draw the rectangle, then the border.
-
- NOTE: This fix changes chart appearance. Bars and Stacked Bars
- will now get a black border around each bar by default, if you
- turn off the 3D-shading. If you want borderless, unshaded bars
- you need to use SetDataBorderColors to set the data border colors
- to be the same as the data colors.
-
- * Fix for bug 1333164: Negative data values, if string variables, result
- in unfilled bars. The problem was a string-to-string compare of a
- negative number with the empty string x_axis_position. Fixed by
- initializing x_axis_y_pixels to 0 if SetXAxisPosition was not used.
-
-
-2005-04-17 (afan)
- * Fix for bug [ 1161072 ] SetInputFile warning, background overwrite
-
- * Bug 1182672 fixed
-
-2005-04-15 (afan)
- * fix for bug: [ 1182666 ] Y Auto-scale rounds in wrong direction
-
- * Fix for bugs 1144644 TrueType font path problems and 1106328 TTF
- path/filename inconsistency
-
- * Fix Bug: [ 1117120 ] X Title sizing uses Y Title font height
-
-2005-04-13 (afan)
- * Error in SetLineStyles() - does not accept an array argument
-
-
-2005-03-29 (afan)
- * Small typo fixed in SetYDataLabelPos
-
- * Update SetDataLabelPos: For past compatibility we accept plotleft,
- ...but pass it to SetTickLabelPos
-
-2005-03-26 (afan)
- * Change to line 3802: data lables now work with multiple bars with *$idx
-
-2005-03-25 (afan)
- * Added Function DrawDataLabels to put data labels in world coords,
- added call from DrawBars and modified SetYDataLabelPos to flag
- whether or not to call DrawDataLabels.
-
-2005-01-20 (migueldb)
- * Many bugfixes reported and solved by L. J. Bayuk. Thanks!
- + fixed bug #1096190
- + FindDataLimits(): fixed bug #1096192
- + CalcTranslation(): fixed bug #1101317
- + DrawImageBorder(): fixed bug 1096200
- + DrawXDataLabel(): fixed bug 1099879
- + DrawDots(): fixed bug #1096194
-
-===== Released as 5.0rc2 =====
-
-2004-10-24 (migueldb)
- * array_merge_php4(): added to cope with the bug introduced by
- the change in array_merge() from PHP4 to PHP5 (I haven't verified this)
- * Fixed some divisions by zero, thanks to an old bug report.
-
-2004-09-09 (migueldb)
- * SetPointSize(): deprecated
- * SetPointSizes(): added as replacement for SetPointSize().
- Now able to set point sizes on a per line basis.
- * SetPointShape(): deprecated.
- * SetPointShapes(): added as replacement for SetPointShape().
- Now able to set point shape on a per line basis.
- * DrawDot(): now needs record number to decide which dot shape and
- size to draw.
- * CalcMargins(): dirty fix for x data label placing.
- * tile_img(): fixed tile placement.
-
-2004-06-14 (migueldb)
- * SetXTickLabelPos() and others: more on the bug reported by Jo Demol.
- * Fixed bug reported by Jo Demol.
-
-2004-05-11 (migueldb)
- * SetBgImage(): added.
- * SetPlotAreaBgImage(): added.
- * SetInputFile(): deprecated.
- * DrawBackground(): now accepts images as backgrounds.
- * DrawPlotAreaBackground(): now accepts images as backgrounds.
- * tile_img(): internal method added.
-
-..........
-Editor's Note: For older changes to PHPlot, please see the CVS logs.
+++ /dev/null
-This is the NEWS file for PHPlot, with release documentation.
-The project web site is http://sourceforge.net/projects/phplot/
-The project home page is http://phplot.sourceforge.net/
-Refer the the ChangeLog file for detailed source changes.
------------------------------------------------------------------------------
-
-2011-01-15 Release 5.3.1
-
-Overview:
-
-This is the current stable release of PHPlot. This release focuses on
-providing better support and documentation for creating multiple plots on a
-single image.
-
-The PHPlot reference manual has been updated to match this release. Some
-new material has been added, including a new section on multiple plots per
-image, and a new example of overlay plots.
-
-
-Bugs Fixed in 5.3.1:
-
-#3143586 "Multiple plots per image - fixes & docs":
- The reference manual now contains a section on multiple plots, and a
- new example. A bug was fixed with SetLegendWorld and multiple plots.
- Image border will now be drawn at most once. It is now possible to
- restore the default 'automatic' behavior for axis positioning. Other
- functions were changed to make arguments optional, so when called with
- no arguments they reset to the default. The reference manual has been
- updated with these changes too.
-
-#3147397 "Data colors missing with multiple plots":
- The fix for bug #3049726 "Optimize color allocation" caused a problem
- with multiple plots. This has been fixed. PHPlot will no longer truncate
- the data color table at each plot. It will still only allocate data colors
- as needed, but all of the pre-set or configured data colors will be
- available for each plot.
-
-
------------------------------------------------------------------------------
-
-2010-12-04 Release 5.3.0
-
-Overview:
-
-This is the current stable release of PHPlot. This release includes new
-plot types and some new features.
-
-The PHPlot reference manual has been updated to match this release. Some of
-the sections have been moved, there are new examples for the new plot types,
-and a new section on tunable parameters has been added.
-
-
-New features in 5.3.0:
-
-#3093483 "Investing support chart types":
- Added 3 new plot types: Basic OHLC (Open/High/Low/Close), Candlesticks,
- and Filled Candlesticks. These are variations of plots that show the
- performance of a stock or other financial security.
-
-#3111166 "Control legend colorbox width":
- It is now possible to control the width of the color boxes in the
- legend, using a class variable which is documented in the manual.
-
-#3117873 "Data value labels in more plot types":
- Data value labels, which show the dependent variable values near the
- data points, are now available for more plot types: lines, linepoints,
- points, and squared. (These were previously available only for bars and
- stackedbars plots.)
-
-#3127005 "Ability to suppress X/Y axis lines":
- New functions SetDrawXAxis() and SetDrawYAxis() were added to control
- display of the X and Y axis lines. (These lines were probably the only
- PHPlot elements that could not be turned off.) In special cases, these
- can be used to produce a "bare" plot image.
-
-
------------------------------------------------------------------------------
-
-2010-10-03 Release 5.2.0
-
-Overview:
-
-This is the current stable release of PHPlot. This release includes some
-bug fixes and new features, described below, and a reimplementation of
-internal processing of colors.
-
-The PHPlot reference manual has been updated to match this release.
-Horizontal plots are now documented in the manual, and the interim
-documentation in the source release (HorizontalBars.txt) has been removed.
-The manual is available in HTML format as a separate download from
-Sourceforge. The manual is also available for on-line viewing from the
-project home page. Starting with this release, the manual is also
-available in PDF format from the project home page.
-
-
-Cautions, Important Notes, and Compatibility Issues:
-
-Due to changes in color allocation (see bug #3049726 below), image files
-produced with PHPlot-5.2.0 will differ when compared byte-for-byte with
-those created by earlier releases, even when the images are identical (as
-they nearly always are).
-
-If you are creating a horizontal plot with any negative X values, and not
-setting the Y axis position, your plot will change (see bug #3074402 below)
-because PHPlot no longer leaves the Y axis on the left for horizontal plots.
-
-Some internal methods that used to have 'public' visibility are now protected.
-This will generally prevent you from using them. The list of changed functions
-can be found in the release ChangeLog. Avoid using any internal methods.
-
-If you are making a stackedbar plot with any negative values, PHPlot-5.1.3
-and earlier took the absolute value of each data value (which was not
-documented), but PHPlot-5.2.0 does not. See Feature Request #3073679 below.
-
-If your plot fills the 256 available color map slots in a palette image,
-your image may look different with PHPlot-5.2.0 due to changes in color
-allocation order. This was seen on two of the tests in the PHPlot test
-suite. These tests tiled a JPEG image into the plot area or image
-background. Being a truecolor image, the JPEG had a huge number of colors,
-which filled all available slots in the color map. Additional colors for
-plot elements had to be approximated, and different colors resulted with
-PHPlot-5.2.0 versus previous releases. To avoid this problem, either use a
-truecolor PHPlot object (PHPlot_truecolor constructor), or reduce the
-number of colors in the background image and convert it to PNG or GIF.
-
-This release contains significant changes to PHPlot internals. In particular,
-variables and functions related to element colors and color handling have
-changed. Refer to the PHPlot release ChangeLog for more details. Remember,
-if you rely on accessing any member variable, or on using any non-public
-function or any function not documented in the reference section of the manual,
-your code is at risk of breaking with each new release.
-
-
-New features in 5.2.0:
-
-#3077554 "Finer control over plot element colors" (partial):
- The X, Y, and main titles can now have different colors. See the PHPlot
- Reference Manual entries for SetXTitleColor and SetYTitleColor.
-
-#3073679 "Stacked bar plots with negative values":
- A stacked bar plot can now include negative values, and stacks of negative
- values will be drawn downwards (or leftwards). See the PHPlot Reference
- Manual under "Plot Type: stackedbars" for details.
-
-
-Bugs Fixed in 5.2.0:
-
-#3045131 "SetTransparentColor problems":
- Setting a transparent color now works whether before or after setting
- the background color (for example), and also now works with a data color.
-
-#3049726 "Optimize color allocation"
- PHPlot now defers allocating colors until drawing time, and tries to allocate
- only the colors which are actually needed. For palette images, this results
- in use of fewer color slots and slightly smaller image files.
-
-#3074402 "Fix Y axis default for horizontal plots":
- When horizontal plots were introduced, an asymmetry with the X and Y axis
- position defaults was known but left. This behavior was later determined
- to be unhelpful. So now the Y axis on horizontal plots will default to X=0,
- or the X value closest to zero within the plot area range. This is the same
- behavior as for the X axis in vertical plots.
-
-#3056991 "Internal methods should be 'protected'":
- More of the internal PHPlot functions were changed to 'protected' visibility,
- as the test suite was fixed to not call them directly.
-
-#3057000 "Review 'deprecated' methods":
- One broken deprecated method (SetColor) was removed and one changed.
- Note that deprecated methods are not documented and not tested.
-
------------------------------------------------------------------------------
-
-2010-08-30 Release 5.1.3
-
-Overview:
-
-This is the current stable release of PHPlot. Additional horizontal plot
-types and features have been added, however horizontal plots are still
-considered 'experimental'. A new callback has been added which allows
-greater control over the data colors. An improved method for accessing
-TrueType Font (TTF) files means that on many systems TTF text can be used
-without specifying font paths.
-
-
-Cautions and Important Notes:
-
-Since the previous PHPlot release, PHP-5.3.3 and PHP-5.2.14 have been
-released, and these include a fix for the TrueType Font (TTF) rendering
-problem. Use of these releases is now recommended.
-
-There has been extensive cleanup of the PHPlot code. If you have a
-customized version of PHPlot, you may find it difficult to update.
-
-The "additional data support" script phplot_data.php has been removed from
-this release. The script has not been developed or tested in a long time,
-and was found to have numerous problems. The script can still be found in
-the CVS repository.
-
-The changes in this release (horizontal plots, custom data color callback,
-and TrueType Font handling) should not result in any compatibility issues.
-
-
-New features in 5.1.3:
-
-#3049703 "Additional horizontal plots and features":
- + Implemented data values labels in horizontal bar charts.
- Use: SetXDataLabelPos('plotin').
- + Add horizontal stacked bar charts, with data value labels.
- + Add horizontal thinbarline plots.
- Horizontal plots are still considered 'experimental', and documentation is
- in the HorizontalBars.txt text file rather than the PHPlot Reference Manual.
-
-#3034164 "Extended control of data colors":
- New callback 'data_color' can be used to customize selection of the color
- of each bar, line segment, point marker, etc. This is documented in the
- PHPlot Reference Manual section "Custom Data Color Selection", with new
- examples in the Examples chapter.
-
-
-Bugs Fixed in 5.1.3:
-
-#3051906 "Better choice for default TT font":
- Rather than always using the unlikely 'benjamingothic.ttf' as its default
- TrueType font name, PHPlot now has a short list of sans-serif fonts, and
- tries to find one that works if a default TT font is needed. On many
- systems, this will provide a high-quality default font without help.
-
-#3051832 "Let PHP/GD find the font file":
- Instead of using file existence to validate a TT font file, PHPlot now
- just tries to use the font. This allows PHP/GD to use its own rules to
- try to find the font, without needing a pathname. This works on Windows
- and at least some Linux systems.
-
-#3048267 "phplot_data add-on is still broken"
- Not fixed. phplot_data.php has been removed from the release.
-
------------------------------------------------------------------------------
-
-2010-06-29 Release 5.1.2
-
-Overview:
-
-This is the current stable release of PHPlot. Truecolor image support is no
-longer considered 'experimental', and is now documented in the reference
-manual. There is a new experimental feature for horizontal bar charts. This
-release also contains a bug fix and new feature.
-
-
-Cautions and Important Notes:
-
-The advisory against using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use
-TrueType fonts (TTF) continues. See the item below for PHPlot-5.1.1. The
-good news is that this has been fixed by the PHP Team and will be in the
-next releases.
-
-Compatibility of data type and plot type are now checked completely. If
-you used an incorrect data type with certain plot types, your script may no
-longer work until you fix the data type. Specifically, the area, squared,
-and thinbarline plot types failed to check the data type they received, and
-treated anything other than 'data-data' as 'text-data'. If you have a
-squared plot with data type 'data-data-error', for example (which is not
-supposed to work), it did produce a plot, but will now result in an error.
-
-The addition of horizontal bar charts should not impact any existing plot,
-with one small exception. The function SetYDataLabelPos() used to accept
-some additional, undocumented options (plotleft, plotright, both, yaxis)
-and pass these through to SetYTickLabelPos() "for compatibility". It no
-longer does so, as some of those are now used for horizontal bar chart
-labels. To position Y tick labels, use only SetYTickLabelPos().
-
-
-New features in 5.1.2:
-
-#3002606 "Add to plot and image border options":
- SetPlotBorderType() now accepts 'right', 'top', and 'bottom', as well
- as an array of options. So you can now control exactly which of the 4
- border sides will be drawn.
- SetImageBorderType() now accepts 'solid' as a choice. This will use the
- actual color set with SetImageBorderColor(), rather than the darker
- shade as type 'plain' does (which may have been a bug).
- SetImageBorderWidth() is a new function that sets the width of the image
- border. The defaults are the same as the fixed values used before: 1
- pixel for plain, 2 pixels for raised. The image border width is now
- accounted for in margin calculations, if it is greater than 2 (to make
- sure existing plots will not change).
-
-#2885930 "Horizontal Bars":
- Horizontal bar charts are implemented, as an experimental feature.
- 'Experimental' means they are not yet documented in the reference manual,
- and subject to change or removal.
- Refer to the text file HorizontalBars.txt for details.
-
-#2947679 (follow-up) "Support for alpha blending/Truecolor":
- Truecolor support is now documented in the Reference Manual. The interim
- documentation file Truecolor.txt has been removed. Alpha channel
- specification now works with both constructors and both image types. This
- fixes an issue if the base constructor was used with a truecolor background
- image. (In PHPlot-5.1.1, the result would be a truecolor image, but the
- alpha channel features were not available.)
-
-
-Bug Fixed in 5.1.2:
-
-#3010116 "Bad rendering of title in multi-plot image when using TTF":
- Make sure the main title is drawn only once, to avoid bad rendering of
- TTF titles with multiple plots due to anti-aliasing.
-
------------------------------------------------------------------------------
-
-2010-04-04 Release 5.1.1
-
-Overview:
-
-This is the current stable release of PHPlot. This release adds truecolor
-image support as an experimental feature, fixes a number of bugs and adds
-a few new features.
-
-The PHPlot reference manual has been updated to match this release. The
-manual is available as a separate download from Sourceforge. The manual is
-also available for on-line viewing from the project home page.
-
-See the ChangeLog file in the release for more about changes and bug fixes.
-
-
-Cautions and Important Notes:
-
-Avoid using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use TrueType fonts
-(TTF). Some new bugs were introduced in those releases that adversely
-affects accurate positioning and rendering of TrueType font text.
-
-
-New features in 5.1.1:
-
-#2947679 "Support for alpha blending/Truecolor":
- PHPlot can now produce truecolor images, with alpha blending of colors and
- other effects. This is considered an experimental feature, meaning it is
- not yet documented in the PHPlot Reference Manual, and subject to change.
- Refer to the text file Truecolor.txt included in the PHPlot release for
- information on using truecolor.
- Two drawing changes were made to improve plot appearance with Truecolor:
- + Filled dots (in points & linepoints plots) are now drawn better. This
- also makes them look rounder with regular (non-Truecolor) plots.
- + Area plots have the areas filled without overlapping each area down to
- the Y axis. This was needed to fix problems with alpha blending, and
- should have no effect on non-Truecolor plots.
-
-#2973995 "Add y-Data to Stackedbars":
- You can now have Y Data Labels with 'stackedbars' plots. These label the Y
- values (incremental and total) for each bar. Refer to the reference manual
- page for SetYDataLabelPos().
-
-
-Bug Fixes in 5.1.1:
-
-#2976735 "Improvements and fixes for 'area' plots":
- Moving X axis works; handle Y<0 better; new 'stackedarea' plot type is a
- variation on 'area' with the data represented differently.
-
-#2974639 "Stacked bars plot breaks with X axis != 0":
- Moving X axis works.
-
-#2963757 "point_counts undefined error in 5.1.0":
- Fixed an error introduced in PHPlot-5.1.0 when point size and shape arrays
- were set to the same size.
-
-#2938219 "Bars go in wrong direction":
- For bar charts with all Y<0, bars will still be drawn down even if Y=0 is
- not in range.
-
------------------------------------------------------------------------------
-
-2009-12-24 Release 5.1.0
-
-Overview:
-
-This is the current stable release of PHPlot. This release fixes a number of
-bugs and adds some new features. Some of the changes in this release can
-alter the appearance of plots, so be sure to review the information in this
-NEWS file and test this release with your application.
-
-The PHPlot reference manual has been updated to match this release. The
-manual is available as a separate download from Sourceforge. The manual is
-also available for on-line viewing from the project home page.
-
-See the ChangeLog file in the release for more about changes and bug fixes.
-
-
-New features in 5.1.0:
-
-+ A new "contrib" directory has been added for useful add-ons.
- This currently contains:
- * prune_labels : Control data label density on X axis.
- * color_range : Define a gradient map for data colors.
-
-+ Feature Request 2899921 "Allow different format for data and tick labels"
- Text angle and format can now be controlled separately for data labels.
-
-+ Locale loading override
- New variable locale_override stops PHPlot from getting locale from system.
-
-+ Translating Coordinates
- New function GetDeviceXY() to translate world to device coordinates.
-
-+ New drawing callback
- New callback 'draw_all', called after all drawing is done.
- The manual now contains an example of using this new callback and
- the new GetDeviceXY() function to annotate a plot.
-
-
-Bug Fixes in 5.1.0:
-
-#2914403 "Pie + X/Y titles: Undefined property error"
- X/Y titles are now properly ignored for pie charts.
-
-#2908256 "Error: array_sum() should be an array" (drupal)
-#2916864 "Should at least print legend on pie charts with empty data"
- Pie charts with invalid data (no Y values > 0) now make an empty plot.
-
-#2906436 "Fixes for X Tick Labels vs X Data Labels"
- Smarter determination of whether to do Tick labels, Data labels, or both.
-
-#2900914 "Problem with display of 0 on Y axis"
- Fixed rounding error that could produce something like Y=8.12345E-16.
-
-#2886365 "PHP 5 patch" (Declare all functions and variables in PHP5 style)
- Most internal PHPlot member functions now have "protected" visibility.
-
-#2839547 "SetImageBorderType('none')
- You can use SetImageBorderType('none') to turn the image border back off.
-
-#1795972 "Fix default point shapes"
- We now have 20 (vs 10) point shapes, with 10 (vs 1) used by default.
-
-#1795971 "Fix default data colors"
- We now have 16 (vs 8) default data colors, no duplicates, all visible.
-
-
-Visible Changes and Possible Incompatibilities:
-
-+ PHP5 visibility changes (Bug #2886365)
-Details: Most internal PHPlot member functions now have visibility
- 'protected', rather than all being public. All member variables are
- still 'public'.
-
-Reason for the change: Use the recommended PHP5 syntax, better OO style.
-
-Compatibility: If you were calling a PHPlot internal function that got
- changed to 'protected', this will break. Please report this.
-
-
-+ Fix default point shapes (Bug 1795972)
-Details: We now have 20 (vs 10) point shapes available, and by default we
- have 10 (vs 1) different shapes in use. The default size is now 6 pixels
- for all point shapes.
-
-Reason for the changes: Using different shapes helps distinguish the data
- sets. The existing 10 defined shapes were not enough, since some of them
- are not centered over the points, too small, or otherwise hard to see.
- The code to synchronize the point shape and size arrays was broken, and
- some dubious code to adjust sizes to even numbers needed to be fixed.
-
-Compatibility (1): If you have a points or linepoints plot with more than
- one dataset, and you did not use SetPointShapes() to configure the
- shapes, them your plot will change from using a diamond for all data
- sets to using different shapes for up to 10 data sets.
-
-Compatibility (2): Fixing the point size/point shape array size bug may
- slightly change the size of some shapes, but it now works the way it
- was documented and supposed to work.
-
-+ Fix default data colors (Bug 1795971)
-Details: Defined a new set of 16 default data colors. The colors are
- different and contrast well against the default white background.
- The first 4 colors were not changed.
-
-Reason for the change: The default 8 data colors included two instances
- of orange, and one color which was invisible on a white background.
-
-Compatibility: Colors will change on any plot with more than 4 data sets
- where you did not use SetDataColors() to set your own data colors.
-
-+ Re-used old function SetXDataLabelAngle()
-Details: SetXDataLabelAngle() now does something different.
-
-Reason for the change: This name was needed for a new function, to set the
- angle for the X Data Labels. The old use of this function was not
- documented, and marked "deprecated" in the code since around 2003-12-07.
-
-Compatibility: If you are still using SetXDataLabelAngle() to set both Tick
- and Data label angles, you need to use SetXLabelAngle() instead.
-
-+ Separate controls for tick and data labels (Feature Request 2899921)
-Details: New functions SetXDataLabelAngle(), SetYDataLabelAngle(),
- SetXDataLabelType(), and SetYDataLabelType() to allow separate control
- over the angle and format of data labels, versus tick labels.
-
-Reason for the change: Allow Data Labels to use different formatting and
- angle compared to Tick Labels.
-
-Compatibility: The default behavior has been set up such that there should
- be no compatibility issues. For example:
- Old behavior: SetXLabelType() sets the type for both tick and data labels.
- New behavior: SetXLabelType() sets the type for tick labels and the
- default type for data labels. SetXDataLabelType() sets the type for
- data labels (overrides SetXLabelType).
-
-+ X Tick Labels vs X Data Labels (Bug 2906436)
-Details: Regarding SetXTickLabelPos() and SetXDataLabelPos(): If only one
- of them is called, the behavior is unchanged (only that label type will
- be displayed). If both are called: Do exactly what was requested. If
- neither was called: display only data labels if any data labels are
- non-empty, else display only tick labels.
-
-Reason for the change: 1) Fix the long-standing problem behavior that by
- default PHPlot overlays tick and data labels below the X axis. 2) Fix
- order dependency between setting the position of tick and data labels.
- 3) Prepare for future extension of data labels, and allow both tick
- and data labels to be on if the programmer enables both.
-
-Compatibility: There are some cases where your plot will change.
- (a) Calls neither SetXDataLabelPos() nor SetXTickLabelPos():
- Old behavior: Both tick and data labels displayed, possibly overlaid.
- New behavior: If there are any non-blank data labels, then show only
- the data labels, not the tick labels. Otherwise, show tick labels.
-
- (b) Calls both SetXDataLabelPos() and SetXTickLabelPos(), with other than
- 'none' for each position:
- Old behavior: The latter call was effective; earlier one ignored.
- New behavior: Independent of order, both calls are effective.
-
------------------------------------------------------------------------------
-
-2009-06-14 Release 5.0.7
-
-Overview:
-
-This is the current stable release of PHPlot. The release adds one new
-feature, fixes a few bugs, and changes the license under which PHPlot
-is released.
-
-The PHPlot reference manual has been updated to match this release. The
-manual is available as a separate download from Sourceforge. The manual is
-also now available for on-line viewing at http://phplot.sourceforge.net
-
-See the ChangeLog file for more about changes and bug fixes.
-
-
-Licensing:
-
-PHPlot is now released on the terms of the GNU Lesser General Public
-License, version 2.1. (Previous versions of PHPlot were released under
-a dual "PHP/GPL" license.) The licensing change was authorized by the
-original author and copyright holder of PHPlot.
-
-
-New feature in 5.0.7:
-
-+ Plot area margins can now be partially specified, using either
- SetMarginsPixels or SetPlotAreaPixels. In previous releases of
- PHPlot you had to either specify all 4 margins or none.
- Credit to adoll for this feature.
-
-
-Visible Changes and Possible Incompatibilities:
-
-+ Y data range can change:
- As a result of the bug fixes in this release, automatically-calculated
- Y data ranges can change. If you have missing Y values in your data,
- and you let PHPlot calculate the Y data range (that is, you do not
- call SetPlotAreaWorld with a Ymin value), then the lower limit for Y
- can change. If you have a plot with data-data-error data type, different
- error values for different points, and let PHPlot calculate the Y data
- range, then either Y limit can change.
-
-
-Bug Fixes in 5.0.7:
-
-
-+ Fix for bug 2803900: SetRGBArray('large') does not work:
- Corrected an array name usage problem. You can now select the large
- color map. Also PHPlot no longer overrides use of the PHP include
- path when loading the large color map, and now reports an error if the
- file is needed and not found.
-
-+ Fix for bug 2791502 "Error plots treat missing Y values as 0":
- Missing Y values now with with data-data-error plots.
-
-+ Fix for bug 2792860 "Wrong DataLabelLines with missing Y":
- Data label lines are now suppressed at missing Y values.
-
-+ Fix for bug 2786350 "Missing Y data results in bad auto-range":
- Missing Y values are now ignored when calculating the Y data range.
- Bug report and analysis by mrten.
-
-+ Fix for bug 2786354 "Incorrect auto-range for data-data-error":
- The Y data range is now correctly calculated for data-data-error plots
- when the error values differ from point to point.
-
-
------------------------------------------------------------------------------
-
-2009-01-20 Release 5.0.6
-
-Overview:
-
-This is the current stable release of PHPlot. The purpose of this release
-is to fix additional problems with text spacing and positioning, and
-introduce some minor new features.
-
-The PHPlot reference manual has been updated to match this release. The
-manual is available as a separate download from Sourceforge. The manual is
-also now available for on-line viewing at http://phplot.sourceforge.net
-
-
-New features in 5.0.6:
-
-+ Allow mixing GD and TrueType font text on the same plot
- You can use the new method functions SetFontGD() and SetFontTTF() to
- select a font and font type for text element (labels, titles, etc.) For
- example, you can have TrueType plot titles, and GD-fixed font labels.
- SetUseTTF() now sets the default text type, TTF or GD. This is fully
- backward compatible.
-
-+ Extended label formatting
- See the reference manual for more information on these.
-
- New label formatting types are added: 'printf' (using a user-defined
- format), and 'custom' (using a callback function).
-
- For 'data' type formatting, a prefix and suffix can be added. (PHPlot
- previously had an undocumented suffix for 'data' type, which still
- works.)
-
- For 'time' formatting, the format can now be specified in the same function
- call rather than using SetXTimeFormat and SetYTimeFormat.
-
- For 'data' formatting, the precision can now be specified in the same
- function call, rather than using SetPrecisionX and SetPrecisionY.
-
-+ Better control over line spacing in multi-line labels
-
- Line spacing can now be set separately for each text element using an
- additional argument to SetFont, SetFontGD, and SetFontTTF. The overall
- SetLineSpacing() value is the default for each text element that does not
- have a specific line spacing set.
-
- PHPlot now interprets the value set for line spacing as the number of
- pixels only for GD text. For TrueType text, it is a scale factor for the
- font's built-in line spacing for TrueType text. The equation used is:
- interline_spacing = line_spacing * font_natural_spacing / 6
- where line_spacing is either the global value set with SetLineSpacing
- or a more specific value set with SetFont(), and font_natural_spacing
- is the amount of space between lines built-in to the TrueType font. The
- factor 6 should really be 4 (since PHPlot always used 4 as the default
- line_spacing, this would give the natural font spacing by default). But
- the text is too widely spaced with this value, and 6 was chosen to be
- more compatible for typical font sizes.
-
-Visible Changes and Possible Incompatibilities:
-
-+ Line spacing
- Multi-line TrueType titles and labels will have different inter-line
- spacing. Since the text size affects the margin and plot area sizes,
- this results in slightly different sized features on any plot with
- multi-line TrueType text.
- Previous versions of PHPlot used a default 4 pixels for inter-line
- spacing of multi-line TrueType text, regardless of the font size.
- PHPlot now uses the 'natural' font inter-line spacing, adjusted by a line
- spacing parameter (per text type, with a global default).
-
- The same change can also increase the size of the legend box slightly.
-
-+ Internal changes were made to the way font information is stored. Anything
- that directly references PHPlot internals regarding fonts will break. Usage
- also changed for the internal functions to size and draw text (ProcessText*,
- SizeText*) due to font data storage changes.
-
-+ Changes were made to internal class variables used to store label
- formatting information. Anything relying on these internals may break.
-
-
-Bug Fixes in 5.0.6:
-
-#1932571: Data-Data Plot fails with same X values
- PHPlot will no longer hang if all X values are the same. But this is
- interim fix to force the X range to 1 to prevent the hang. Eventually,
- smarter automatic range code will handle this better.
- Credit to andyl for finding this.
-
-#1891636: Misaligned TTF X Labels
- PHPlot will now correctly line-up TrueType labels along the X axis. There
- were small but very noticeable errors before, when the text had descenders
- or lines with all short letters.
-
-
------------------------------------------------------------------------------
-
-2008-01-13 Released 5.0.5
-
-Overview:
-
-This is the current stable release of PHPlot. The emphasis of this release
-is to improve text positioning, margin calculation, and error handling.
-
-Although this is considered a stable release, it has a large amount
-of changed code compared to the previous release 5.0.4. Two of the more
-complex components of PHPlot - text and margin calculations - were mostly
-re-written in this release. You are advised to carefully test your own
-applications with PHPlot-5.0.5 to see how your plots look. Refer to the
-README.txt file included in the release for information on reporting problems.
-
-Starting with this release, PHPlot no longer supports PHP4, since the PHP
-group officially declared end-of-life for PHP4 as of 31 December 2007.
-PHPlot-5.0.5 was tested only with PHP-5.2.5 and we are unlikely to address
-any issues using PHPlot with older versions of PHP.
-
-The PHPlot reference manual has been updated to match this release. The
-manual is available as a separate download from Sourceforge. The manual is
-now also now available for on-line viewing at http://phplot.sourceforge.net
-
-The callback feature added in 5.0.4 is now documented in the reference
-manual. It is still considered experimental and subject to change, however.
-
-
-
-Visible Changes and Possible Incompatibilities:
-
-+ Dropped support for PHP4.
-
-+ Eliminated remaining order-dependent behavior related to margins and
-text. PHPlot should now do nothing at all, except record parameters, until
-you draw the graph with DrawGraph. I believe this was always the intended
-behavior of PHPlot, but over time perhaps various pre-calculations and
-dependencies crept in. Fixing this simplifies processing and should lead to
-more consistent behavior.
-
-+ The rewritten margin calculation code now uses actual sizes of all tick
-and data labels and tick marks, rather than guesses. Margins collapse to
-remove unused elements, but a minimum margin (currently fixed at 15 pixels)
-is applied so the plot edges don't get to close to the image edges. The
-result is that most graphs with auto-calculated margins will change in
-appearance. It most cases, the margins get slightly smaller. In other
-cases, earlier releases mis-calculated the margins, so this release will
-produce much neater margins.
-
-+ The X and Y titles are now offset out from the plot area, not in from the
-image area. For auto-calculated margins this should not make any
-difference, but if you use SetMarginsPixels or SetPlotAreaPixels to set
-larger margins, the axis titles will move in closer to the plot with this
-release.
-
-+ Changes were made to PHPlot internals, including removal of some class
-variables and functions, and addition of new variables and functions.
-These are documented in the ChangeLog. Relying on any internal variables
-or functions in an application using PHPlot is unwise. The following
-internal functions were removed:
- SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights()
- CalcYWidths() DrawLabels() InitImage() DrawDashedLine()
- These were marked 'deprecated', were undocumented and unmaintained.
- TTFBBoxSize()
- This was replaced with SizeText().
-
-+ Line spacing set with SetLineSpacing() now affects TTF text as well as
-GD text. Previously, it only affected GD text. The default line spacing
-happens to be usable for TTF text.
-
-+ Changes were made to error handling. PHPlot will now trigger a user-level
-error after producing an error image, instead of exiting. If no error
-handler has been set, it will exit, as before. But now the error message
-should also get logged, or written to the standard error stream, depending
-on the SAPI in use. You can now establish an error handler to catch most
-PHPlot errors and do some cleanup before exit.
-
-+ PHPlot no longer accepts some invalid option values (such as a substring
-of a valid value, or empty strings) passed to functions. If your
-application aborts in CheckOption with PHPlot-5.0.5 but 'worked' with
-previous releases, them you were probably using an invalid option value.
-
-
-
-Bug Fixes in 5.0.5:
-
-#945439: x_tick_label_height not set correctly
- Exact sizes of labels are now used to calculate margins.
-
-#1813070: Bad position for multi-line TrueType text
- Fixed as part of text functions rewrite. Use correct basepoint
- (lower left of each line) when positioning text lines.
-
-#1813071: Wrong title height for multi-line TTF text
- Fixed as part of text functions rewrite: calculate height of
- multi-line text correctly. Also now uses the line-spacing setting.
-
-#1813474: DrawText alignment arguments wrong
- Fixed so 'top' and 'bottom' now have the usual meaning: top means
- align top of text with reference, bottom means align bottom of text.
- This was switched before. Changed every internal caller to compensate.
-
-#1816844: Fix order dependency for setting titles
- Defer processing of title strings until DrawGraph(),
- so it doesn't matter if fonts, etc. are set before or after.
-
-#1819668: Horiz. align multi-line text: GD vs TTF
- The text functions were rewritten to draw TTF text line-by-line,
- like GD text, and correctly align each line.
-
-#1823774: Default Font Path and Error Message
- Error handling has been improved to make sure a message is logged, in
- addition to the error image, and use error_trigger rather than exit.
-
-#1826513: FIXME in DrawLegend: Max label length
- The actual size needed for legend text is now used.
-
-#1827263: Spoiled up pie-chart if $val is close to zero
- Fixed by skipping over any segment that rounds to 0 degrees of
- arc. (The GD function uses integer angles only, and 0 degrees
- means draw a complete circle.)
-
-#1836528: Insufficient checking of parameter values
- Rewrote validator function to reject improper parameter values.
-
-#1843012: Make margins, drawing consistent
- Margin code logic was rewritten and checked for consistency.
-
-#1856207: Margin error with 'xaxis'/'yaxis' position
- Margin space is now allocated for ticks and labels if their position
- is 'xaxis' or 'yaxis' and the axis is at the plot edge. This is not
- a perfect fix (the axis could be close but not at the edge).
-
-
------------------------------------------------------------------------------
-
-2007-10-20 Released 5.0.4
-
-Overview:
-
-This is the latest stable release of PHPlot. We are abandoning the 'rc'
-version naming style, because we don't consider these last releases
-'release candidate' versions. As we continue to make changes to PHPlot,
-we are not converging toward a final "5.0" release, however we do consider
-these releases stable and complete enough for production use.
-
-This release fixes a number of problems and introduces a few new features.
-
-The PHPlot reference manual has also been updated to match this release.
-New material has been added documenting some of the PHPlot internals.
-The manual is available as a separate download from Sourceforge.
-
-
-Code Cleanup:
-
-Some code cleanup is going in to this release. It is hoped that these
-changes will not impact any existing scripts using PHPlot, but will make
-the PHPlot code itself easier to understand and maintain.
-
-PHPlot now avoids making changes outside its own class definition. There
-are no longer any functions defined outside the class, nor any constants.
-Three constants (MINY MAXY TOTY) were removed, and 2 functions were removed
-(see Visible Changes below). Also PHPlot no longer sets the PHP error
-reporting level to E_ALL. Although we highly recommend setting error
-reporting to E_ALL in your php.ini file or scripts, it is not right for
-PHPlot to assume that you want it.
-
-
-Visible Changes and Possible Incompatibilities:
-
-Arrays containing color and style information are used with several PHPlot
-functions to control the plot style array. These functions are:
- SetPointShapes, SetPointSizes, SetLineWidths, SetLineStyles,
- SetDataColors, SetDataBorderColors, and SetErrorBarColors.
-The arrays passed to these functions MUST used sequential integer 0-based
-indexes. This is what the PHP manual calls "Usual integer indices (starting
-from zero, increasing by one)". This is the type of array you get in PHP by
-default if you use array() without specifying key values, or use the
-empty-bracket assignment operator to add values onto an array. In previous
-versions of PHPlot, some of these functions would also work with
-string-indexed or non-sequentially-indexed arrays, but this was not clearly
-defined. Starting with PHPlot-5.0.4, only arrays with "usual integer
-indices" work, and other array indexes will cause errors.
-
-Some internal-use-only functions have had their usage changed or been removed.
-If you are using functions that are not documented in the PHPlot Function
-Reference in the manual, your code may have to be changed.
-
-As part of the code cleanup, two functions which were defined outside the
-PHPlot class were removed: array_pad_array(), and array_merge_php4().
-If your code used these, you need to fix your code.
-
-The routines which accept a color name, value, or array now check for a valid
-color name. If you specify a color name which is not in your current color
-table, PHPlot will draw an error and exit. Previously, PHP would report an
-index error, continue, and get a 'headers already sent' message.
-
-
-Bug Fixes in 5.0.4:
-
-#1813021: Miss-positioned right-justified vertical GD text.
- Fixed DrawText() to correctly position 90 degree right-justified text
- drawn in a fixed GD font. This could be seen with 90 degree Y tick labels.
-
-#1790441 Removed destructor/shutdown function, and no longer recommend
- using reference assignment when creating a PHPlot object. This was
- interfering with memory usage.
- Credit to annajilly for analysis.
-
-#1779115 SetLegendWorld() failed because of undefined variables. The
- required order dependency was too hard to meet. This is now fixed.
- You can now use SetLegendWorld anywhere before DrawGraph.
-
-#1726810 (feature request, but actually a bug fix) Ignore empty strings
- as data labels when doing time or data label formatting. These would
- previously produce errors or bad formatting. Now you can omit labels
- as needed even with time and data formatting.
- Credit to exgerhardr for finding this.
-
-#1605555 Y data labels used wrong font and not formatted (bar charts only).
-
-#1208054 Localization of number formatting in 'data' format type. PHPlot
- will attempt to format the numbers in a way appropriate to your locale.
- You can also force the formatting with the new function SetNumberFormat.
- Credit to David Hernández Sanz.
-
-#937944 X/Y Tick counts: PHPlot could draw one two few Y tick counts, and
- one too many X tick counts. This is not a perfect fix, and more work is
- needed here, but this fixes an error case in both X and Y values.
-
-
-New Features in 5.0.4:
-
-New function SetLegendStyle allows control of the alignment of text and
- color boxes within the legend. Also allows removing the color boxes.
- Based on bug #1208054.
- Credit to David Hernández Sanz.
-
-New function SetNumberFormat. See bug report #1208054 above.
-
-Callbacks are added. PHPlot can call back your functions while generating the
- plot. This is experimental, and documented only in the file "Callbacks".
- Credit to annajilly for the idea and design.
-
------------------------------------------------------------------------------
-
-2006-11-13 Released 5.0rc3
-
-Overview:
-
-This is an interim release. It has been a long time since the previous
-release 5.0rc2, and there have been a lot of changes. There are still more
-changes likely to go in before we have "5.0", but there are enough for now.
-
-The PHPlot Reference Manual has also been released, and is available as a
-separate download from Sourceforge. PHPlot users and developers are
-strongly encouraged to read the manual.
-
-This release does not include the "doc/" and "examples/" directories of
-previous releases. The Reference Manual contains more complete and
-up-to-date information and examples, and I am unable to maintain the doc/
-and examples/ files while also maintaining the Reference Manual. If you
-need those files, they can be accessed with the Sourceforge web CVS
-browser.
-
-
-New Features:
-
-The emphasis for this release is bug fixing, so there are few new features.
-
-+ You can now suppress lines or points on individual plots in a linepoints
- graph. This feature was added because I needed a graph with several
- linepoints lines, but also with a solid line showing an "80% goal".
- Use SetPointShapes with the value 'none' in the array to suppress the
- point markers for that plot (and only draw the line).
- Use SetLineStyles with the value 'none' in the array to suppress the
- line for that plot (and only draw the point markers).
- [Bug # 1594458]
-
-+ Bar charts can have data labels above the bar with the value. Turn
- these on with SetYDataLabelPos('plotin'). This is somewhat experimental,
- since there isn't a lot of room for labels on top of the bars and you
- may find the results are not useful.
-
-
-Visible Changes:
-
-Here are the more significant changes in this release. These are changes
-which may affect existing scripts and output from PHPlot. See the
-ChangeLog file for information about all changes and bug fixes.
-
-+ A bug fix on bar chart bar borders results in black borders around the
- bars if shading is turned off. The border was previously covered up,
- but was supposed to be there. If you need borderless, unshaded bars,
- you need to use SetDataBorderColors to make the borders the same colors
- as the bars. [Bug # 1096197]
-
-+ TrueType font pathname handling was fixed. You no longer need to use
- SetUseTTF(True). You can either use full paths to the font files with
- SetDefaultTTFont() and SetFont(), or you can call SetTTFPath() to point
- to a directory of font files, and then use simple font filenames without
- paths in SetDefaultTTFont() and SetFont().
- [Bug # 1144644 plus several others]
-
-+ There have been several fixes regarding automatically calculated ranges
- and scales. The result is that you may see less extra space and fewer
- tick marks in some cases.
-
-+ A fix was made to bar and stackedbar graph bar widths in order to get
- the X axis labels to properly center. As part of the fix, the bar widths
- now match between the two graph types. (Before this fix, the bars were
- narrower in bar graphs compared to the same data plotted as a stacked
- bar.) As a result, bar graph bars will now be drawn with wider bars, and
- stackedbar graph bars will be narrower. You can adjust this with the new
- class variable bar_extra_space. [Bug # 1437912]
-
-+ Dot shapes and sizes were off by 1 or 2 slots in the array of shapes or
- sizes. After the fix, you may get different dot shapes or sizes per
- plot line. [Bug # 1096194]
-
-
-Testing:
-
-Since its output is visual (graphics), and it has so many interconnected
-modes and options, PHPlot is difficult to test. But at least we are now
-trying. I have a collection of PHPlot scripts (currently about 60) and a
-script to run through them. The script automatically checks that:
- 1) Nothing was written to the standard error stream;
- 2) An image file of size greater than 0 was written;
- 3) Neither the test script nor PHPlot did exit(). This catches cases
- where PHPlot aborts with DrawError().
-
-The automated test is an easy way to check for serious regression, but you
-really need to inspect the output files to validate PHPlot. This takes a
-little time, and it is easy to overlook problems.
-
-The real issue is test coverage. Just as we can be sure that future
-PHPlot releases will pass the test collection, we can also be sure that
-future bug reports will be written against untested cases.
-
---------------------
-
-2006-11-08 PHPlot on Sourceforge has a new maintainer: lbayuk
-
---------------------
-
-2004-10-24 Released 5.0rc2
-
---------------------
-
+++ /dev/null
-This is the README file for PHPlot
-Last updated for PHPlot-5.3.1 on 2011-01-15
-The project web site is http://sourceforge.net/projects/phplot/
-The project home page is http://phplot.sourceforge.net/
------------------------------------------------------------------------------
-
-OVERVIEW:
-
-PHPlot is a PHP class for creating scientific and business charts.
-
-The release documentation contains only summary information. For more
-complete information, download the PHPlot Reference Manual from the
-Sourceforge project web site. You can also view the manual online at
-http://phplot.sourceforge.net
-
-For information about changes in this release, including any possible
-incompatibilities, see the NEWS.txt file.
-
-
-CONTENTS:
-
- COPYING . . . . . . . . . . . . LGPL 2.1 License file
- ChangeLog . . . . . . . . . . . Lists changes to the sources
- NEWS.txt . . . . . . . . . . . . Highlights changes in releases
- README.txt . . . . . . . . . . This file
- contrib . . . . . . . . . . . . "Contributed" directory, add-ons
- phplot.php . . . . . . . . . . The main PHPlot source file
- rgb.inc.php . . . . . . . . . . Optional extended color table
-
-
-REQUIREMENTS:
-
-You need a recent version of PHP5, and you are advised to use the latest
-stable release. This version of PHPlot has been tested with PHP-5.3.5 and
-PHP-5.2.17 on Linux, and with PHP-5.3.5 on Windows XP.
-
-Use of PHP-5.3.2 or PHP-5.2.13 is not recommended, if you are using
-TrueType Font (TTF) text. A bug with TTF rendering in those versions
-affects PHPlot images. This was fixed in PHP-5.3.3 and PHP-5.2.14.
-
-You need the GD extension to PHP either built in to PHP or loaded as a
-module. Refer to the PHP documentation for more information - see the
-Image Functions chapter in the PHP Manual. We test PHPlot only with the
-PHP-supported, bundled GD library.
-
-If you want to display PHPlot charts on a web site, you need a PHP-enabled
-web server. You can also use the PHP CLI interface without a web server.
-
-PHPlot supports TrueType fonts, but does not include any TrueType font
-files. If you want to use TrueType fonts on your charts, you need to have
-TrueType support in GD, and some TrueType font files. By default, PHPlot
-uses a simple font which is built in to the GD library.
-
-
-INSTALLATION:
-
-Unpack the distribution. (If you are reading this file, you have probably
-already done that.)
-
-Installation of PHPlot simply involves copying two script files somewhere
-your PHP application scripts will be able to find them. The scripts are:
- phplot.php - The main script file
- rgb.inc.php - Optional large color table
-Make sure the permissions on these files allow the web server to read them.
-
-The ideal place is a directory outside your web server document area,
-and on your PHP include path. You can add to the include path in the PHP
-configuration file; consult the PHP manual for details.
-
-
-KNOWN ISSUES:
-
-Here are some of the problems we know about in PHPlot. See the bug tracker
-on the PHPlot project web site for more information.
-
-#3142124 Clip plot elements to plot area
- Plot elements are not currently clipped to the plot area, and may extend
- beyond. PHP does not currently support the GD clipping control.
-
-#1795969 The automatic range calculation for Y values needs to be rewritten.
- This is especially a problem with small offset ranges (e.g. Y=[999:1001]).
- You can use SetPlotAreaWorld to set a specific range instead.
-
-#1605558 Wide/Custom dashed lines don't work well
- This is partially a GD issue, partially PHPlot's fault.
-
-#2919086 Improve tick interval calculations
- Tick interval calculations should try for intervals of 1, 2, or 5 times
- a power of 10.
-
-PHP Issues:
-
- PHP has many build-time and configuration options, and these can affect
-the operation of PHPlot (as well as any other application or library). Here
-are some known issues:
- + Slackware Linux includes a version of PHP built with --enable-gd-jis-conv
-(JIS-mapped Japanese font support). This prevents the usual UTF-8 encoding
-of characters from working in TrueType Font (TTF) text strings.
- + The Ubuntu Linux PHP GD package (php5-gd) was built to use the external
-shared GD library, not the one bundled with PHP. This can result in small
-differences in images, and some unsupported features (such as advanced
-truecolor image operations). Also, although this Ubuntu GD library was
-built with fontconfig support, PHP does not use it, so you still need to
-specify TrueType fonts with their actual file names.
- + Some PHP installations may have a memory limit set too low to support
-large images, especially truecolor images.
-
-
-If you think you found a problem with PHPlot, or want to ask questions or
-provide feedback, please use the Help and Discussion forum at
- http://sourceforge.net/projects/phplot/
-If you are sure you have found a bug, you can report it on the Bug tracker
-at the same web site. There is also a Features Request tracker.
-
-
-TESTING:
-
-You can test your installation by creating the following two files somewhere
-in your web document area. First, the HTML file:
-
------------- simpleplot.html ----------------------------
-<html>
-<head>
-<title>Hello, PHPlot!</title>
-</head>
-<body>
-<h1>PHPlot Test</h1>
-<img src="simpleplot.php">
-</body>
-</html>
----------------------------------------------------------
-
-Second, in the same directory, the image file producing PHP script file.
-Depending on where you installed phplot.php, you may need to specify a path
-in the 'require' line below.
-
------------- simpleplot.php -----------------------------
-<?php
-require 'phplot.php';
-$plot = new PHPlot();
-$data = array(array('', 0, 0), array('', 1, 9));
-$plot->SetDataValues($data);
-$plot->SetDataType('data-data');
-$plot->DrawGraph();
----------------------------------------------------------
-
-Access the URL to 'simpleplot.html' in your web browser. If you see a
-simple graph, you have successfully installed PHPlot. If you see no
-graph, check your web server error log for more information.
-
-
-COPYRIGHT and LICENSE:
-
-PHPlot is Copyright (C) 1998-2011 Afan Ottenheimer
-
-This is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation;
-version 2.1 of the License.
-
-This software 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this software; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+++ /dev/null
-This is the README for PHPlot Contributed Code
-The project web site is http://sourceforge.net/projects/phplot/
-Last updated on 2009-12-08
------------------------------------------------------------------------------
-
-The PHPlot Contributed Code directory contains code you might find useful
-with PHPlot, but that doesn't quite belong as part of PHPlot itself.
-
-You will have to read the comments in the code files, and see the example
-files, to determine what these do and if they are useful to you. None of
-these functions is documented in the PHPlot Reference Manual.
-
-You may include or paste these functions into your own scripts. Check the
-files for details, but some of these are considered "public domain" with no
-usage or license restrictions.
-
------------------------------------------------------------------------------
-Contents:
-
-prune_labels: Reduce the number of labels along the X axis
- prune_labels.php . . . . . . . . . . . . Code
- prune_labels.example.php . . . . . . . . Example
- prune_labels.test.php . . . . . . . . . Test
-
-color_range: Create a gradient color map for data colors
- color_range.php . . . . . . . . . . . . Code
- color_range.example.php . . . . . . . . Example
- color_range.test1.php . . . . . . . . . Image creation test
- color_range.test2.php . . . . . . . . . Unit test
-
------------------------------------------------------------------------------
+++ /dev/null
-<?php
-# PHPlot / contrib / color_range : Example
-# $Id: color_range.example.php,v 1.1 2009/12/09 03:45:45 lbayuk Exp $
-# This is a bar chart with a color gradient for the bars in each group.
-
-require_once 'phplot.php';
-require_once 'color_range.php';
-
-$bars_per_group = 10;
-$x_values = 4;
-
-mt_srand(1);
-$data = array();
-for ($i = 0; $i < $x_values; $i++) {
- $row = array($i);
- for ($j = 0; $j < $bars_per_group; $j++) $row[] = mt_rand(0, 100);
- $data[] = $row;
-}
-
-$p = new PHPlot(800, 600);
-$p->SetTitle('Example - Bar Chart with gradient colors');
-$p->SetDataType('text-data');
-$p->SetDataValues($data);
-$p->SetPlotAreaWorld(0, 0, $x_values, 100);
-
-# This isn't necessary, as we do know how many data sets (bars_per_group):
-$n_data = count_data_sets($data, 'text-data');
-# Make a gradient color map:
-$colors = color_range($p->SetRGBColor('SkyBlue'),
- $p->SetRGBColor('DarkGreen'), $n_data);
-$p->SetDataColors($colors);
-$p->SetXTickLabelPos('none');
-$p->SetXTickPos('none');
-$p->SetPlotType('bars');
-$p->DrawGraph();
+++ /dev/null
-<?php
-/*
- PHPlot / contrib / color_range
- $Id: color_range.php,v 1.2 2010/10/03 21:57:15 lbayuk Exp $
- PHPlot contrib code - public domain - no copyright - use as you wish
-
- Original contribution from: Josep Sanz <josep dot sans at w3 dot es>
- "I wrote this code to calculate the range of colors between 2 colors
- to plot using the range from color_a to color_b..."
-
- I have changed the code and repackaged it, but the idea is the same.
- Given 2 colors and number of data sets, computes an array of colors
- that make up a gradient between the two provided colors, for use
- with SetDataColors().
-
- Provides the following functions:
- $colors = color_range($color_a, $color_b, $n_intervals)
- Returns a color array for SetDataColors.
-
- $n = count_data_sets($data, $data_type)
- Counts the number of data sets in a data array.
- This can be used to provide $n_intervals in color_range().
-*/
-
-
-
-/*
- Fill a color map with a gradient step between two colors.
- Arguments:
- $color_a : Starting color for the gradient. Array of (r, g, b)
- $color_b : Ending color for the gradient. Array of (r, g, b)
- $n_steps : Total number of color steps, including color_a and color_b.
-
- Returns: A color map array with n_steps colors in the form
- $colors[i][3], suitable for SetDataColors().
-
- Notes:
- You may use the PHPlot internal function $plot->SetRGBColor($color)
- to convert a color name or #rrggbb notation into the required array
- of 3 values (r, g, b) for color_a and color_b.
-
- Newer versions of PHPlot use 4 components (r, g, b, a) arrays for color.
- This script ignores the alpha component in those arrays.
-
-*/
-function color_range($color_a, $color_b, $n_steps)
-{
- if ($n_steps < 2) $n_steps = 2;
- $nc = $n_steps - 1;
- # Note: $delta[] and $current[] are kept as floats. $colors is integers.
- for ($i = 0; $i < 3; $i++)
- $delta[$i] = ($color_b[$i] - $color_a[$i]) / $nc;
- $current = $color_a;
- for ($col = 0; $col < $nc; $col++) {
- for ($i = 0; $i < 3; $i++) {
- $colors[$col][$i] = (int)$current[$i];
- $current[$i] += $delta[$i];
- }
- }
- $colors[$nc] = $color_b; # Make sure the last color is exact.
- return $colors;
-}
-
-
-/*
- Determine the number of data sets (plot lines, bars per group, pie
- segments, etc.) contained in a data array.
- This can be used to determine n_steps for $color_range.
-
- Arguments:
- $data : PHPlot data array
- $data_type : PHPlot data type, describing $data. (e.g. 'data-data')
- Returns: The number of data sets in the data array.
- Notes:
- This has to scan the entire data array. Don't use this unless you
- really don't have a better way to determine the number of data sets.
-
- This does NOT require that the data array be integer indexed.
-
-*/
-function count_data_sets($data, $data_type)
-{
-
- if ($data_type == 'text-data-single')
- return count($data); # Pie chart, 1 segment per record
-
- # Get the longest data record:
- $max_row = 0;
- foreach ($data as $row)
- if (($n = count($row)) > $max_row) $max_row = $n;
-
- if ($data_type == 'text-data' || $data_type == 'text-data-yx')
- return ($max_row - 1); # Each record is (label Y1 Y2...)
-
- if ($data_type == 'data-data' || $data_type == 'data-data-yx')
- return ($max_row - 2); # Each record is (label X Y1 Y2...)
-
- if ($data_type == 'data-data-error')
- return (($max_row - 2) / 3); # Each record is (label X Y1 Y1+ Y1-...)
-
- # Not a recognized data type... Just return something sane.
- return $max_row;
-}
+++ /dev/null
-<?php
-# PHPlot / contrib / color_range : Test 1, make a picture
-# $Id: color_range.test1.php,v 1.1 2009/12/09 03:45:49 lbayuk Exp $
-# This creates a PNG file on output with a color gradient.
-
-require_once 'color_range.php';
-
-function usage()
-{
- fwrite(STDERR, "Usage: color_range.test1.php color1 color2 number_of_colors
-Each color is of the form rrggbb with 2 digit hex color components.
-");
- exit(1);
-}
-
-# Split color "rrggbb" into separate components. Code is from PHPlot.
-function rgb($color)
-{
- return array(hexdec(substr($color, 1, 2)),
- hexdec(substr($color, 3, 2)),
- hexdec(substr($color, 5, 2)));
-}
-
-if ($_SERVER['argc'] != 4) usage();
-
-$color1 = rgb($_SERVER['argv'][1]);
-$color2 = rgb($_SERVER['argv'][2]);
-$n_col = (int)$_SERVER['argv'][3];
-if ($n_col < 2) usage();
-
-# Build a color map from colors[0]=color1 to colors[$n_col-1]=color2.
-$colors = color_range($color1, $color2, $n_col);
-
-# Make a picture:
-$w = 800;
-$h = 800;
-$im = imagecreate($w, $h);
-$background = imagecolorresolve($im, 0, 0, 0);
-for ($col = 0; $col < $n_col; $col++) {
- list($r, $g, $b) = $colors[$col];
- $colmap[$col] = imagecolorresolve($im, $r, $g, $b);
-}
-
-$margin = 20;
-$bar_width = (int)(($w - 2 * $margin) / $n_col);
-$x1 = $margin;
-$x2 = $x1 + $bar_width;
-$y1 = $margin;
-$y2 = $h - $margin;
-for ($col = 0; $col < $n_col; $col++) {
- imagefilledrectangle($im, $x1, $y1, $x2, $y2, $colmap[$col]);
- $x1 = $x2;
- $x2 += $bar_width;
-}
-imagepng($im);
+++ /dev/null
-<?php
-/*
- PHPlot / contrib / color_range : Unit tests
- $Id: color_range.test2.php,v 1.1 2009/12/09 03:45:51 lbayuk Exp $
-
- Tests color.range.php functions:
- color_range($color_a, $color_b, $n_steps)
- count_data_sets($data, $data_type)
-
-*/
-require_once 'color_range.php';
-
-
-# Testing count_data_sets()
-function test_count_data_sets($data, $data_type, $expected)
-{
- $n = count_data_sets($data, $data_type);
- if ($n == $expected) $result = "Pass";
- else $result = "FAIL: Expected $expected but got";
- echo "$result: $n data sets, $data_type with " . count($data) . " records.\n";
-}
-
-function test_driver_count_data_sets()
-{
- echo "\nTesting count_data_sets():\n";
- $data1 = array(array('a', 1, 2, 3), array('b', 2, 2, 3));
- $data2 = array(array('a', 1, 2, 3, 4, 5, 6, 7), array('b', 2, 4, 5, 6));
- $data3 = array(array('', 1), array('', 2), array('', 3), array('', 4));
- $data4 = array(array('', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
- array('', 1, 2, 3, 4, 5, 6, 7),
- array('', 1, 2, 3, 4));
-
- test_count_data_sets($data1, 'text-data', 3);
- test_count_data_sets($data1, 'data-data', 2);
- test_count_data_sets($data2, 'data-data-error', 2);
- test_count_data_sets($data3, 'text-data-single', 4);
-
- test_count_data_sets($data4, 'text-data', 13);
- test_count_data_sets($data4, 'data-data', 12);
- test_count_data_sets($data4, 'data-data-error', 4);
- test_count_data_sets($data4, 'text-data-single', 3);
-}
-
-# Testing color_range()
-function test_color_range($color1, $color2, $nsteps, $expected)
-{
- $info = 'From (' . implode(', ', $color1)
- . ') To (' . implode(', ', $color2) . ") with $nsteps steps";
-
- $colors = color_range($color1, $color2, $nsteps);
- if ($colors == $expected) echo "Pass: $info\n";
- else echo "FAIL: $info\n" . print_r($colors, True) . "\n";
- if (($n = count($colors)) != $nsteps)
- echo "FAIL: Bad count $n expecting $nsteps\n";
-}
-
-function test_driver_color_range()
-{
- echo "\nTesting color_range():\n";
- test_color_range(array(0,0,0), array(255,255,255), 3,
- array(array(0,0,0), array(127,127,127), array(255,255,255)));
-
- test_color_range(array(255,0,0), array(0,255,0), 2,
- array(array(255,0,0), array(0,255,0)));
-
- test_color_range(array(100,0,100), array(0,100,0), 6,
- array(array(100,0,100), array(80,20,80), array(60,40,60),
- array(40,60,40), array(20,80,20), array(0,100,0)));
-}
-
-
-test_driver_count_data_sets();
-test_driver_color_range();
+++ /dev/null
-<?php
-# PHPlot / contrib / prune_labels : Example
-# $Id: prune_labels.example.php,v 1.1 2009/12/09 03:45:53 lbayuk Exp $
-# This produces 250 data points with date-formatted labels, and sets
-# a max of 20 labels to display.
-
-require_once 'phplot.php';
-require_once 'prune_labels.php';
-
-$base = mktime(12, 0, 0, 1, 1, 2000);
-$data = array();
-for ($i = 0; $i < 250; $i++) {
- $data[] = array(86400 * $i + $base, $i, $i * 0.20);
-}
-
-# Show no more than 20 labels:
-prune_labels($data, 20);
-
-$p = new PHPlot(800, 600);
-$p->SetTitle('Example - pruned data labels');
-$p->SetDataType('data-data');
-$p->SetDataValues($data);
-$p->SetXLabelType('time', '%Y-%m-%d');
-$p->SetXLabelAngle(90);
-$p->SetXDataLabelPos('plotdown');
-$p->SetXTickLabelPos('none');
-$p->SetXTickPos('none');
-$p->SetDrawXGrid(False);
-$p->SetDrawYGrid(False);
-$p->SetPlotType('lines');
-$p->DrawGraph();
+++ /dev/null
-<?php
-/*
- PHPlot / contrib / prune_labels
- $Id: prune_labels.php,v 1.1 2009/12/09 03:45:55 lbayuk Exp $
- PHPlot contrib code - public domain - no copyright - use as you wish
-
-Reduce the number of data labels along the X axis, when the density is too
-high. This simply blanks out M-1 of every M labels in the data array.
-There are other ways to do this, but we need to keep the labels uniformly
-spaced. You select the target maximum label count (maxlabels), and you will
-get no more than maxlabels data labels.
-
- Arguments:
- $data - The PHPlot data array (reference variable)
- $maxlabels - The maximum number of data labels you are willing to have,
- Returns: Nothing
- Modifies the $data array in place to remove some of the labels.
-
- Notes:
- The data array and its rows must be 0-based integer indexed arrays.
-*/
-function prune_labels(&$data, $maxlabels)
-{
- # Do nothing if there are not already too many labels:
- if (($n = count($data)) <= $maxlabels) return;
-
- # Compute how many labels to erase. Keep 1 of every $m labels.
- $m = (int)ceil($n / $maxlabels);
-
- # Process the data array, zapping M-1 of every M labels:
- $k = 0;
- for ($i = 0; $i < $n; $i++) {
- if ($k > 0) $data[$i][0] = '';
- if (++$k >= $m) $k = 0;
- }
-}
+++ /dev/null
-<?php
-# PHPlot / contrib / prune_labels : Test
-# $Id: prune_labels.test.php,v 1.1 2009/12/09 03:45:57 lbayuk Exp $
-# Test driver for contrib / prune_labels
-
-require_once 'prune_labels.php';
-
-/* Testing the prune_labels function: */
-function test($count, $maxlabels)
-{
- # Make an array of count records, like PHPlot uses, with labels:
- $data = array();
- for ($i = 0; $i < $count; $i++) {
- $data[] = array("Row $i", $i, 100, 200, 300);
- }
-
- prune_labels($data, $maxlabels);
-
- # See how many labels are non-blank now:
- $line = '';
- $non_blank = 0;
- for ($i = 0; $i < $count; $i++) {
- if (!empty($data[$i][0])) {
- $non_blank++;
- $line .= '*';
- } else {
- $line .= '_';
- }
- }
- $status = ($non_blank <= $maxlabels) ? 'PASS' : 'FAIL';
- echo "$status: $count rows, maxlabels=$maxlabels => $non_blank labels\n";
- echo substr($line, 0, 80) . "\n"; # Only show first 80 chars.
-}
-
-/* Test cases for prune_labels */
-for ($n = 7; $n <= 1000; $n *= 2) test($n, 10);
-for ($g = 5; $g <= 40; $g++) test(72, $g);
-# Edge cases
-test(80, 41);
-test(80, 40);
-test(80, 39);
+++ /dev/null
-<?php
-/* $Id: phplot.php,v 1.216 2011/01/16 01:19:55 lbayuk Exp $ */
-/*
- * PHPLOT Version 5.3.1
- *
- * A PHP class for creating scientific and business charts
- * Visit http://sourceforge.net/projects/phplot/
- * for PHPlot documentation, downloads, and discussions.
- * ---------------------------------------------------------------------
- * Copyright (C) 1998-2011 Afan Ottenheimer
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- * ---------------------------------------------------------------------
- *
- * Co-author and maintainer (2003-2005)
- * Miguel de Benito Delgado <nonick AT vodafone DOT es>
- *
- * Maintainer (2006-present)
- * <lbayuk AT users DOT sourceforge DOT net>
- *
- * Requires PHP 5.2.x or later. (PHP 4 is unsupported as of Jan 2008)
- */
-
-class PHPlot
-{
- /* Declare class variables which are initialized to static values. Many more class variables
- * are used, defined as needed, but are unset by default.
- * All these are declared as public. While it is tempting to make them private or protected, this
- * is avoided for two reasons. First, it will break existing code, since all member variables
- * were public in PHP4 and who knows what internal variables people used. Second, it makes
- * testing harder and less effective. Nevertheless, your code should not modify these.
- */
-
- public $is_inline = FALSE; // FALSE = Sends headers, TRUE = sends just raw image data
- public $browser_cache = FALSE; // FALSE = Sends headers for browser to not cache the image,
- // (only if is_inline = FALSE also)
- public $print_image = TRUE; // DrawGraph calls PrintImage. See SetPrintImage
-
- public $safe_margin = 5; // Extra margin used in several places, in pixels
-
- public $x_axis_position = ''; // X axis position in Y world coordinates, blank for default.
- public $y_axis_position = ''; // Y axis position in X world coordinates, blank for default.
-
- public $xscale_type = 'linear'; // linear, log
- public $yscale_type = 'linear';
-
-//Fonts
- public $use_ttf = FALSE; // Use True Type Fonts by default?
- public $ttf_path = '.'; // Default path to look in for TT Fonts.
- // public $default_ttfont; // Initialized in GetDefaultTTFont
- public $line_spacing = 4; // Controls line spacing of multi-line labels
-
- // Label angles: 0 or 90 degrees for fixed fonts, any for TTF
- public $x_label_angle = 0; // For X tick labels
- // public $x_data_label_angle; // For X data labels; defaults to x_label_angle - see CheckLabels()
- public $y_label_angle = 0; // For Y tick labels
- public $y_data_label_angle = 0; // For Y data labels
-
-//Formats
- public $file_format = 'png';
- public $output_file = ''; // For output to a file instead of stdout
-
-//Data
- public $data_type = 'text-data'; // Structure of the data array
- public $plot_type = 'linepoints'; // See $plots[] below
-
- public $label_scale_position = 0.5; // Shifts data labels in pie charts. 1 = top, 0 = bottom
- public $group_frac_width = 0.7; // Bars use this fraction (0 to 1) of a group's space
- public $bar_extra_space = 0.5; // Number of extra bar's worth of space in a group
- public $bar_width_adjust = 1; // 1 = bars of normal width, must be > 0
-
-// Titles
- public $title_txt = '';
-
- public $x_title_txt = '';
- public $x_title_pos = 'none'; // plotdown, plotup, both, none
-
- public $y_title_txt = '';
- public $y_title_pos = 'none'; // plotleft, plotright, both, none
-
-//Labels
- // There are two types of labels in PHPlot:
- // Tick labels: Follow the grid, next to ticks in axis.
- // Are drawn at grid drawing time, by DrawXTicks() and DrawYTicks()
- // Data labels: Follow the data points, and can be placed on the axis or the plot (x/y)
- // Are drawn at graph plotting time, by Draw*DataLabel(), called by DrawLines(), etc.
- // DrawXDataLabel() also draws vertical lines to data points, depending on
- // draw_x_data_label_lines.
- // Tick Labels
- // Tick and Data label positions are not initialized, because PHPlot needs to tell if they
- // defaulted or are set by the user. See CheckLabels() for details. The variables and
- // effective defaults are shown here in comments (but CheckLabels adjusts the defaults).
- // public $x_tick_label_pos = 'plotdown'; // X tick label position
- // public $y_tick_label_pos = 'plotleft'; // Y tick label position
- // public $x_data_label_pos = 'plotdown'; // X data label position
- // public $y_data_label_pos = 'none'; // Y data label position
-
- public $draw_x_data_label_lines = FALSE; // Draw a line from the data point to the axis?
-
- // Label format controls: (for tick, data and plot labels)
- // Unset by default, these array members are used as needed for 'x' (x tick labels), 'xd' (x data
- // labels), 'y' (y tick labels), and 'yd' (y data labels).
- // type, precision, prefix, suffix, time_format, printf_format, custom_callback, custom_arg.
- // These replace the former: x_label_type, x_time_format, x_precision (similar for y), data_units_text.
- public $label_format = array('x' => array(), 'xd' => array(), 'y' => array(), 'yd' => array());
- // data_units_text is retained for backward compatibility, because there was never a function
- // to set it. Use the 'suffix' argument to Set[XY]LabelType instead.
- public $data_units_text = ''; // Units text for 'data' labels (i.e: '¤', '$', etc.)
-
-// Legend
- public $legend = ''; // An array with legend titles
- // These variables are unset to take default values:
- // public $legend_x_pos; // User-specified upper left coordinates of legend box
- // public $legend_y_pos;
- // public $legend_xy_world; // If set, legend_x/y_pos are world coords, else pixel coords
- // public $legend_text_align; // left or right, Unset means right
- // public $legend_colorbox_align; // left, right, or none; Unset means same as text_align
-
-//Ticks
- public $x_tick_length = 5; // tick length in pixels for upper/lower axis
- public $y_tick_length = 5; // tick length in pixels for left/right axis
-
- public $x_tick_cross = 3; // ticks cross x axis this many pixels
- public $y_tick_cross = 3; // ticks cross y axis this many pixels
-
- public $x_tick_pos = 'plotdown'; // plotdown, plotup, both, xaxis, none
- public $y_tick_pos = 'plotleft'; // plotright, plotleft, both, yaxis, none
-
- public $num_x_ticks = '';
- public $num_y_ticks = '';
-
- public $x_tick_inc = ''; // Set num_x_ticks or x_tick_inc, not both.
- public $y_tick_inc = ''; // Set num_y_ticks or y_tick_inc, not both.
-
- public $skip_top_tick = FALSE;
- public $skip_bottom_tick = FALSE;
- public $skip_left_tick = FALSE;
- public $skip_right_tick = FALSE;
-
-//Grid Formatting
- // public $draw_x_grid = FALSE; // Default is False except for swapped data type
- // public $draw_y_grid = TRUE; // Default is True except for swapped data type
-
- public $dashed_grid = TRUE;
- public $grid_at_foreground = FALSE; // Chooses whether to draw the grid below or above the graph
-
-//Colors and styles (all colors can be array (R,G,B) or named color)
- public $color_array = 'small'; // 'small', 'large' or array (define your own colors)
- // See rgb.inc.php and SetRGBArray()
- public $default_colors = array( // The default colors for data and error bars
- 'SkyBlue', 'green', 'orange', 'blue', 'red', 'DarkGreen', 'purple', 'peru',
- 'cyan', 'salmon', 'SlateBlue', 'YellowGreen', 'magenta', 'aquamarine1', 'gold', 'violet');
-
- // See SetDefaultStyles() for default colors for PHPlot elements.
-
- public $line_widths = 1; // single value or array
- public $line_styles = array('solid', 'solid', 'dashed'); // single value or array
- public $dashed_style = '2-4'; // colored dots-transparent dots
-
- public $point_sizes = array(6); // Array of sizes for points. See CheckPointParams()
- public $point_shapes = array( // Array of point shapes. See SetPointShapes() and DrawDot()
- 'diamond', 'dot', 'delta', 'home', 'yield', 'box', 'circle', 'up', 'down', 'cross'
- );
-
- public $error_bar_size = 5; // right and left size of tee
- public $error_bar_shape = 'tee'; // 'tee' or 'line'
- public $error_bar_line_width = 1; // single value (or array TODO)
-
- public $plot_border_type = 'sides'; // left, right, top, bottom, sides, none, full; or array
- public $image_border_type = 'none'; // 'raised', 'plain', 'none'
- // public $image_border_width; // NULL, 0, or unset for default. Default depends on type.
-
- public $shading = 5; // 0 for no shading, > 0 is size of shadows in pixels
-
- public $draw_plot_area_background = FALSE;
- public $draw_broken_lines = FALSE; // Tells not to draw lines for missing Y data.
-
-//Miscellaneous
- public $callbacks = array( // Valid callback reasons (see SetCallBack)
- 'draw_setup' => NULL,
- 'draw_image_background' => NULL,
- 'draw_plotarea_background' => NULL,
- 'draw_titles' => NULL,
- 'draw_axes' => NULL,
- 'draw_graph' => NULL,
- 'draw_border' => NULL,
- 'draw_legend' => NULL,
- 'draw_all' => NULL,
- 'data_color' => NULL,
- 'debug_textbox' => NULL, // For testing/debugging text box alignment
- 'debug_scale' => NULL, // For testing/debugging scale setup
- );
-
- // Defined plot types static array:
- // Array key is the plot type. (Upper case letters are not allowed due to CheckOption)
- // Value is an array with these keys:
- // draw_method (required) : Class method to call to draw the plot.
- // draw_arg : Optional array of arguments to pass to draw_method.
- // draw_axes : If FALSE, do not draw X/Y axis lines, labels, ticks, grid, titles.
- // abs_vals, sum_vals : Data array processing flags. See FindDataLimits().
- static protected $plots = array(
- 'area' => array(
- 'draw_method' => 'DrawArea',
- 'abs_vals' => TRUE,
- ),
- 'bars' => array(
- 'draw_method' => 'DrawBars',
- ),
- 'candlesticks' => array(
- 'draw_method' => 'DrawOHLC',
- 'draw_arg' => array(TRUE, FALSE), // Draw candlesticks, only fill if "closed down"
- ),
- 'candlesticks2' => array(
- 'draw_method' => 'DrawOHLC',
- 'draw_arg' => array(TRUE, TRUE), // Draw candlesticks, fill always
- ),
- 'linepoints' => array(
- 'draw_method' => 'DrawLinePoints',
- ),
- 'lines' => array(
- 'draw_method' => 'DrawLines',
- ),
- 'ohlc' => array(
- 'draw_method' => 'DrawOHLC',
- 'draw_arg' => array(FALSE), // Don't draw candlesticks
- ),
- 'pie' => array(
- 'draw_method' => 'DrawPieChart',
- 'draw_axes' => FALSE,
- 'abs_vals' => TRUE,
- ),
- 'points' => array(
- 'draw_method' => 'DrawDots',
- ),
- 'squared' => array(
- 'draw_method' => 'DrawSquared',
- ),
- 'stackedarea' => array(
- 'draw_method' => 'DrawArea',
- 'draw_arg' => array(TRUE), // Tells DrawArea to draw stacked area plot
- 'sum_vals' => TRUE,
- 'abs_vals' => TRUE,
- ),
- 'stackedbars' => array(
- 'draw_method' => 'DrawStackedBars',
- 'sum_vals' => TRUE,
- ),
- 'thinbarline' => array(
- 'draw_method' => 'DrawThinBarLines',
- ),
- );
-
-//////////////////////////////////////////////////////
-//BEGIN CODE
-//////////////////////////////////////////////////////
-
- /*
- * Constructor: Setup img resource, colors and size of the image, and font sizes.
- *
- * $which_width : Image width in pixels.
- * $which_height : Image height in pixels.
- * $which_output_file : Filename for output.
- * $which_input_file : Path to a file to be used as background.
- */
- function PHPlot($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
- {
- $this->SetRGBArray($this->color_array);
-
- if ($which_output_file)
- $this->SetOutputFile($which_output_file);
-
- if ($which_input_file) {
- $this->SetInputFile($which_input_file);
- } else {
- $this->image_width = $which_width;
- $this->image_height = $which_height;
-
- $this->img = ImageCreate($this->image_width, $this->image_height);
- if (! $this->img)
- return $this->PrintError('PHPlot(): Could not create image resource.');
- }
-
- $this->SetDefaultStyles();
- $this->SetDefaultFonts();
- }
-
- /*
- * Reads an image file. Stores width and height, and returns the image
- * resource. On error, calls PrintError and returns False.
- * This is used by the constructor via SetInputFile, and by tile_img().
- */
- protected function GetImage($image_filename, &$width, &$height)
- {
- $error = '';
- $size = getimagesize($image_filename);
- if (!$size) {
- $error = "Unable to query image file $image_filename";
- } else {
- $image_type = $size[2];
- switch ($image_type) {
- case IMAGETYPE_GIF:
- $img = @ ImageCreateFromGIF ($image_filename);
- break;
- case IMAGETYPE_PNG:
- $img = @ ImageCreateFromPNG ($image_filename);
- break;
- case IMAGETYPE_JPEG:
- $img = @ ImageCreateFromJPEG ($image_filename);
- break;
- default:
- $error = "Unknown image type ($image_type) for image file $image_filename";
- break;
- }
- }
- if (empty($error) && !$img) {
- // getimagesize is OK, but GD won't read it. Maybe unsupported format.
- $error = "Failed to read image file $image_filename";
- }
- if (!empty($error)) {
- return $this->PrintError("GetImage(): $error");
- }
- $width = $size[0];
- $height = $size[1];
- return $img;
- }
-
- /*
- * Selects an input file to be used as background for the whole graph.
- * This resets the graph size to the image's size.
- * Note: This is used by the constructor. It is deprecated for direct use.
- */
- function SetInputFile($which_input_file)
- {
- $im = $this->GetImage($which_input_file, $this->image_width, $this->image_height);
- if (!$im)
- return FALSE; // GetImage already produced an error message.
-
- // Deallocate any resources previously allocated
- if (isset($this->img))
- imagedestroy($this->img);
-
- $this->img = $im;
-
- // Do not overwrite the input file with the background color.
- $this->done['background'] = TRUE;
-
- return TRUE;
- }
-
-/////////////////////////////////////////////
-////////////// COLORS
-/////////////////////////////////////////////
-
- /*
- * Allocate a GD color index for a color specified by a 4 component array.
- * When a color is requested, it is parsed and checked by SetRGBColor, and then saved as an array
- * of (R,G,B,A) components. At graph drawing time, this function is used to allocate the color.
- * $color : The color specification as a 4 component array: R, G, B, A.
- * Returns: A GD color index that can be used when drawing.
- */
- protected function GetColorIndex($color)
- {
- list($r, $g, $b, $a) = $color;
- return imagecolorresolvealpha($this->img, $r, $g, $b, $a);
- }
-
- /*
- * Allocate an array of GD color indexes for an array of color specifications.
- * This is used for the data_colors array, for example.
- * $color_array : Array of color specifications, each an array of R,G,B,A components.
- * This must use 0-based sequential integer indexes.
- * $max_colors : Limit color allocation to no more than this.
- * Returns an array of GD color indexes.
- */
- protected function GetColorIndexArray($color_array, $max_colors)
- {
- $n = min(count($color_array), $max_colors);
- $result = array();
- for ($i = 0; $i < $n; $i++)
- $result[] = $this->GetColorIndex($color_array[$i]);
- return $result;
- }
-
- /*
- * Allocate an array of GD color indexes for darker shades of an array of color specifications.
- * $color_array : Array of color specifications, each an array of R,G,B,A components.
- * $max_colors : Limit color allocation to this many colors from the array.
- * Returns an array of GD color indexes.
- */
- protected function GetDarkColorIndexArray($color_array, $max_colors)
- {
- $n = min(count($color_array), $max_colors);
- $result = array();
- for ($i = 0; $i < $n; $i++)
- $result[] = $this->GetDarkColorIndex($color_array[$i]);
- return $result;
- }
-
- /*
- * Allocate a GD color index for a darker shade of a color specified by a 4 component array.
- * See notes for GetColorIndex() above.
- * $color : The color specification as a 4 component array: R, G, B, A.
- * Returns: A GD color index that can be used when drawing.
- */
- protected function GetDarkColorIndex($color)
- {
- list ($r, $g, $b, $a) = $color;
- $r = max(0, $r - 0x30);
- $g = max(0, $g - 0x30);
- $b = max(0, $b - 0x30);
- return imagecolorresolvealpha($this->img, $r, $g, $b, $a);
- }
-
- /*
- * Sets/reverts all colors and styles to their defaults.
- */
- protected function SetDefaultStyles()
- {
- $this->SetDefaultDashedStyle($this->dashed_style);
- $this->SetImageBorderColor(array(194, 194, 194));
- $this->SetPlotBgColor('white');
- $this->SetBackgroundColor('white');
- $this->SetTextColor('black');
- $this->SetGridColor('black');
- $this->SetLightGridColor('gray');
- $this->SetTickColor('black');
- $this->SetTitleColor('black');
- // These functions set up the default colors when called without parameters
- $this->SetDataColors();
- $this->SetErrorBarColors();
- $this->SetDataBorderColors();
- return TRUE;
- }
-
- /*
- * Set the image background color to $which_color.
- */
- function SetBackgroundColor($which_color)
- {
- return (bool)($this->bg_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the plot area background color (if enabled) to $which_color.
- */
- function SetPlotBgColor($which_color)
- {
- return (bool)($this->plot_bg_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the color of the titles (main, X, and Y) to $which_color.
- * See also SetXTitleColor and SetYTitleColor.
- */
- function SetTitleColor($which_color)
- {
- return (bool)($this->title_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the color of the X title to $which_color.
- * This overrides the color set with SetTitleColor.
- */
- function SetXTitleColor($which_color)
- {
- return (bool)($this->x_title_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the color of the Y title to $which_color.
- * This overrides the color set with SetTitleColor.
- */
- function SetYTitleColor($which_color)
- {
- return (bool)($this->y_title_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the color of the axis tick marks to $which_color.
- */
- function SetTickColor($which_color)
- {
- return (bool)($this->tick_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Deprecated. Use SetTitleColor()
- */
- function SetLabelColor($which_color)
- {
- return $this->SetTitleColor($which_color);
- }
-
- /*
- * Set the general text color (tick and data labels, legend, etc) to $which_color.
- */
- function SetTextColor($which_color)
- {
- return (bool)($this->text_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the X and Y grid colors to $which_color. Also sets the data label line color.
- */
- function SetLightGridColor($which_color)
- {
- return (bool)($this->light_grid_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the color used for the X and Y axis, plot border, legend border to $which_color.
- * Note: This has nothing to do with the grid, and we don't recall where this name came from.
- */
- function SetGridColor($which_color)
- {
- return (bool)($this->grid_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Set the color used for the image border to $which_color.
- */
- function SetImageBorderColor($which_color)
- {
- return (bool)($this->i_border = $this->SetRGBColor($which_color));
- }
-
- /*
- * Designate color $which_color to be transparent, if supported by the image format.
- */
- function SetTransparentColor($which_color)
- {
- return (bool)($this->transparent_color = $this->SetRGBColor($which_color));
- }
-
- /*
- * Sets the array of colors to be used. It can be user defined, a small predefined one
- * or a large one included from 'rgb.inc.php'.
- *
- * $which_color_array : A color array, or 'small' or 'large'.
- * Color arrays map color names into arrays of R, G, B and optionally A values.
- */
- function SetRGBArray($which_color_array)
- {
- if (is_array($which_color_array)) { // User defined array
- $this->rgb_array = $which_color_array;
- } elseif ($which_color_array == 'small') { // Small predefined color array
- $this->rgb_array = array(
- 'white' => array(255, 255, 255),
- 'snow' => array(255, 250, 250),
- 'PeachPuff' => array(255, 218, 185),
- 'ivory' => array(255, 255, 240),
- 'lavender' => array(230, 230, 250),
- 'black' => array( 0, 0, 0),
- 'DimGrey' => array(105, 105, 105),
- 'gray' => array(190, 190, 190),
- 'grey' => array(190, 190, 190),
- 'navy' => array( 0, 0, 128),
- 'SlateBlue' => array(106, 90, 205),
- 'blue' => array( 0, 0, 255),
- 'SkyBlue' => array(135, 206, 235),
- 'cyan' => array( 0, 255, 255),
- 'DarkGreen' => array( 0, 100, 0),
- 'green' => array( 0, 255, 0),
- 'YellowGreen' => array(154, 205, 50),
- 'yellow' => array(255, 255, 0),
- 'orange' => array(255, 165, 0),
- 'gold' => array(255, 215, 0),
- 'peru' => array(205, 133, 63),
- 'beige' => array(245, 245, 220),
- 'wheat' => array(245, 222, 179),
- 'tan' => array(210, 180, 140),
- 'brown' => array(165, 42, 42),
- 'salmon' => array(250, 128, 114),
- 'red' => array(255, 0, 0),
- 'pink' => array(255, 192, 203),
- 'maroon' => array(176, 48, 96),
- 'magenta' => array(255, 0, 255),
- 'violet' => array(238, 130, 238),
- 'plum' => array(221, 160, 221),
- 'orchid' => array(218, 112, 214),
- 'purple' => array(160, 32, 240),
- 'azure1' => array(240, 255, 255),
- 'aquamarine1' => array(127, 255, 212)
- );
- } elseif ($which_color_array == 'large') { // Large color array
- if (!@include('rgb.inc.php')) {
- return $this->PrintError("SetRGBArray(): Large color map could not be loaded\n"
- . "from 'rgb.inc.php'.");
- }
- $this->rgb_array = $ColorArray;
- } else { // Default to black and white only.
- $this->rgb_array = array('white' => array(255, 255, 255), 'black' => array(0, 0, 0));
- }
-
- return TRUE;
- }
-
- /*
- * Parse a color description and return the color component values.
- * Arguments:
- * $color_asked : The desired color description, in one of these forms:
- * Component notation: array(R, G, B) or array(R, G, B, A) with each
- * in the range described below for the return value.
- * Examples: (255,255,0) (204,0,0,30)
- * Hex notation: "#RRGGBB" or "#RRGGBBAA" where each pair is a 2 digit hex number.
- * Examples: #FF00FF (magenta) #0000FF40 (Blue with alpha=64/127)
- * Named color in the current colormap, with optional suffix ":alpha" for alpha value.
- * Examples: blue red:60 yellow:20
- * $alpha : optional default alpha value. This is applied to the color if it doesn't
- * already have an alpha value. If not supplied, colors are opaque (alpha=0) by default.
- *
- * Returns an array describing a color as (R, G, B, Alpha).
- * R, G, and B are integers 0-255, and Alpha is 0 (opaque) to 127 (transparent).
- * Note: This function should be considered 'protected', and is not documented for public use.
- */
- function SetRGBColor($color_asked, $alpha = 0)
- {
- if (empty($color_asked)) {
- $ret_val = array(0, 0, 0);
-
- } elseif (is_array($color_asked) && (($n = count($color_asked)) == 3 || $n == 4) ) {
- // Already an array of 3 or 4 elements:
- $ret_val = $color_asked;
-
- } elseif (preg_match('/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i',
- $color_asked, $ss)) {
- // #RRGGBB or #RRGGBBAA notation:
- $ret_val = array(hexdec($ss[1]), hexdec($ss[2]), hexdec($ss[3]));
- if (isset($ss[4])) $ret_val[] = hexdec($ss[4]);
-
- } elseif (isset($this->rgb_array[$color_asked])) {
- // Color by name:
- $ret_val = $this->rgb_array[$color_asked];
-
- } elseif (preg_match('/(.+):([\d]+)$/', $color_asked, $ss)
- && isset($this->rgb_array[$ss[1]])) {
- // Color by name with ":alpha" suffix, alpha is a decimal number:
- $ret_val = $this->rgb_array[$ss[1]];
- $ret_val[3] = (int)$ss[2];
-
- } else {
- return $this->PrintError("SetRGBColor(): Color '$color_asked' is not valid.");
- }
-
- // Append alpha if not already provided for:
- if (count($ret_val) == 3)
- $ret_val[] = $alpha;
- return $ret_val;
- }
-
- /*
- * Sets the colors for the data, with optional default alpha value (for PHPlot_truecolor only)
- * Cases are:
- * SetDataColors(array(...)) : Use the supplied array as the color map.
- * SetDataColors(colorname) : Use an array of just colorname as the color map.
- * SetDataColors() or SetDataColors(NULL) : Load default color map if no color map is already set.
- * SetDataColors('') or SetDataColors(False) : Load default color map (even if one is already set).
- * $which_border is passed to SetDataBorderColors, for backward compatibility.
- * $alpha is a default Alpha to apply to all data colors that do not have alpha.
- * The default for this is NULL, not 0, so we can tell if it was defaulted. But the effective
- * default value is 0 (opaque).
- */
- function SetDataColors($which_data = NULL, $which_border = NULL, $alpha = NULL)
- {
- if (is_array($which_data)) {
- $colors = $which_data; // Use supplied array
- } elseif (!empty($which_data)) {
- $colors = array($which_data); // Use supplied single color
- } elseif (empty($this->data_colors) || !is_null($which_data)) {
- $colors = $this->default_colors; // Use default color array
- } else {
- // which_data is NULL or missing and a color array is already set.
- // The existing color array is left alone, except that if $alpha is
- // given this will replace the alpha value of each existing color.
- // This makes SetDataColors(NULL, NULL, $alpha) work.
- if (isset($alpha)) {
- $n_colors = count($this->data_colors);
- for ($i = 0; $i < $n_colors; $i++) {
- $this->data_colors[$i][3] = $alpha; // Component 3 = alpha value
- }
- }
- // No need to reparse the colors or anything else.
- return TRUE;
- }
-
- if (!isset($alpha))
- $alpha = 0; // Actual default is opaque colors.
-
- // Check each color and convert to array (r,g,b,a) form.
- // Use the $alpha argument as a default for the alpha value of each color.
- $this->data_colors = array();
- foreach ($colors as $color) {
- $color_array = $this->SetRGBColor($color, $alpha);
- if (!$color_array) return FALSE; // SetRGBColor already did an error message.
- $this->data_colors[] = $color_array;
- }
-
- // For past compatibility:
- return $this->SetDataBorderColors($which_border);
- }
-
- /*
- * Set the colors for the bars and stacked bars outlines.
- * Argument usage is similar to SetDataColors(), except the default is just black.
- */
- function SetDataBorderColors($which_br = NULL)
- {
- if (is_array($which_br)) {
- $colors = $which_br; // Use supplied array
- } elseif (!empty($which_br)) {
- $colors = array($which_br); // Use supplied single color
- } elseif (empty($this->data_border_colors) || !is_null($which_br)) {
- $colors = array('black'); // Use default
- } else {
- return TRUE; // Do nothing: which_br is NULL or missing and a color array is already set.
- }
-
- // Check each color and convert to array (r,g,b,a) form.
- $this->data_border_colors = array();
- foreach ($colors as $color) {
- $color_array = $this->SetRGBColor($color);
- if (!$color_array) return FALSE; // SetRGBColor already did an error message.
- $this->data_border_colors[] = $color_array;
- }
- return TRUE;
- }
-
- /*
- * Sets the colors for the data error bars.
- * Argument usage is the same as SetDataColors().
- */
- function SetErrorBarColors($which_err = NULL)
- {
- if (is_array($which_err)) {
- $colors = $which_err; // Use supplied array
- } elseif (!empty($which_err)) {
- $colors = array($which_err); // Use supplied single color
- } elseif (empty($this->error_bar_colors) || !is_null($which_err)) {
- $colors = $this->default_colors; // Use default color array
- } else {
- return TRUE; // Do nothing: which_err is NULL or missing and a color array is already set.
- }
-
- // Check each color and convert to array (r,g,b,a) form.
- $this->error_bar_colors = array();
- foreach ($colors as $color) {
- $color_array = $this->SetRGBColor($color);
- if (!$color_array) return FALSE; // SetRGBColor already did an error message.
- $this->error_bar_colors[] = $color_array;
- }
- return TRUE;
- }
-
- /*
- * Sets the default dashed line style.
- * $which_style : A string specifying the dashed line style, as alternating numbers
- * of the length (in pixels) of lines and spaces, separated by dashes.
- * For example: '2-3-1-2' means 2 dots of color, 3 transparent, 1 color, then 2 transparent.
- * This builds a string which will evaluate to an array of integers. Each colored dot
- * is '$which_ndxcol' and each transparent dot is 'IMG_COLOR_TRANSPARENT'. When SetDashedStyle()
- * eval's this with $which_ndxcol set, the result is a GD line style array.
- */
- function SetDefaultDashedStyle($which_style)
- {
- // Explode "numcol-numtrans-numcol-numtrans..." into segment counts:
- $asked = explode('-', $which_style);
-
- if (count($asked) < 2) {
- return $this->PrintError("SetDefaultDashedStyle(): Wrong parameter '$which_style'.");
- }
-
- // Build the string to be evaluated later by SetDashedStyle() with $which_ndxcolor set.
- $result = '';
- $vals = array('$which_ndxcol,', 'IMG_COLOR_TRANSPARENT,');
- $index = 0;
- foreach ($asked as $n) {
- $result .= str_repeat($vals[$index], $n);
- $index = 1 - $index;
- }
- $this->default_dashed_style = "array($result)";
-
- return TRUE;
- }
-
- /*
- * Sets the style before drawing a dashed line. Defaults to $this->default_dashed_style
- * $which_ndxcol : Color index to be used.
- */
- protected function SetDashedStyle($which_ndxcol)
- {
- // See SetDefaultDashedStyle() to understand this.
- eval ("\$style = $this->default_dashed_style;");
- return imagesetstyle($this->img, $style);
- }
-
- /*
- * Set line widths for each data set.
- * $which_lw : Array of line widths in pixels, or a single value to use for all data sets.
- */
- function SetLineWidths($which_lw=NULL)
- {
- if (is_array($which_lw)) {
- $this->line_widths = $which_lw; // Use provided array
- } elseif (!is_null($which_lw)) {
- $this->line_widths = array($which_lw); // Convert value to array
- }
- return TRUE;
- }
-
- /*
- * Set line style ('solid' or 'dashed') for each data set.
- * $which_ls : Array of keywords, or a single keyword to use for all data sets.
- */
- function SetLineStyles($which_ls=NULL)
- {
- if (is_array($which_ls)) {
- $this->line_styles = $which_ls; // Use provided array
- } elseif (!is_null($which_ls)) {
- $this->line_styles = ($which_ls) ? array($which_ls) : array('solid');
- }
- return TRUE;
- }
-
-/////////////////////////////////////////////
-////////////// TEXT and FONTS
-/////////////////////////////////////////////
-
- /*
- * Controls the line spacing of multi-line labels.
- * $which_spc : Line spacing factor for text
- * For GD text, this is the number of pixels between lines.
- * For TTF text, it controls line spacing in proportion to the normal
- * spacing defined by the font.
- */
- function SetLineSpacing($which_spc)
- {
- $this->line_spacing = $which_spc;
- return TRUE;
- }
-
- /*
- * Select the default font type to use.
- * $which_ttf : True to default to TrueType, False to default to GD (fixed) fonts.
- * This also resets all font settings to the defaults.
- */
- function SetUseTTF($which_ttf)
- {
- $this->use_ttf = $which_ttf;
- return $this->SetDefaultFonts();
- }
-
- /*
- * Sets the directory name to look into for TrueType fonts.
- */
- function SetTTFPath($which_path)
- {
- if (!is_dir($which_path) || !is_readable($which_path)) {
- return $this->PrintError("SetTTFPath(): $which_path is not a valid path.");
- }
- $this->ttf_path = $which_path;
- return TRUE;
- }
-
- /*
- * Sets the default TrueType font and updates all fonts to that.
- * The default font might be a full path, or relative to the TTFPath,
- * so let SetFont check that it exists.
- * Side effects: Enables use of TrueType fonts as the default font type,
- * and resets all font settings.
- */
- function SetDefaultTTFont($which_font)
- {
- $this->default_ttfont = $which_font;
- return $this->SetUseTTF(TRUE);
- }
-
- /*
- * Return the default TrueType font name. If no default has been set,
- * this tries some likely candidates for a font which can be loaded.
- * If it finds one that works, that becomes the default TT font.
- * If there is no default and it cannot find a working font, it falls
- * back to the original PHPlot default (which will not likely work either).
- */
- protected function GetDefaultTTFont()
- {
- if (!isset($this->default_ttfont)) {
- // No default font yet. Try some common sans-serif fonts.
- $fonts = array('LiberationSans-Regular.ttf', // For Linux with a correct GD font search path
- 'Verdana.ttf', 'Arial.ttf', 'Helvetica.ttf', // For Windows, maybe others
- 'ttf-liberation/LiberationSans-Regular.ttf', // For Debian, Ubuntu, and friends
- 'benjamingothic.ttf', // Original PHPlot default
- );
- foreach ($fonts as $font) {
- // First try the font name alone, to see if GD can find and load it.
- if (@imagettfbbox(10, 0, $font, "1") !== False)
- break;
- // If the font wasn't found, try it with the default TTF path in front.
- $font_with_path = $this->ttf_path . DIRECTORY_SEPARATOR . $font;
- if (@imagettfbbox(10, 0, $font_with_path, "1") !== False) {
- $font = $font_with_path;
- break;
- }
- }
- // We either have a working font, or are using the last one regardless.
- $this->default_ttfont = $font;
- }
- return $this->default_ttfont;
- }
-
- /*
- * Sets fonts to their defaults
- */
- protected function SetDefaultFonts()
- {
- // TTF:
- if ($this->use_ttf) {
- return $this->SetFont('generic', '', 8)
- && $this->SetFont('title', '', 14)
- && $this->SetFont('legend', '', 8)
- && $this->SetFont('x_label', '', 6)
- && $this->SetFont('y_label', '', 6)
- && $this->SetFont('x_title', '', 10)
- && $this->SetFont('y_title', '', 10);
- }
- // Fixed GD Fonts:
- return $this->SetFont('generic', 2)
- && $this->SetFont('title', 5)
- && $this->SetFont('legend', 2)
- && $this->SetFont('x_label', 1)
- && $this->SetFont('y_label', 1)
- && $this->SetFont('x_title', 3)
- && $this->SetFont('y_title', 3);
- }
-
- /*
- * Select a fixed (GD) font for an element.
- * This allows using a fixed font, even with SetUseTTF(True).
- * $which_elem : The element whose font is to be changed.
- * One of: title legend generic x_label y_label x_title y_title
- * $which_font : A GD font number 1-5
- * $which_spacing (optional) : Line spacing factor
- */
- function SetFontGD($which_elem, $which_font, $which_spacing = NULL)
- {
- if ($which_font < 1 || 5 < $which_font) {
- return $this->PrintError(__FUNCTION__ . ': Font size must be 1, 2, 3, 4 or 5');
- }
- if (!$this->CheckOption($which_elem,
- 'generic, title, legend, x_label, y_label, x_title, y_title',
- __FUNCTION__)) {
- return FALSE;
- }
-
- // Store the font parameters: name/size, char cell height and width.
- $this->fonts[$which_elem] = array('ttf' => FALSE,
- 'font' => $which_font,
- 'height' => ImageFontHeight($which_font),
- 'width' => ImageFontWidth($which_font),
- 'line_spacing' => $which_spacing);
- return TRUE;
- }
-
- /*
- * Select a TrueType font for an element.
- * This allows using a TrueType font, even with SetUseTTF(False).
- * $which_elem : The element whose font is to be changed.
- * One of: title legend generic x_label y_label x_title y_title
- * $which_font : A TrueType font filename or pathname.
- * $which_size : Font point size.
- * $which_spacing (optional) : Line spacing factor
- */
- function SetFontTTF($which_elem, $which_font, $which_size = 12, $which_spacing = NULL)
- {
- if (!$this->CheckOption($which_elem,
- 'generic, title, legend, x_label, y_label, x_title, y_title',
- __FUNCTION__)) {
- return FALSE;
- }
-
- // Empty font name means use the default font.
- if (empty($which_font))
- $which_font = $this->GetDefaultTTFont();
- $path = $which_font;
-
- // First try the font name directly, if not then try with path.
- // Use GD imagettfbbox() to determine if this is a valid font.
- // The return $bbox is used below, if valid.
- if (($bbox = @imagettfbbox($which_size, 0, $path, "E")) === False) {
- $path = $this->ttf_path . DIRECTORY_SEPARATOR . $which_font;
- if (($bbox = @imagettfbbox($which_size, 0, $path, "E")) === False) {
- return $this->PrintError(__FUNCTION__ . ": Can't find TrueType font $which_font");
- }
- }
-
- // Calculate the font height and inherent line spacing. TrueType fonts have this information
- // internally, but PHP/GD has no way to directly access it. So get the bounding box size of
- // an upper-case character without descenders, and the baseline-to-baseline height.
- // Note: In practice, $which_size = $height, maybe +/-1 . But which_size is in points,
- // and height is in pixels, and someday GD may be able to tell the difference.
- // The character width is saved too, but not used by the normal text drawing routines - it
- // isn't necessarily a fixed-space font. It is used in DrawLegend.
- $height = $bbox[1] - $bbox[5];
- $width = $bbox[2] - $bbox[0];
- $bbox = ImageTTFBBox($which_size, 0, $path, "E\nE");
- $spacing = $bbox[1] - $bbox[5] - 2 * $height;
-
- // Store the font parameters:
- $this->fonts[$which_elem] = array('ttf' => TRUE,
- 'font' => $path,
- 'size' => $which_size,
- 'height' => $height,
- 'width' => $width,
- 'spacing' => $spacing,
- 'line_spacing' => $which_spacing);
- return TRUE;
- }
-
- /*
- * Select Fixed/TrueType font for an element. Which type of font is
- * selected depends on the $use_ttf class variable (see SetUseTTF()).
- * Before PHPlot supported mixing font types, only this function and
- * SetUseTTF were available to select an overall font type, but now
- * SetFontGD() and SetFontTTF() can be used for mixing font types.
- * $which_elem : The element whose font is to be changed.
- * One of: title legend generic x_label y_label x_title y_title
- * $which_font : A number 1-5 for fixed fonts, or a TrueType font.
- * $which_size : Ignored for Fixed fonts, point size for TrueType.
- * $which_spacing (optional) : Line spacing factor
- */
- function SetFont($which_elem, $which_font, $which_size = 12, $line_spacing = NULL)
- {
- if ($this->use_ttf)
- return $this->SetFontTTF($which_elem, $which_font, $which_size, $line_spacing);
- return $this->SetFontGD($which_elem, $which_font, $line_spacing);
- }
-
- /*
- * Return the inter-line spacing for a font.
- * This is an internal function, used by ProcessText* and DrawLegend.
- * $font : A font array variable.
- * Returns: Spacing, in pixels, between text lines.
- */
- protected function GetLineSpacing($font)
- {
- // Use the per-font line spacing preference, if set, else the global value:
- if (isset($font['line_spacing']))
- $line_spacing = $font['line_spacing'];
- else
- $line_spacing = $this->line_spacing;
-
- // For GD fonts, that is the spacing in pixels.
- // For TTF, adjust based on the 'natural' font spacing (see SetFontTTF):
- if ($font['ttf']) {
- $line_spacing = (int)($line_spacing * $font['spacing'] / 6.0);
- }
- return $line_spacing;
- }
-
- /*
- * Text drawing and sizing functions:
- * ProcessText is meant for use only by DrawText and SizeText.
- * ProcessText(True, ...) - Draw a block of text
- * ProcessText(False, ...) - Just return ($width, $height) of
- * the orthogonal bounding box containing the text.
- * ProcessText is further split into separate functions for GD and TTF
- * text, due to the size of the code.
- *
- * Horizontal and vertical alignment are relative to the drawing. That is:
- * vertical text (90 deg) gets centered along Y position with
- * v_align = 'center', and adjusted to the right of X position with
- * h_align = 'right'. Another way to look at this is to say
- * that text rotation happens first, then alignment.
- *
- * Original multiple lines code submitted by Remi Ricard.
- * Original vertical code submitted by Marlin Viss.
- *
- * Text routines rewritten by ljb to fix alignment and position problems.
- * Here is my explanation and notes. More information and pictures will be
- * placed in the PHPlot Reference Manual.
- *
- * + Process TTF text one line at a time, not as a block. (See below)
- * + Flipped top vs bottom vertical alignment. The usual interpretation
- * is: bottom align means bottom of the text is at the specified Y
- * coordinate. For some reason, PHPlot did left/right the correct way,
- * but had top/bottom reversed. I fixed it, and left the default valign
- * argument as bottom, but the meaning of the default value changed.
- *
- * For GD font text, only single-line text is handled by GD, and the
- * basepoint is the upper left corner of each text line.
- * For TTF text, multi-line text could be handled by GD, with the text
- * basepoint at the lower left corner of the first line of text.
- * (Behavior of TTF drawing routines on multi-line text is not documented.)
- * But you cannot do left/center/right alignment on each line that way,
- * or proper line spacing.
- * Therefore, for either text type, we have to break up the text into
- * lines and position each line independently.
- *
- * There are 9 alignment modes: Horizontal = left, center, or right, and
- * Vertical = top, center, or bottom. Alignment is interpreted relative to
- * the image, not as the text is read. This makes sense when you consider
- * for example X axis labels. They need to be centered below the marks
- * (center, top alignment) regardless of the text angle.
- * 'Bottom' alignment really means baseline alignment.
- *
- * GD font text is supported (by libgd) at 0 degrees and 90 degrees only.
- * Multi-line or single line text works with any of the 9 alignment modes.
- *
- * TTF text can be at any angle. The 9 alignment modes work for all angles,
- * but the results might not be what you expect for multi-line text. See
- * the PHPlot Reference Manual for pictures and details. In short, alignment
- * applies to the orthogonal (aligned with X and Y axes) bounding box that
- * contains the text, and to each line in the multi-line text box. Since
- * alignment is relative to the image, 45 degree multi-line text aligns
- * differently from 46 degree text.
- *
- * Note that PHPlot allows multi-line text for the 3 titles, and they
- * are only drawn at 0 degrees (main and X titles) or 90 degrees (Y title).
- * Data labels can also be multi-line, and they can be drawn at any angle.
- * -ljb 2007-11-03
- *
- */
-
- /*
- * ProcessTextGD() - Draw or size GD fixed-font text.
- * This is intended for use only by ProcessText().
- * $draw_it : True to draw the text, False to just return the orthogonal width and height.
- * $font : PHPlot font array (with 'ttf' = False) - see SetFontGD()
- * $angle : Text angle in degrees. GD only supports 0 and 90. We treat >= 45 as 90, else 0.
- * $x, $y : Reference point for the text (ignored if !$draw_it)
- * $color : GD color index to use for drawing the text (ignored if !$draw_it)
- * $text : The text to draw or size. Put a newline between lines.
- * $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it)
- * $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it)
- * Returns: True, if drawing text, or an array of ($width, $height) if not.
- */
- protected function ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor)
- {
- // Extract font parameters:
- $font_number = $font['font'];
- $font_width = $font['width'];
- $font_height = $font['height'];
- $line_spacing = $this->GetLineSpacing($font);
-
- // Break up the text into lines, trim whitespace, find longest line.
- // Save the lines and length for drawing below.
- $longest = 0;
- foreach (explode("\n", $text) as $each_line) {
- $lines[] = $line = trim($each_line);
- $line_lens[] = $line_len = strlen($line);
- if ($line_len > $longest) $longest = $line_len;
- }
- $n_lines = count($lines);
-
- // Width, height are based on font size and longest line, line count respectively.
- // These are relative to the text angle.
- $total_width = $longest * $font_width;
- $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing;
-
- if (!$draw_it) {
- if ($angle < 45) return array($total_width, $total_height);
- return array($total_height, $total_width);
- }
-
- $interline_step = $font_height + $line_spacing; // Line-to-line step
-
- if ($angle >= 45) {
- // Vertical text (90 degrees):
- // (Remember the alignment convention with vertical text)
- // For 90 degree text, alignment factors change like this:
- $temp = $v_factor;
- $v_factor = $h_factor;
- $h_factor = 1 - $temp;
-
- $draw_func = 'ImageStringUp';
-
- // Rotation matrix "R" for 90 degrees (with Y pointing down):
- $r00 = 0; $r01 = 1;
- $r10 = -1; $r11 = 0;
-
- } else {
- // Horizontal text (0 degrees):
- $draw_func = 'ImageString';
-
- // Rotation matrix "R" for 0 degrees:
- $r00 = 1; $r01 = 0;
- $r10 = 0; $r11 = 1;
- }
-
- // Adjust for vertical alignment (horizontal text) or horizontal alignment (vertical text):
- $factor = (int)($total_height * $v_factor);
- $xpos = $x - $r01 * $factor;
- $ypos = $y - $r11 * $factor;
-
- // Debug callback provides the bounding box:
- if ($this->GetCallback('debug_textbox')) {
- if ($angle >= 45) {
- $bbox_width = $total_height;
- $bbox_height = $total_width;
- $px = $xpos;
- $py = $ypos - (1 - $h_factor) * $total_width;
- } else {
- $bbox_width = $total_width;
- $bbox_height = $total_height;
- $px = $xpos - $h_factor * $total_width;
- $py = $ypos;
- }
- $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height);
- }
-
- for ($i = 0; $i < $n_lines; $i++) {
-
- // Adjust for alignment of this line within the text block:
- $factor = (int)($line_lens[$i] * $font_width * $h_factor);
- $x = $xpos - $r00 * $factor;
- $y = $ypos - $r10 * $factor;
-
- // Call ImageString or ImageStringUp:
- $draw_func($this->img, $font_number, $x, $y, $lines[$i], $color);
-
- // Step to the next line of text. This is a rotation of (x=0, y=interline_spacing)
- $xpos += $r01 * $interline_step;
- $ypos += $r11 * $interline_step;
- }
- return TRUE;
- }
-
- /*
- * ProcessTextTTF() - Draw or size TTF text.
- * This is intended for use only by ProcessText().
- * $draw_it : True to draw the text, False to just return the orthogonal width and height.
- * $font : PHPlot font array (with 'ttf' = True) - see SetFontTTF()
- * $angle : Text angle in degrees.
- * $x, $y : Reference point for the text (ignored if !$draw_it)
- * $color : GD color index to use for drawing the text (ignored if !$draw_it)
- * $text : The text to draw or size. Put a newline between lines.
- * $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it)
- * $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it)
- * Returns: True, if drawing text, or an array of ($width, $height) if not.
- */
- protected function ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor)
- {
- // Extract font parameters (see SetFontTTF):
- $font_file = $font['font'];
- $font_size = $font['size'];
- $font_height = $font['height'];
- $line_spacing = $this->GetLineSpacing($font);
-
- // Break up the text into lines, trim whitespace.
- // Calculate the total width and height of the text box at 0 degrees.
- // Save the trimmed lines and their widths for later when drawing.
- // To get uniform spacing, don't use the actual line heights.
- // Total height = Font-specific line heights plus inter-line spacing.
- // Total width = width of widest line.
- // Last Line Descent is the offset from the bottom to the text baseline.
- // Note: For some reason, ImageTTFBBox uses (-1,-1) as the reference point.
- // So 1+bbox[1] is the baseline to bottom distance.
- $total_width = 0;
- $lastline_descent = 0;
- foreach (explode("\n", $text) as $each_line) {
- $lines[] = $line = trim($each_line);
- $bbox = ImageTTFBBox($font_size, 0, $font_file, $line);
- $line_widths[] = $width = $bbox[2] - $bbox[0];
- if ($width > $total_width) $total_width = $width;
- $lastline_descent = 1 + $bbox[1];
- }
- $n_lines = count($lines);
- $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing;
-
- // Calculate the rotation matrix for the text's angle. Remember that GD points Y down,
- // so the sin() terms change sign.
- $theta = deg2rad($angle);
- $cos_t = cos($theta);
- $sin_t = sin($theta);
- $r00 = $cos_t; $r01 = $sin_t;
- $r10 = -$sin_t; $r11 = $cos_t;
-
- // Make a bounding box of the right size, with upper left corner at (0,0).
- // By convention, the point order is: LL, LR, UR, UL.
- // Note this is still working with the text at 0 degrees.
- // When sizing text (SizeText), use the overall size with descenders.
- // This tells the caller how much room to leave for the text.
- // When drawing text (DrawText), use the size without descenders - that
- // is, down to the baseline. This is for accurate positioning.
- $b[0] = 0;
- if ($draw_it) {
- $b[1] = $total_height;
- } else {
- $b[1] = $total_height + $lastline_descent;
- }
- $b[2] = $total_width; $b[3] = $b[1];
- $b[4] = $total_width; $b[5] = 0;
- $b[6] = 0; $b[7] = 0;
-
- // Rotate the bounding box, then offset to the reference point:
- for ($i = 0; $i < 8; $i += 2) {
- $x_b = $b[$i];
- $y_b = $b[$i+1];
- $c[$i] = $x + $r00 * $x_b + $r01 * $y_b;
- $c[$i+1] = $y + $r10 * $x_b + $r11 * $y_b;
- }
-
- // Get an orthogonal (aligned with X and Y axes) bounding box around it, by
- // finding the min and max X and Y:
- $bbox_ref_x = $bbox_max_x = $c[0];
- $bbox_ref_y = $bbox_max_y = $c[1];
- for ($i = 2; $i < 8; $i += 2) {
- $x_b = $c[$i];
- if ($x_b < $bbox_ref_x) $bbox_ref_x = $x_b;
- elseif ($bbox_max_x < $x_b) $bbox_max_x = $x_b;
- $y_b = $c[$i+1];
- if ($y_b < $bbox_ref_y) $bbox_ref_y = $y_b;
- elseif ($bbox_max_y < $y_b) $bbox_max_y = $y_b;
- }
- $bbox_width = $bbox_max_x - $bbox_ref_x;
- $bbox_height = $bbox_max_y - $bbox_ref_y;
-
- if (!$draw_it) {
- // Return the bounding box, rounded up (so it always contains the text):
- return array((int)ceil($bbox_width), (int)ceil($bbox_height));
- }
-
- $interline_step = $font_height + $line_spacing; // Line-to-line step
-
- // Calculate the offsets from the supplied reference point to the
- // upper-left corner of the text.
- // Start at the reference point at the upper left corner of the bounding
- // box (bbox_ref_x, bbox_ref_y) then adjust it for the 9 point alignment.
- // h,v_factor are 0,0 for top,left, .5,.5 for center,center, 1,1 for bottom,right.
- // $off_x = $bbox_ref_x + $bbox_width * $h_factor - $x;
- // $off_y = $bbox_ref_y + $bbox_height * $v_factor - $y;
- // Then use that offset to calculate back to the supplied reference point x, y
- // to get the text base point.
- // $qx = $x - $off_x;
- // $qy = $y - $off_y;
- // Reduces to:
- $qx = 2 * $x - $bbox_ref_x - $bbox_width * $h_factor;
- $qy = 2 * $y - $bbox_ref_y - $bbox_height * $v_factor;
-
- // Check for debug callback. Don't calculate bounding box unless it is wanted.
- if ($this->GetCallback('debug_textbox')) {
- // Calculate the orthogonal bounding box coordinates for debug testing.
-
- // qx, qy is upper left corner relative to the text.
- // Calculate px,py: upper left corner (absolute) of the bounding box.
- // There are 4 equation sets for this, depending on the quadrant:
- if ($sin_t > 0) {
- if ($cos_t > 0) {
- // Quadrant: 0d - 90d:
- $px = $qx; $py = $qy - $total_width * $sin_t;
- } else {
- // Quadrant: 90d - 180d:
- $px = $qx + $total_width * $cos_t; $py = $qy - $bbox_height;
- }
- } else {
- if ($cos_t < 0) {
- // Quadrant: 180d - 270d:
- $px = $qx - $bbox_width; $py = $qy + $total_height * $cos_t;
- } else {
- // Quadrant: 270d - 360d:
- $px = $qx + $total_height * $sin_t; $py = $qy;
- }
- }
- $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height);
- }
-
- // Since alignment is applied after rotation, which parameter is used
- // to control alignment of each line within the text box varies with
- // the angle.
- // Angle (degrees): Line alignment controlled by:
- // -45 < angle <= 45 h_align
- // 45 < angle <= 135 reversed v_align
- // 135 < angle <= 225 reversed h_align
- // 225 < angle <= 315 v_align
- if ($cos_t >= $sin_t) {
- if ($cos_t >= -$sin_t) $line_align_factor = $h_factor;
- else $line_align_factor = $v_factor;
- } else {
- if ($cos_t >= -$sin_t) $line_align_factor = 1-$v_factor;
- else $line_align_factor = 1-$h_factor;
- }
-
- // Now we have the start point, spacing and in-line alignment factor.
- // We are finally ready to start drawing the text, line by line.
- for ($i = 0; $i < $n_lines; $i++) {
-
- // For drawing TTF text, the reference point is the left edge of the
- // text baseline (not the lower left corner of the bounding box).
- // The following also adjusts for horizontal (relative to
- // the text) alignment of the current line within the box.
- // What is happening is rotation of this vector by the text angle:
- // (x = (total_width - line_width) * factor, y = font_height)
-
- $width_factor = ($total_width - $line_widths[$i]) * $line_align_factor;
- $rx = $qx + $r00 * $width_factor + $r01 * $font_height;
- $ry = $qy + $r10 * $width_factor + $r11 * $font_height;
-
- // Finally, draw the text:
- ImageTTFText($this->img, $font_size, $angle, $rx, $ry, $color, $font_file, $lines[$i]);
-
- // Step to position of next line.
- // This is a rotation of (x=0,y=height+line_spacing) by $angle:
- $qx += $r01 * $interline_step;
- $qy += $r11 * $interline_step;
- }
- return TRUE;
- }
-
- /*
- * ProcessText() - Wrapper for ProcessTextTTF() and ProcessTextGD(). See notes above.
- * This is intended for use from within PHPlot only, and only by DrawText() and SizeText().
- * $draw_it : True to draw the text, False to just return the orthogonal width and height.
- * $font : PHPlot font array, or NULL or empty string to use 'generic'
- * $angle : Text angle in degrees
- * $x, $y : Reference point for the text (ignored if !$draw_it)
- * $color : GD color index to use for drawing the text (ignored if !$draw_it)
- * $text : The text to draw or size. Put a newline between lines.
- * $halign : Horizontal alignment: left, center, or right (ignored if !$draw_it)
- * $valign : Vertical alignment: top, center, or bottom (ignored if !$draw_it)
- * Note: Alignment is relative to the image, not the text.
- * Returns: True, if drawing text, or an array of ($width, $height) if not.
- */
- protected function ProcessText($draw_it, $font, $angle, $x, $y, $color, $text, $halign, $valign)
- {
- // Empty text case:
- if ($text === '') {
- if ($draw_it) return TRUE;
- return array(0, 0);
- }
-
- // Calculate width and height offset factors using the alignment args:
- if ($valign == 'top') $v_factor = 0;
- elseif ($valign == 'center') $v_factor = 0.5;
- else $v_factor = 1.0; // 'bottom'
- if ($halign == 'left') $h_factor = 0;
- elseif ($halign == 'center') $h_factor = 0.5;
- else $h_factor = 1.0; // 'right'
-
- // Apply a default font. This is mostly for external (callback) users.
- if (empty($font)) $font = $this->fonts['generic'];
-
- if ($font['ttf']) {
- return $this->ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text,
- $h_factor, $v_factor);
- }
- return $this->ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor);
- }
-
- /*
- * Draws a block of text. See comments above before ProcessText().
- * $which_font : PHPlot font array, or NULL or empty string to use 'generic'
- * $which_angle : Text angle in degrees
- * $which_xpos, $which_ypos: Reference point for the text
- * $which_color : GD color index to use for drawing the text
- * $which_text : The text to draw, with newlines (\n) between lines.
- * $which_halign : Horizontal (relative to the image) alignment: left, center, or right.
- * $which_valign : Vertical (relative to the image) alignment: top, center, or bottom.
- * Note: This function should be considered 'protected', and is not documented for public use.
- */
- function DrawText($which_font, $which_angle, $which_xpos, $which_ypos, $which_color, $which_text,
- $which_halign = 'left', $which_valign = 'bottom')
- {
- return $this->ProcessText(TRUE,
- $which_font, $which_angle, $which_xpos, $which_ypos,
- $which_color, $which_text, $which_halign, $which_valign);
- }
-
- /*
- * Returns the size of block of text. This is the orthogonal width and height of a bounding
- * box aligned with the X and Y axes of the text. Only for angle=0 is this the actual
- * width and height of the text block, but for any angle it is the amount of space needed
- * to contain the text.
- * $which_font : PHPlot font array, or NULL or empty string to use 'generic'
- * $which_angle : Text angle in degrees
- * $which_text : The text to draw, with newlines (\n) between lines.
- * Returns a two element array with: $width, $height.
- * This is just a wrapper for ProcessText() - see above.
- * Note: This function should be considered 'protected', and is not documented for public use.
- */
- function SizeText($which_font, $which_angle, $which_text)
- {
- // Color, position, and alignment are not used when calculating the size.
- return $this->ProcessText(FALSE,
- $which_font, $which_angle, 0, 0, 1, $which_text, '', '');
- }
-
-/////////////////////////////////////////////
-/////////// INPUT / OUTPUT CONTROL
-/////////////////////////////////////////////
-
- /*
- * Sets output file format to $format (jpg, png, ...)
- */
- function SetFileFormat($format)
- {
- $asked = $this->CheckOption($format, 'jpg, png, gif, wbmp', __FUNCTION__);
- if (!$asked) return FALSE;
- switch ($asked) {
- case 'jpg':
- $format_test = IMG_JPG;
- break;
- case 'png':
- $format_test = IMG_PNG;
- break;
- case 'gif':
- $format_test = IMG_GIF;
- break;
- case 'wbmp':
- $format_test = IMG_WBMP;
- break;
- }
- if (!(imagetypes() & $format_test)) {
- return $this->PrintError("SetFileFormat(): File format '$format' not supported");
- }
- $this->file_format = $asked;
- return TRUE;
- }
-
- /*
- * Selects an input file to be used as graph background and scales or tiles this image
- * to fit the sizes.
- * $input_file : Path to the file to be used (jpeg, png and gif accepted)
- * $mode : 'centeredtile', 'tile', or 'scale' (the image to the graph's size)
- */
- function SetBgImage($input_file, $mode='centeredtile')
- {
- $this->bgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
- $this->bgimg = $input_file;
- return (boolean)$this->bgmode;
- }
-
- /*
- * Selects an input file to be used as plot area background and scales or tiles this image
- * to fit the sizes.
- * $input_file : Path to the file to be used (jpeg, png and gif accepted)
- * $mode : 'centeredtile', 'tile', or 'scale' (the image to the graph's size)
- */
- function SetPlotAreaBgImage($input_file, $mode='tile')
- {
- $this->plotbgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
- $this->plotbgimg = $input_file;
- return (boolean)$this->plotbgmode;
- }
-
- /*
- * Sets the name of the file to be used as output file.
- */
- function SetOutputFile($which_output_file)
- {
- $this->output_file = $which_output_file;
- return TRUE;
- }
-
- /*
- * Sets the output image as 'inline', that is: no Content-Type headers are sent
- * to the browser. Needed if you want to embed the images.
- */
- function SetIsInline($which_ii)
- {
- $this->is_inline = (bool)$which_ii;
- return TRUE;
- }
-
- /*
- * Performs the actual outputting of the generated graph.
- */
- function PrintImage()
- {
- // Browser cache stuff submitted by Thiemo Nagel
- if ( (! $this->browser_cache) && (! $this->is_inline)) {
- header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT');
- header('Cache-Control: no-cache, must-revalidate');
- header('Pragma: no-cache');
- }
-
- switch ($this->file_format) {
- case 'png':
- $mime_type = 'image/png';
- $output_f = 'imagepng';
- break;
- case 'jpg':
- $mime_type = 'image/jpeg';
- $output_f = 'imagejpeg';
- break;
- case 'gif':
- $mime_type = 'image/gif';
- $output_f = 'imagegif';
- break;
- case 'wbmp':
- $mime_type = 'image/wbmp';
- $output_f = 'imagewbmp';
- break;
- default:
- return $this->PrintError('PrintImage(): Please select an image type!');
- }
- if (!$this->is_inline) {
- Header("Content-type: $mime_type");
- }
- if ($this->is_inline && $this->output_file != '') {
- $output_f($this->img, $this->output_file);
- } else {
- $output_f($this->img);
- }
- return TRUE;
- }
-
- /*
- * Error handling for 'fatal' errors:
- * $error_message Text of the error message
- * Standard output from PHPlot is expected to be an image file, such as
- * when handling an <img> tag browser request. So it is not permitted to
- * output text to standard output. (You should have display_errors=off)
- * Here is how PHPlot handles fatal errors:
- * + Write the error message into an image, and output the image.
- * + If no image can be output, write nothing and produce an HTTP
- * error header.
- * + Trigger a user-level error containing the error message.
- * If no error handler was set up, the script will log the
- * error and exit with non-zero status.
- *
- * PrintError() and DrawError() are now equivalent. Both are provided for
- * compatibility. (In earlier releases, PrintError sent the message to
- * stdout only, and DrawError sent it in an image only.)
- *
- * This function does not return, unless the calling script has set up
- * an error handler which does not exit. In that case, PrintError will
- * return False. But not all of PHPlot will handle this correctly, so
- * it is probably a bad idea for an error handler to return.
- */
- protected function PrintError($error_message)
- {
- // Be sure not to loop recursively, e.g. PrintError - PrintImage - PrintError.
- if (isset($this->in_error)) return FALSE;
- $this->in_error = TRUE;
-
- // Output an image containing the error message:
- if (!empty($this->img)) {
- $ypos = $this->image_height/2;
- $xpos = $this->image_width/2;
- $bgcolor = ImageColorResolve($this->img, 255, 255, 255);
- $fgcolor = ImageColorResolve($this->img, 0, 0, 0);
- ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height, $bgcolor);
-
- // Switch to built-in fonts, in case of error with TrueType fonts:
- $this->SetUseTTF(FALSE);
-
- $this->DrawText($this->fonts['generic'], 0, $xpos, $ypos, $fgcolor,
- wordwrap($error_message), 'center', 'center');
-
- $this->PrintImage();
- } elseif (! $this->is_inline) {
- Header('HTTP/1.0 500 Internal Server Error');
- }
- trigger_error($error_message, E_USER_ERROR);
- unset($this->in_error);
- return FALSE; // In case error handler returns, rather than doing exit().
- }
-
- /*
- * Display an error message and exit.
- * This is provided for backward compatibility only. Use PrintError() instead.
- * $error_message Text of the error message
- * $where_x, $where_y Ignored, provided for compatibility.
- */
- protected function DrawError($error_message, $where_x = NULL, $where_y = NULL)
- {
- return $this->PrintError($error_message);
- }
-
-/////////////////////////////////////////////
-/////////// LABELS
-/////////////////////////////////////////////
-
- /*
- * Sets position for X data labels.
- * For vertical plots, these are X axis data labels, showing label strings from the data array.
- * Accepted positions are: plotdown, plotup, both, none.
- * For horizontal plots (bar, stackedbar only), these are X data value labels, show the data values.
- * Accepted positions are: plotin, plotstack, none.
- */
- function SetXDataLabelPos($which_xdlp)
- {
- $which_xdlp = $this->CheckOption($which_xdlp, 'plotdown, plotup, both, none, plotin, plotstack',
- __FUNCTION__);
- if (!$which_xdlp) return FALSE;
- $this->x_data_label_pos = $which_xdlp;
-
- return TRUE;
- }
-
- /*
- * Sets position for Y data labels.
- * For vertical plots (where available), these are Y data value labels, showing the data values.
- * Accepted positions are: plotin, plotstack, none.
- * For horizontal plots, these are Y axis data labels, showing label strings from the data array.
- * Accepted positions are: plotleft, plotright, both, none.
- */
- function SetYDataLabelPos($which_ydlp)
- {
- $which_ydlp = $this->CheckOption($which_ydlp, 'plotleft, plotright, both, none, plotin, plotstack',
- __FUNCTION__);
- if (!$which_ydlp) return FALSE;
- $this->y_data_label_pos = $which_ydlp;
-
- return TRUE;
- }
-
- /*
- * Set position for X tick labels.
- */
- function SetXTickLabelPos($which_xtlp)
- {
- $which_xtlp = $this->CheckOption($which_xtlp, 'plotdown, plotup, both, xaxis, none',
- __FUNCTION__);
- if (!$which_xtlp) return FALSE;
- $this->x_tick_label_pos = $which_xtlp;
-
- return TRUE;
- }
-
- /*
- * Set position for Y tick labels.
- */
- function SetYTickLabelPos($which_ytlp)
- {
- $which_ytlp = $this->CheckOption($which_ytlp, 'plotleft, plotright, both, yaxis, none',
- __FUNCTION__);
- if (!$which_ytlp) return FALSE;
- $this->y_tick_label_pos = $which_ytlp;
-
- return TRUE;
- }
-
- /*
- * Set formatting type for tick and data labels on X or Y axis.
- * This implements the 4 functions Set[XY]LabelType() and Set[XY]DataLabelType().
- * $mode : 'x', 'y', 'xd', or 'yd' - which type of label to configure.
- * 'x' and 'y' set the type for tick labels, and the default type for data labels
- * if they are not separately configured. 'xd' and 'yd' set the type for data labels.
- * $args : Variable arguments, passed as an array.
- * [0] = $type (required) : Label type. 'data', 'time', 'printf', or 'custom'.
- * For type 'data':
- * [1] = $precision (optional). Numeric precision. Can also be set by SetPrecision[XY]().
- * [2] = $prefix (optional) - prefix string for labels.
- * [3] = $suffix (optional) - suffix string for labels. This replaces data_units_text.
- * For type 'time':
- * [1] = $format for strftime (optional). Can also be set by Set[XY]TimeFormat().
- * For type 'printf':
- * [1] = $format (optional) for sprintf.
- * For type 'custom':
- * [1] = $callback (required) - Custom function or array of (instance,method) to call.
- * [2] = $argument (optional) - Pass-through argument for the formatting function.
- */
- protected function SetLabelType($mode, $args)
- {
- if (!$this->CheckOption($mode, 'x, y, xd, yd', __FUNCTION__))
- return FALSE;
-
- $type = isset($args[0]) ? $args[0] : '';
- $format =& $this->label_format[$mode]; // Shorthand reference to format storage variables
- switch ($type) {
- case 'data':
- if (isset($args[1]))
- $format['precision'] = $args[1];
- elseif (!isset($format['precision']))
- $format['precision'] = 1;
- $format['prefix'] = isset($args[2]) ? $args[2] : '';
- $format['suffix'] = isset($args[3]) ? $args[3] : '';
- break;
-
- case 'time':
- if (isset($args[1]))
- $format['time_format'] = $args[1];
- elseif (!isset($format['time_format']))
- $format['time_format'] = '%H:%M:%S';
- break;
-
- case 'printf':
- if (isset($args[1]))
- $format['printf_format'] = $args[1];
- elseif (!isset($format['printf_format']))
- $format['printf_format'] = '%e';
- break;
-
- case 'custom':
- if (isset($args[1])) {
- $format['custom_callback'] = $args[1];
- $format['custom_arg'] = isset($args[2]) ? $args[2] : NULL;
- } else {
- $type = ''; // Error, 'custom' without a function, set to no-format mode.
- }
- break;
-
- case '':
- case 'title': // Retained for backwards compatibility?
- break;
-
- default:
- $this->CheckOption($type, 'data, time, printf, custom', __FUNCTION__);
- $type = '';
- }
- $format['type'] = $type;
- return (boolean)$type;
- }
-
- /*
- * Select label formating for X tick labels, and for X data labels
- * (unless SetXDataLabelType was called).
- * See SetLabelType() for details.
- */
- function SetXLabelType() // Variable arguments: $type, ...
- {
- $args = func_get_args();
- return $this->SetLabelType('x', $args);
- }
-
- /*
- * Select label formatting for X data labels, overriding SetXLabelType.
- */
- function SetXDataLabelType() // Variable arguments: $type, ...
- {
- $args = func_get_args();
- return $this->SetLabelType('xd', $args);
- }
-
- /*
- * Select label formating for Y tick labels, and for Y data labels
- * (unless SetYDataLabelType was called).
- * See SetLabelType() for details.
- */
- function SetYLabelType() // Variable arguments: $type, ...
- {
- $args = func_get_args();
- return $this->SetLabelType('y', $args);
- }
-
- /*
- * Select label formatting for Y data labels, overriding SetYLabelType.
- */
- function SetYDataLabelType() // Variable arguments: $type, ...
- {
- $args = func_get_args();
- return $this->SetLabelType('yd', $args);
- }
-
- /*
- * Set the date/time format code for X labels.
- * Note: Use of SetXLabelType('time', $which_xtf) is preferred, because
- * SetXTimeFormat does not also enable date/time formatting.
- */
- function SetXTimeFormat($which_xtf)
- {
- $this->label_format['x']['time_format'] = $which_xtf;
- return TRUE;
- }
-
- /*
- * Set the date/time format code for Y labels.
- * Note: Use of SetYLabelType('time', $which_ytf) is preferred, because
- * SetYTimeFormat does not also enable date/time formatting.
- */
- function SetYTimeFormat($which_ytf)
- {
- $this->label_format['y']['time_format'] = $which_ytf;
- return TRUE;
- }
-
- /*
- * Set number format parameters (decimal point and thousands separator) for
- * 'data' mode label formatting, overriding the locale-defaults.
- */
- function SetNumberFormat($decimal_point, $thousands_sep)
- {
- $this->decimal_point = $decimal_point;
- $this->thousands_sep = $thousands_sep;
- return TRUE;
- }
-
- /*
- * Set the text angle for X labels to $which_xla degrees.
- */
- function SetXLabelAngle($which_xla)
- {
- $this->x_label_angle = $which_xla;
- return TRUE;
- }
-
- /*
- * Set the text angle for Y labels to $which_xla degrees.
- */
- function SetYLabelAngle($which_yla)
- {
- $this->y_label_angle = $which_yla;
- return TRUE;
- }
-
- /*
- * Set the angle for X Data Labels to $which_xdla degrees.
- * If not used, this defaults to the value set with SetXLabelAngle.
- */
- function SetXDataLabelAngle($which_xdla)
- {
- $this->x_data_label_angle = $which_xdla;
- return TRUE;
- }
-
- /*
- * Set the angle for Y Data Labels to $which_ydla degrees.
- * If not used, this defaults to zero (unlike X data labels).
- */
- function SetYDataLabelAngle($which_ydla)
- {
- $this->y_data_label_angle = $which_ydla;
- return TRUE;
- }
-
-/////////////////////////////////////////////
-/////////// MISC
-/////////////////////////////////////////////
-
- /*
- * Checks the validity of an option.
- * $which_opt String to check, such as the provided value of a function argument.
- * $which_acc String of accepted choices. Must be lower-case, and separated
- * by exactly ', ' (comma, space).
- * $which_func Name of the calling function, for error messages.
- * Returns the supplied option value, downcased and trimmed, if it is valid.
- * Reports an error if the supplied option is not valid.
- */
- protected function CheckOption($which_opt, $which_acc, $which_func)
- {
- $asked = strtolower(trim($which_opt));
-
- // Look for the supplied value in a comma/space separated list.
- if (strpos(", $which_acc,", ", $asked,") !== FALSE)
- return $asked;
-
- $this->PrintError("$which_func(): '$which_opt' not in available choices: '$which_acc'.");
- return NULL;
- }
-
- /*
- * Checks the validity of an array of options.
- * $opt Array or string to check.
- * $acc String of accepted choices. Must be lower-case, and separated
- * by exactly ', ' (comma, space).
- * $func Name of the calling function, for error messages.
- * Returns a array option value(s), downcased and trimmed, if all entries in $opt are valid.
- * Reports an error if any supplied option is not valid. Returns NULL if the error handler returns.
- */
- protected function CheckOptionArray($opt, $acc, $func)
- {
- $opt_array = (array)$opt;
- $result = array();
- foreach ($opt_array as $option) {
- $choice = $this->CheckOption($option, $acc, $func);
- if (is_null($choice)) return NULL; // In case CheckOption error handler returns
- $result[] = $choice;
- }
- return $result;
- }
-
- /*
- * Check compatibility of a plot type and data type.
- * This is called by the plot-type-specific drawing functions.
- * $valid_types String of supported data types. Multiple values must be
- * separated by exactly ', ' (comma, space).
- * Returns True if the type is valid for this plot.
- * Reports an error if the data type is not value. If the error is handled and
- * the handler returns, this returns False.
- */
- protected function CheckDataType($valid_types)
- {
- if (strpos(", $valid_types,", ", $this->data_type,") !== FALSE)
- return TRUE;
-
- $this->PrintError("Data type '$this->data_type' is not valid for '$this->plot_type' plots."
- . " Supported data type(s): '$valid_types'");
- return FALSE;
- }
-
- /*
- * Decode the data type into variables used to determine how to process a data array.
- * The goal is minimize which functions understand the actual data type values.
- * This sets the datatype_* variables for use by other member functions.
- * datatype_implied : Implicit independent variable (e.g. text-data vs data-data)
- * datatype_swapped_xy : Swapped X/Y (horizontal plot)
- * datatype_error_bars : Data array has error bar data
- * datatype_pie_single : Data array is for a pie chart with one row per slice
- */
- protected function DecodeDataType()
- {
- $dt = $this->data_type;
-
- $this->datatype_implied = ($dt == 'text-data' || $dt == 'text-data-single'
- || $dt == 'text-data-yx');
- $this->datatype_swapped_xy = ($dt == 'text-data-yx' || $dt == 'data-data-yx');
- $this->datatype_error_bars = ($dt == 'data-data-error');
- $this->datatype_pie_single = ($dt == 'text-data-single');
- }
-
- /*
- * Make sure the data array is populated, and calculate the number of columns.
- * This is called from DrawGraph. Calculates data_columns, which is the
- * maximum number of dependent variable values (usually Y) in the data array rows.
- * (For pie charts, this is the number of slices.)
- * This depends on the data_type, unlike records_per_group (which was
- * previously used to pad style arrays, but is not accurate).
- * Returns True if the data array is OK, else reports an error (and may return False).
- * Note error messages refer to the caller, the public DrawGraph().
- */
- protected function CheckDataArray()
- {
- // Test for missing image, which really should never happen.
- if (!$this->img) {
- return $this->PrintError('DrawGraph(): No image resource allocated');
- }
-
- // Test for missing or empty data array:
- if (empty($this->data) || !is_array($this->data)) {
- return $this->PrintError("DrawGraph(): No data array");
- }
- if ($this->total_records == 0) {
- return $this->PrintError('DrawGraph(): Empty data set');
- }
-
- // Decode the data type into functional flags.
- $this->DecodeDataType();
-
- // Calculate the maximum number of dependent values per independent value
- // (e.g. Y for each X), or the number of pie slices.
- if ($this->datatype_pie_single) {
- $this->data_columns = $this->num_data_rows; // Special case for 1 type of pie chart.
- } else {
- $skip = $this->datatype_implied ? 1 : 2; // Skip data label and independent variable if used
- $this->data_columns = $this->records_per_group - $skip;
- if ($this->datatype_error_bars) // Each Y has +err and -err along with it
- $this->data_columns = (int)($this->data_columns / 3);
- }
- return TRUE;
- }
-
- /*
- * Control headers for browser-side image caching.
- * $which_browser_cache : True to allow browsers to cache the image.
- */
- function SetBrowserCache($which_browser_cache)
- {
- $this->browser_cache = $which_browser_cache;
- return TRUE;
- }
-
- /*
- * Set whether DrawGraph automatically outputs the image too.
- * $which_pi : True to have DrawGraph call PrintImage at the end.
- */
- function SetPrintImage($which_pi)
- {
- $this->print_image = $which_pi;
- return TRUE;
- }
-
- /*
- * Set text to display in the graph's legend.
- * $which_leg : Array of strings for the complete legend, or a single string
- * to be appended to the legend.
- * Or NULL (or an empty array) to cancel the legend.
- */
- function SetLegend($which_leg)
- {
- if (is_array($which_leg)) { // use array (or cancel, if empty array)
- $this->legend = $which_leg;
- } elseif (!is_null($which_leg)) { // append string
- $this->legend[] = $which_leg;
- } else {
- $this->legend = ''; // Reinitialize to empty, meaning no legend.
- }
- return TRUE;
- }
-
- /*
- * Specifies the position of the legend's upper/leftmost corner,
- * in pixel (device) coordinates.
- * Both X and Y must be provided, or both omitted (or use NULL) to restore auto-positioning.
- */
- function SetLegendPixels($which_x=NULL, $which_y=NULL)
- {
- $this->legend_x_pos = $which_x;
- $this->legend_y_pos = $which_y;
- // Make sure this is unset, meaning we have pixel coords:
- unset($this->legend_xy_world);
-
- return TRUE;
- }
-
- /*
- * Specifies the position of the legend's upper/leftmost corner,
- * in world (data space) coordinates.
- */
- function SetLegendWorld($which_x, $which_y)
- {
- // Since conversion from world to pixel coordinates is not yet available, just
- // remember the coordinates and set a flag to indicate conversion is needed.
- $this->legend_x_pos = $which_x;
- $this->legend_y_pos = $which_y;
- $this->legend_xy_world = TRUE;
-
- return TRUE;
- }
-
- /*
- * Set legend text alignment, color box alignment, and style options.
- * $text_align : Alignment of the text, 'left' or 'right'.
- * $colorbox_align : Alignment of the color boxes, 'left', 'right', 'none', or missing/empty.
- * If missing or empty, the same alignment as $text_align is used. Color box is positioned first.
- * $style : reserved for future use.
- */
- function SetLegendStyle($text_align, $colorbox_align = '', $style = '')
- {
- $this->legend_text_align = $this->CheckOption($text_align, 'left, right', __FUNCTION__);
- if (empty($colorbox_align))
- $this->legend_colorbox_align = $this->legend_text_align;
- else
- $this->legend_colorbox_align = $this->CheckOption($colorbox_align, 'left, right, none',
- __FUNCTION__);
- return ((boolean)$this->legend_text_align && (boolean)$this->legend_colorbox_align);
- }
-
- /*
- * Set border for the plot area.
- * Accepted values are: left, right, top, bottom, sides, none, full or an array of those.
- */
- function SetPlotBorderType($pbt)
- {
- $this->plot_border_type = $this->CheckOptionArray($pbt, 'left, right, top, bottom, sides, none, full',
- __FUNCTION__);
- return !empty($this->plot_border_type);
- }
-
- /*
- * Set border style for the image.
- * Accepted values are: raised, plain, solid, none
- * 'solid' is the same as 'plain' except it fixes the color (see DrawImageBorder)
- */
- function SetImageBorderType($sibt)
- {
- $this->image_border_type = $this->CheckOption($sibt, 'raised, plain, solid, none', __FUNCTION__);
- return (boolean)$this->image_border_type;
- }
-
- /*
- * Set border width for the image to $width in pixels.
- */
- function SetImageBorderWidth($width)
- {
- $this->image_border_width = $width;
- return TRUE;
- }
-
- /*
- * Enable or disable drawing of the plot area background color.
- */
- function SetDrawPlotAreaBackground($dpab)
- {
- $this->draw_plot_area_background = (bool)$dpab;
- return TRUE;
- }
-
- /*
- * Enable or disable drawing of the X grid lines.
- */
- function SetDrawXGrid($dxg)
- {
- $this->draw_x_grid = (bool)$dxg;
- return TRUE;
- }
-
- /*
- * Enable or disable drawing of the Y grid lines.
- */
- function SetDrawYGrid($dyg)
- {
- $this->draw_y_grid = (bool)$dyg;
- return TRUE;
- }
-
- /*
- * Select dashed or solid grid lines.
- * $ddg : True for dashed grid lines, false for solid grid lines.
- */
- function SetDrawDashedGrid($ddg)
- {
- $this->dashed_grid = (bool)$ddg;
- return TRUE;
- }
-
- /*
- * Enable or disable drawing of X Data Label Lines.
- */
- function SetDrawXDataLabelLines($dxdl)
- {
- $this->draw_x_data_label_lines = (bool)$dxdl;
- return TRUE;
- }
-
- /*
- * Set the main title text for the plot.
- */
- function SetTitle($which_title)
- {
- $this->title_txt = $which_title;
- return TRUE;
- }
-
- /*
- * Set the X axis title and position.
- */
- function SetXTitle($which_xtitle, $which_xpos = 'plotdown')
- {
- if ($which_xtitle == '')
- $which_xpos = 'none';
-
- $this->x_title_pos = $this->CheckOption($which_xpos, 'plotdown, plotup, both, none', __FUNCTION__);
- if (!$this->x_title_pos) return FALSE;
- $this->x_title_txt = $which_xtitle;
- return TRUE;
- }
-
- /*
- * Set the Y axis title and position.
- */
- function SetYTitle($which_ytitle, $which_ypos = 'plotleft')
- {
- if ($which_ytitle == '')
- $which_ypos = 'none';
-
- $this->y_title_pos = $this->CheckOption($which_ypos, 'plotleft, plotright, both, none', __FUNCTION__);
- if (!$this->y_title_pos) return FALSE;
- $this->y_title_txt = $which_ytitle;
- return TRUE;
- }
-
- /*
- * Set the size of the drop shadow for bar and pie charts.
- * $which_s : Size of the drop shadow in pixels.
- */
- function SetShading($which_s)
- {
- $this->shading = (int)$which_s;
- return TRUE;
- }
-
- /*
- * Set the plot type (bars, points, ...)
- */
- function SetPlotType($which_pt)
- {
- $avail_plot_types = implode(', ', array_keys(PHPlot::$plots)); // List of known plot types
- $this->plot_type = $this->CheckOption($which_pt, $avail_plot_types, __FUNCTION__);
- return (boolean)$this->plot_type;
- }
-
- /*
- * Set the position of the X axis.
- * $pos : Axis position in world coordinates (as an integer).
- */
- function SetXAxisPosition($pos='')
- {
- $this->x_axis_position = ($pos === '') ? $pos : (int)$pos;
- return TRUE;
- }
-
- /*
- * Set the position of the Y axis.
- * $pos : Axis position in world coordinates (as an integer).
- */
- function SetYAxisPosition($pos='')
- {
- $this->y_axis_position = ($pos === '') ? $pos : (int)$pos;
- return TRUE;
- }
-
- /*
- * Enable or disable drawing of the X axis line.
- * $draw : True to draw the axis (default if not called), False to suppress it.
- * This controls drawing of the axis line only, and not the ticks, labels, or grid.
- */
- function SetDrawXAxis($draw)
- {
- $this->suppress_x_axis = !$draw; // See DrawXAxis()
- return TRUE;
- }
-
- /*
- * Enable or disable drawing of the Y axis line.
- * $draw : True to draw the axis (default if not called), False to suppress it.
- * This controls drawing of the axis line only, and not the ticks, labels, or grid.
- */
- function SetDrawYAxis($draw)
- {
- $this->suppress_y_axis = !$draw; // See DrawYAxis()
- return TRUE;
- }
-
- /*
- * Select linear or log scale for the X axis.
- */
- function SetXScaleType($which_xst)
- {
- $this->xscale_type = $this->CheckOption($which_xst, 'linear, log', __FUNCTION__);
- return (boolean)$this->xscale_type;
- }
-
- /*
- * Select linear or log scale for the Y axis.
- */
- function SetYScaleType($which_yst)
- {
- $this->yscale_type = $this->CheckOption($which_yst, 'linear, log', __FUNCTION__);
- return (boolean)$this->yscale_type;
- }
-
- /*
- * Set the precision for numerically formatted X labels.
- * $which_prec : Number of digits to display.
- * Note: This is equivalent to: SetXLabelType('data', $which_prec)
- */
- function SetPrecisionX($which_prec)
- {
- return $this->SetXLabelType('data', $which_prec);
- }
-
- /*
- * Set the precision for numerically formatted Y labels.
- * $which_prec : Number of digits to display.
- * Note: This is equivalent to: SetYLabelType('data', $which_prec)
- */
- function SetPrecisionY($which_prec)
- {
- return $this->SetYLabelType('data', $which_prec);
- }
-
- /*
- * Set the line width (in pixels) for error bars.
- */
- function SetErrorBarLineWidth($which_seblw)
- {
- $this->error_bar_line_width = $which_seblw;
- return TRUE;
- }
-
- /*
- * Set the position for pie chart percentage labels.
- * $which_blb : Real number between 0 and 1.
- * Smaller values move the labels in towards the center.
- */
- function SetLabelScalePosition($which_blp)
- {
- $this->label_scale_position = $which_blp;
- return TRUE;
- }
-
- /*
- * Set the size (in pixels) of the "T" in error bars.
- */
- function SetErrorBarSize($which_ebs)
- {
- $this->error_bar_size = $which_ebs;
- return TRUE;
- }
-
- /*
- * Set the shape of the in error bars.
- * $which_ebs : Error bar shape, 'tee' or 'line'.
- */
- function SetErrorBarShape($which_ebs)
- {
- $this->error_bar_shape = $this->CheckOption($which_ebs, 'tee, line', __FUNCTION__);
- return (boolean)$this->error_bar_shape;
- }
-
- /*
- * Synchronize the point shape and point size arrays.
- * This is called just before drawing any plot that needs 'points'.
- */
- protected function CheckPointParams()
- {
- // Make both point_shapes and point_sizes the same size, by padding the smaller.
- $ps = count($this->point_sizes);
- $pt = count($this->point_shapes);
-
- if ($ps < $pt) {
- $this->pad_array($this->point_sizes, $pt);
- $this->point_counts = $pt;
- } elseif ($ps > $pt) {
- $this->pad_array($this->point_shapes, $ps);
- $this->point_counts = $ps;
- } else {
- $this->point_counts = $ps;
- }
-
- // Note: PHPlot used to check and adjust point_sizes to be an even number here,
- // for all 'diamond' and 'triangle' shapes. The reason for this having been
- // lost, and the current maintainer seeing no sense it doing this for only
- // some shapes, the code has been removed. But see what DrawDot() does.
- }
-
- /*
- * Set the point shape for each data set.
- * $which_pt : Array (or single value) of valid point shapes. See also DrawDot() for valid shapes.
- * The point shape and point sizes arrays are synchronized before drawing a graph
- * that uses points. See CheckPointParams()
- */
- function SetPointShapes($which_pt)
- {
- $this->point_shapes = $this->CheckOptionArray($which_pt, 'halfline, line, plus, cross, rect,'
- . ' circle, dot, diamond, triangle, trianglemid, delta, yield, star, hourglass,'
- . ' bowtie, target, box, home, up, down, none', __FUNCTION__);
- return !empty($this->point_shapes);
- }
-
- /*
- * Set the point size for point plots.
- * $which_ps : Array (or single value) of point sizes in pixels.
- * The point shape and point sizes arrays are synchronized before drawing a graph
- * that uses points. See CheckPointParams()
- */
- function SetPointSizes($which_ps)
- {
- if (is_array($which_ps)) {
- // Use provided array:
- $this->point_sizes = $which_ps;
- } elseif (!is_null($which_ps)) {
- // Make the single value into an array:
- $this->point_sizes = array($which_ps);
- }
- return TRUE;
- }
-
- /*
- * Sets whether lines should be broken at missing data.
- * $bl : True to break the lines, false to connect around missing data.
- * This only works with 'lines' and 'squared' plots.
- */
- function SetDrawBrokenLines($bl)
- {
- $this->draw_broken_lines = (bool)$bl;
- return TRUE;
- }
-
- /*
- * Set the data type, which defines the structure of the data array
- * text-data: ('label', y1, y2, y3, ...)
- * text-data-single: ('label', data), for some pie charts.
- * data-data: ('label', x, y1, y2, y3, ...)
- * data-data-error: ('label', x1, y1, e1+, e2-, y2, e2+, e2-, y3, e3+, e3-, ...)
- * data-data-yx: ('label', y, x1, x2, x3, ..)
- * text-data-yx: ('label', x1, x2, x3, ...)
- */
- function SetDataType($which_dt)
- {
- //The next four lines are for past compatibility.
- if ($which_dt == 'text-linear') $which_dt = 'text-data';
- elseif ($which_dt == 'linear-linear') $which_dt = 'data-data';
- elseif ($which_dt == 'linear-linear-error') $which_dt = 'data-data-error';
- elseif ($which_dt == 'text-data-pie') $which_dt = 'text-data-single';
-
- $this->data_type = $this->CheckOption($which_dt, 'text-data, text-data-single, '.
- 'data-data, data-data-error, '.
- 'data-data-yx, text-data-yx',
- __FUNCTION__);
- return (boolean)$this->data_type;
- }
-
- /*
- * Copy the array passed as data values. We convert to numerical indexes, for its
- * use for (or while) loops, which sometimes are faster. Performance improvements
- * vary from 28% in DrawLines() to 49% in DrawArea() for plot drawing functions.
- */
- function SetDataValues($which_dv)
- {
- $this->num_data_rows = count($which_dv);
- $this->total_records = 0;
- $this->data = array();
- $this->num_recs = array();
- for ($i = 0; $i < $this->num_data_rows; $i++) {
- $this->data[$i] = array_values($which_dv[$i]); // convert to numerical indices.
-
- // Count size of each row, and total for the array.
- $recs = count($this->data[$i]);
- $this->total_records += $recs;
- $this->num_recs[$i] = $recs;
- }
- // This is the size of the widest row in the data array
- // Note records_per_group isn't used much anymore. See data_columns in CheckDataArray()
- $this->records_per_group = max($this->num_recs);
- return TRUE;
- }
-
- /*
- * Pad styles arrays for later use by plot drawing functions:
- * This removes the need for $max_data_colors, etc. and $color_index = $color_index % $max_data_colors
- * in DrawBars(), DrawLines(), etc.
- * The arrays are padded to data_columns which is the maximum number of data sets.
- * See CheckDataArray() for the calculation.
- */
- protected function PadArrays()
- {
- $this->pad_array($this->line_widths, $this->data_columns);
- $this->pad_array($this->line_styles, $this->data_columns);
- $this->pad_array($this->ndx_data_colors, $this->data_columns);
- $this->pad_array($this->ndx_data_border_colors, $this->data_columns);
- // Other data color arrays are handled in the Need*Colors() functions.
-
- return TRUE;
- }
-
- /*
- * Pads an array with itself. This only works on 0-based sequential integer indexed arrays.
- * $arr : The array (or scalar) to pad. This argument is modified.
- * $size : Minimum size of the resulting array.
- * If $arr is a scalar, it will be converted first to a single element array.
- * If $arr has at least $size elements, it is unchanged.
- * Otherwise, append elements of $arr to itself until it reaches $size elements.
- */
- protected function pad_array(&$arr, $size)
- {
- if (! is_array($arr)) {
- $arr = array($arr);
- }
- $n = count($arr);
- $base = 0;
- while ($n < $size) $arr[$n++] = $arr[$base++];
- }
-
- /*
- * Format a floating-point number.
- * $number : A floating point number to format
- * $decimals : Number of decimal places in the result
- * Returns the formatted result.
- * This is like PHP's number_format, but uses class variables for separators.
- * The separators will default to locale-specific values, if available.
- */
- protected function number_format($number, $decimals=0)
- {
- if (!isset($this->decimal_point) || !isset($this->thousands_sep)) {
- // Load locale-specific values from environment, unless disabled:
- if (empty($this->locale_override))
- @setlocale(LC_ALL, '');
- // Fetch locale settings:
- $locale = @localeconv();
- if (isset($locale['decimal_point']) && isset($locale['thousands_sep'])) {
- $this->decimal_point = $locale['decimal_point'];
- $this->thousands_sep = $locale['thousands_sep'];
- } else {
- // Locale information not available.
- $this->decimal_point = '.';
- $this->thousands_sep = ',';
- }
- }
- return number_format($number, $decimals, $this->decimal_point, $this->thousands_sep);
- }
-
- /*
- * Register a callback (hook) function
- * $reason : A pre-defined name where a callback can be defined.
- * $function : The name of a function to register for callback, or an instance/method
- * pair in an array (see 'callbacks' in the PHP reference manual).
- * $arg : Optional argument to supply to the callback function when it is triggered.
- * (Often called "clientData")
- * Returns True if the callback reason is valid, else False.
- */
- function SetCallback($reason, $function, $arg = NULL)
- {
- // Use array_key_exists because valid reason keys have NULL as value.
- if (!array_key_exists($reason, $this->callbacks))
- return FALSE;
- $this->callbacks[$reason] = array($function, $arg);
- return TRUE;
- }
-
- /*
- * Return the name of a function registered for callback. See SetCallBack.
- * $reason - A pre-defined name where a callback can be defined.
- * Returns the current callback function (name or array) for the given reason,
- * or False if there was no active callback or the reason is not valid.
- * Note you can safely test the return value with a simple 'if', as
- * no valid function name evaluates to false.
- */
- function GetCallback($reason)
- {
- if (isset($this->callbacks[$reason]))
- return $this->callbacks[$reason][0];
- return FALSE;
- }
-
- /*
- * Un-register (remove) a function registered for callback.
- * $reason - A pre-defined name where a callback can be defined.
- * Returns: True if it was a valid callback reason, else False.
- * Note: Returns True whether or not there was a callback registered.
- */
- function RemoveCallback($reason)
- {
- if (!array_key_exists($reason, $this->callbacks))
- return FALSE;
- $this->callbacks[$reason] = NULL;
- return TRUE;
- }
-
- /*
- * Invoke a callback, if one is registered.
- * Accepts a variable number of arguments >= 1:
- * $reason : A string naming the callback.
- * ... : Zero or more additional arguments to be passed to the
- * callback function, after the passthru argument:
- * callback_function($image, $passthru, ...)
- * Returns: whatever value (if any) was returned by the callback.
- */
- protected function DoCallback() // Note: Variable arguments
- {
- $args = func_get_args();
- $reason = $args[0];
- if (!isset($this->callbacks[$reason]))
- return;
- list($function, $args[0]) = $this->callbacks[$reason];
- array_unshift($args, $this->img);
- // Now args[] looks like: img, passthru, extra args...
- return call_user_func_array($function, $args);
- }
-
- /*
- * Allocate colors for the plot.
- * This is called by DrawGraph to allocate the colors needed for the plot. Each selectable
- * color has already been validated, parsed into an array (r,g,b,a), and stored into a member
- * variable. Now the GD color indexes are assigned and stored into the ndx_*_color variables.
- * This is deferred here to avoid allocating unneeded colors and to avoid order dependencies,
- * especially with the transparent color.
- *
- * For drawing data elements, only the main data colors and border colors are allocated here.
- * Dark colors and error bar colors are allocated by Need*Color() functions.
- * (Data border colors default to just black, so there is no cost to always allocating.)
- *
- * Data color allocation works as follows. If there is a data_color callback, then allocate all
- * defined data colors (because the callback can use them however it wants). Otherwise, only allocate
- * the number of colors that will be used. This is the larger of the number of data sets and the
- * number of legend lines.
- */
- protected function SetColorIndexes()
- {
- $this->ndx_bg_color = $this->GetColorIndex($this->bg_color); // Background first
- $this->ndx_plot_bg_color = $this->GetColorIndex($this->plot_bg_color);
- if ($this->image_border_type != 'none') {
- $this->ndx_i_border = $this->GetColorIndex($this->i_border);
- $this->ndx_i_border_dark = $this->GetDarkColorIndex($this->i_border);
- }
-
- // Handle defaults for X and Y title colors.
- $this->ndx_title_color = $this->GetColorIndex($this->title_color);
- if (empty($this->x_title_color)) {
- $this->ndx_x_title_color = $this->ndx_title_color;
- } else {
- $this->ndx_x_title_color = $this->GetColorIndex($this->x_title_color);
- }
- if (empty($this->y_title_color)) {
- $this->ndx_y_title_color = $this->ndx_title_color;
- } else {
- $this->ndx_y_title_color = $this->GetColorIndex($this->y_title_color);
- }
-
- $this->ndx_text_color = $this->GetColorIndex($this->text_color);
- $this->ndx_grid_color = $this->GetColorIndex($this->grid_color);
- $this->ndx_light_grid_color = $this->GetColorIndex($this->light_grid_color);
- $this->ndx_tick_color = $this->GetColorIndex($this->tick_color);
-
- // Maximum number of data & border colors to allocate:
- if ($this->GetCallback('data_color')) {
- $n_data = count($this->data_colors); // Need all of them
- $n_border = count($this->data_border_colors);
- } else {
- $n_data = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend));
- $n_border = $n_data; // One border color per data color
- }
-
- // Allocate main data colors. For other colors used for data, see the functions which follow.
- $this->ndx_data_colors = $this->GetColorIndexArray($this->data_colors, $n_data);
- $this->ndx_data_border_colors = $this->GetColorIndexArray($this->data_border_colors, $n_border);
-
- // Set up a color as transparent, if SetTransparentColor was used.
- if (!empty($this->transparent_color)) {
- imagecolortransparent($this->img, $this->GetColorIndex($this->transparent_color));
- }
- }
-
- /*
- * Allocate dark-shade data colors. Called if needed by graph drawing functions.
- */
- protected function NeedDataDarkColors()
- {
- // This duplicates the calculation in SetColorIndexes() for number of data colors to allocate.
- if ($this->GetCallback('data_color')) {
- $n_data = count($this->data_colors);
- } else {
- $n_data = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend));
- }
- $this->ndx_data_dark_colors = $this->GetDarkColorIndexArray($this->data_colors, $n_data);
- $this->pad_array($this->ndx_data_dark_colors, $this->data_columns);
- }
-
- /*
- * Allocate error bar colors. Called if needed by graph drawing functions.
- */
- protected function NeedErrorBarColors()
- {
- // This is similar to the calculation in SetColorIndexes() for number of data colors to allocate.
- if ($this->GetCallback('data_color')) {
- $n_err = count($this->error_bar_colors);
- } else {
- $n_err = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend));
- }
- $this->ndx_error_bar_colors = $this->GetColorIndexArray($this->error_bar_colors, $n_err);
- $this->pad_array($this->ndx_error_bar_colors, $this->data_columns);
- }
-
- /*
- * Determine if, and where, to draw Data Value Labels.
- * $label_control : Label position control. Either x_data_label_pos or y_data_label_pos.
- * &$x_adj, &$y_adj : Returns X,Y adjustments (offset in pixels) to the text position.
- * &$h_align, &$v_align : Returns horizontal and vertical alignment for the label.
- * The above 4 argument values should be passed to DrawDataValueLabel()
- * Returns True if data value labels should be drawn (based on $label_control), else False.
- * This is used for plot types other than bars/stackedbars (which have their own way of doing it).
- * It uses two member variables (unset by default): data_value_label_angle and data_value_label_distance
- * to define the vector to the label. Default is 90 degrees at 5 pixels.
- */
- protected function CheckDataValueLabels($label_control, &$x_adj, &$y_adj, &$h_align, &$v_align)
- {
- if ($label_control != 'plotin')
- return FALSE; // No data value labels
- $angle = deg2rad(isset($this->data_value_label_angle) ? $this->data_value_label_angle : 90);
- $radius = isset($this->data_value_label_distance) ? $this->data_value_label_distance : 5;
- $cos = cos($angle);
- $sin = sin($angle);
- $x_adj = (int)($radius * $cos);
- $y_adj = -(int)($radius * $sin); // Y is reversed in device coordinates
-
- // Choose from 8 (not 9, center/center can't happen) text alignments based on angle:
- if ($sin >= 0.383) $v_align = 'bottom'; // 0.383 = sin(360deg / 16)
- elseif ($sin >= -0.383) $v_align = 'center';
- else $v_align = 'top';
- if ($cos >= 0.383) $h_align = 'left';
- elseif ($cos >= -0.383) $h_align = 'center';
- else $h_align = 'right';
- return TRUE;
- }
-
-//////////////////////////////////////////////////////////
-/////////// DATA ANALYSIS, SCALING AND TRANSLATION
-//////////////////////////////////////////////////////////
-
- /*
- * Analyzes the data array and calculates the minimum and maximum values.
- * In this function, IV refers to the independent variable, and DV the dependent variable.
- * For most plots, IV is X and DV is Y. For swapped X/Y plots, IV is Y and DV is X.
- * At the end of the function, IV and DV ranges get assigned into X or Y.
- *
- * The data type mostly determines the data array structure, but some plot types do special
- * things such as sum the values in a row. This information is in the plots[] array.
- *
- * This calculates min_x, max_x, min_y, and max_y. It also calculates two arrays
- * data_min[] and data_max[] with per-row min and max values. These are used for
- * data label lines. For normal (unswapped) data, these are the Y range for each X.
- * For swapped X/Y data, they are the X range for each Y.
- */
- protected function FindDataLimits()
- {
- // Does this plot type need special processing of the data values?
- $sum_vals = !empty(PHPlot::$plots[$this->plot_type]['sum_vals']); // Add up values in each row
- $abs_vals = !empty(PHPlot::$plots[$this->plot_type]['abs_vals']); // Take absolute values
-
- // These need to be initialized in case there are multiple plots and missing data points.
- $this->data_min = array();
- $this->data_max = array();
-
- // Independent values are in the data array or assumed?
- if ($this->datatype_implied) {
- $all_iv = array(0, $this->num_data_rows - 1);
- } else {
- $all_iv = array();
- }
-
- // Process all rows of data:
- for ($i = 0; $i < $this->num_data_rows; $i++) {
- $n_vals = $this->num_recs[$i];
- $j = 1; // Skips label at [0]
-
- if (!$this->datatype_implied) {
- $all_iv[] = (double)$this->data[$i][$j++];
- }
-
- if ($sum_vals) {
- $all_dv = array(0, 0); // One limit is 0, other calculated below
- } else {
- $all_dv = array();
- }
- while ($j < $n_vals) {
- if (is_numeric($this->data[$i][$j])) {
- $val = (double)$this->data[$i][$j++];
-
- if ($this->datatype_error_bars) {
- $all_dv[] = $val + (double)$this->data[$i][$j++];
- $all_dv[] = $val - (double)$this->data[$i][$j++];
- } else {
- if ($abs_vals) {
- $val = abs($val); // Use absolute values
- }
- if ($sum_vals) {
- $all_dv[1] += $val; // Sum of values
- } else {
- $all_dv[] = $val; // List of all values
- }
- }
- } else { // Missing DV value
- $j++;
- if ($this->datatype_error_bars) $j += 2;
- }
- }
- if (!empty($all_dv)) {
- $this->data_min[$i] = min($all_dv); // Store per-row DV range
- $this->data_max[$i] = max($all_dv);
- }
- }
-
- if ($this->datatype_swapped_xy) {
- // Assign min and max for swapped X/Y plots: IV=Y and DV=X
- $this->min_y = min($all_iv);
- $this->max_y = max($all_iv);
- if (empty($this->data_min)) { // Guard against regressive case: No X at all
- $this->min_x = 0;
- $this->max_x = 0;
- } else {
- $this->min_x = min($this->data_min); // Store global X range
- $this->max_x = max($this->data_max);
- }
- } else {
- // Assign min and max for normal plots: IV=X and DV=Y
- $this->min_x = min($all_iv);
- $this->max_x = max($all_iv);
- if (empty($this->data_min)) { // Guard against regressive case: No Y at all
- $this->min_y = 0;
- $this->max_y = 0;
- } else {
- $this->min_y = min($this->data_min); // Store global Y range
- $this->max_y = max($this->data_max);
- }
- }
-
- if ($this->GetCallback('debug_scale')) {
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'min_x' => $this->min_x, 'min_y' => $this->min_y,
- 'max_x' => $this->max_x, 'max_y' => $this->max_y));
- }
- return TRUE;
- }
-
- /*
- * Calculates image margins on the fly from title positions and sizes,
- * and tick labels positions and sizes.
- *
- * A picture of the locations of elements and spacing can be found in the
- * PHPlot Reference Manual.
- *
- * Calculates the following (class variables unless noted):
- *
- * Plot area margins (see note below):
- * y_top_margin
- * y_bot_margin
- * x_left_margin
- * x_right_margin
- *
- * Title sizes (these are now local, not class variables, since they are not used elsewhere):
- * title_height : Height of main title
- * x_title_height : Height of X axis title, 0 if no X title
- * y_title_width : Width of Y axis title, 0 if no Y title
- *
- * Tick/Data label offsets, relative to plot_area:
- * x_label_top_offset, x_label_bot_offset, x_label_axis_offset
- * y_label_left_offset, y_label_right_offset, y_label_axis_offset
- *
- * Title offsets, relative to plot area:
- * x_title_top_offset, x_title_bot_offset
- * y_title_left_offset, y_title_left_offset
- * title_offset (for main title, relative to image edge)
- *
- * Note: The margins are calculated, but not stored, if margins or plot area were
- * set by the user with SetPlotAreaPixels or SetMarginsPixels. The margin
- * calculation is mixed in with the offset variables, so it doesn't seem worth the
- * trouble to separate them.
- *
- * If the $maximize argument is true, we use the full image size, minus safe_margin
- * and main title, for the plot. This is for pie charts which have no axes or X/Y titles.
- */
- protected function CalcMargins($maximize)
- {
- // This is the line-to-line or line-to-text spacing:
- $gap = $this->safe_margin;
- // Initial margin on each side takes into account a possible image border.
- // For compatibility, if border is 1 or 2, don't increase the margins.
- $base_margin = max($gap, $this->GetImageBorderWidth() + 3);
- $this->title_offset = $base_margin; // For use in DrawTitle
-
- // Minimum margin on each side. This reduces the chance that the
- // right-most tick label (for example) will run off the image edge
- // if there are no titles on that side.
- $min_margin = 2 * $gap + $base_margin;
-
- // Calculate the title sizes:
- list($unused, $title_height) = $this->SizeText($this->fonts['title'], 0, $this->title_txt);
- list($unused, $x_title_height) = $this->SizeText($this->fonts['x_title'], 0, $this->x_title_txt);
- list($y_title_width, $unused) = $this->SizeText($this->fonts['y_title'], 90, $this->y_title_txt);
-
- // Special case for maximum area usage with no X/Y titles or labels, only main title:
- if ($maximize) {
- if (!isset($this->x_left_margin))
- $this->x_left_margin = $base_margin;
- if (!isset($this->x_right_margin))
- $this->x_right_margin = $base_margin;
- if (!isset($this->y_top_margin)) {
- $this->y_top_margin = $base_margin;
- if ($title_height > 0)
- $this->y_top_margin += $title_height + $gap;
- }
- if (!isset($this->y_bot_margin))
- $this->y_bot_margin = $base_margin;
-
- return TRUE;
- }
-
- // Make local variables for these. (They get used a lot and I'm tired of this, this, this.)
- $x_tick_label_pos = $this->x_tick_label_pos;
- $x_data_label_pos = $this->x_data_label_pos;
- $x_tick_pos = $this->x_tick_pos;
- $x_tick_len = $this->x_tick_length;
- $y_tick_label_pos = $this->y_tick_label_pos;
- $y_tick_pos = $this->y_tick_pos;
- $y_tick_len = $this->y_tick_length;
- $y_data_label_pos = $this->y_data_label_pos;
-
- // For X/Y tick and label position of 'xaxis' or 'yaxis', determine if the axis happens to be
- // on an edge of a plot. If it is, we need to account for the margins there.
- if ($this->x_axis_position <= $this->plot_min_y)
- $x_axis_pos = 'bottom';
- elseif ($this->x_axis_position >= $this->plot_max_y)
- $x_axis_pos = 'top';
- else
- $x_axis_pos = 'none';
- if ($this->y_axis_position <= $this->plot_min_x)
- $y_axis_pos = 'left';
- elseif ($this->y_axis_position >= $this->plot_max_x)
- $y_axis_pos = 'right';
- else
- $y_axis_pos = 'none';
-
- // Calculate the heights for X tick and data labels, and the max (used if they are overlaid):
- $x_data_label_height = ($x_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('x');
- $x_tick_label_height = ($x_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('x');
- $x_max_label_height = max($x_data_label_height, $x_tick_label_height);
-
- // Calculate the space needed above and below the plot for X tick and X data labels:
-
- // Above the plot:
- $tick_labels_above = ($x_tick_label_pos == 'plotup' || $x_tick_label_pos == 'both'
- || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'top'));
- $data_labels_above = ($x_data_label_pos == 'plotup' || $x_data_label_pos == 'both');
- if ($tick_labels_above) {
- if ($data_labels_above) {
- $label_height_above = $x_max_label_height;
- } else {
- $label_height_above = $x_tick_label_height;
- }
- } elseif ($data_labels_above) {
- $label_height_above = $x_data_label_height;
- } else {
- $label_height_above = 0;
- }
-
- // Below the plot:
- $tick_labels_below = ($x_tick_label_pos == 'plotdown' || $x_tick_label_pos == 'both'
- || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'bottom'));
- $data_labels_below = ($x_data_label_pos == 'plotdown' || $x_data_label_pos == 'both');
- if ($tick_labels_below) {
- if ($data_labels_below) {
- $label_height_below = $x_max_label_height;
- } else {
- $label_height_below = $x_tick_label_height;
- }
- } elseif ($data_labels_below) {
- $label_height_below = $x_data_label_height;
- } else {
- $label_height_below = 0;
- }
-
- // Calculate the width for Y tick and data labels, if on, and the max:
- // Note CalcMaxDataLabelSize('y') returns 0 except for swapped X/Y plots.
- $y_data_label_width = ($y_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('y');
- $y_tick_label_width = ($y_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('y');
- $y_max_label_width = max($y_data_label_width, $y_tick_label_width);
-
- // Calculate the space needed left and right of the plot for Y tick and Y data labels:
- // (Y data labels here are for swapped X/Y plots such has horizontal bars)
-
- // Left of the plot:
- $tick_labels_left = ($y_tick_label_pos == 'plotleft' || $y_tick_label_pos == 'both'
- || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'left'));
- $data_labels_left = ($y_data_label_pos == 'plotleft' || $y_data_label_pos == 'both');
- if ($tick_labels_left) {
- if ($data_labels_left) {
- $label_width_left = $y_max_label_width;
- } else {
- $label_width_left = $y_tick_label_width;
- }
- } elseif ($data_labels_left) {
- $label_width_left = $y_data_label_width;
- } else {
- $label_width_left = 0;
- }
-
- // Right of the plot:
- $tick_labels_right = ($y_tick_label_pos == 'plotright' || $y_tick_label_pos == 'both'
- || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'right'));
- $data_labels_right = ($y_data_label_pos == 'plotright' || $y_data_label_pos == 'both');
- if ($tick_labels_right) {
- if ($data_labels_right) {
- $label_width_right = $y_max_label_width;
- } else {
- $label_width_right = $y_tick_label_width;
- }
- } elseif ($data_labels_right) {
- $label_width_right = $y_data_label_width;
- } else {
- $label_width_right = 0;
- }
-
- ///////// Calculate margins:
-
- // Calculating Top and Bottom margins:
- // y_top_margin: Main title, Upper X title, X ticks and tick labels, and X data labels:
- // y_bot_margin: Lower title, ticks and tick labels, and data labels:
- $top_margin = $base_margin;
- $bot_margin = $base_margin;
- $this->x_title_top_offset = $gap;
- $this->x_title_bot_offset = $gap;
-
- // Space for main title?
- if ($title_height > 0)
- $top_margin += $title_height + $gap;
-
- // Space for X Title?
- if ($x_title_height > 0) {
- $pos = $this->x_title_pos;
- if ($pos == 'plotup' || $pos == 'both')
- $top_margin += $x_title_height + $gap;
- if ($pos == 'plotdown' || $pos == 'both')
- $bot_margin += $x_title_height + $gap;
- }
-
- // Space for X Labels above the plot?
- if ($label_height_above > 0) {
- $top_margin += $label_height_above + $gap;
- $this->x_title_top_offset += $label_height_above + $gap;
- }
-
- // Space for X Labels below the plot?
- if ($label_height_below > 0) {
- $bot_margin += $label_height_below + $gap;
- $this->x_title_bot_offset += $label_height_below + $gap;
- }
-
- // Space for X Ticks above the plot?
- if ($x_tick_pos == 'plotup' || $x_tick_pos == 'both'
- || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'top')) {
- $top_margin += $x_tick_len;
- $this->x_label_top_offset = $x_tick_len + $gap;
- $this->x_title_top_offset += $x_tick_len;
- } else {
- // No X Ticks above the plot:
- $this->x_label_top_offset = $gap;
- }
-
- // Space for X Ticks below the plot?
- if ($x_tick_pos == 'plotdown' || $x_tick_pos == 'both'
- || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'bottom')) {
- $bot_margin += $x_tick_len;
- $this->x_label_bot_offset = $x_tick_len + $gap;
- $this->x_title_bot_offset += $x_tick_len;
- } else {
- // No X Ticks below the plot:
- $this->x_label_bot_offset = $gap;
- }
- // Label offsets for on-axis ticks:
- if ($x_tick_pos == 'xaxis') {
- $this->x_label_axis_offset = $x_tick_len + $gap;
- } else {
- $this->x_label_axis_offset = $gap;
- }
-
- // Calculating Left and Right margins:
- // x_left_margin: Left Y title, Y ticks and tick labels:
- // x_right_margin: Right Y title, Y ticks and tick labels:
- $left_margin = $base_margin;
- $right_margin = $base_margin;
- $this->y_title_left_offset = $gap;
- $this->y_title_right_offset = $gap;
-
- // Space for Y Title?
- if ($y_title_width > 0) {
- $pos = $this->y_title_pos;
- if ($pos == 'plotleft' || $pos == 'both')
- $left_margin += $y_title_width + $gap;
- if ($pos == 'plotright' || $pos == 'both')
- $right_margin += $y_title_width + $gap;
- }
-
- // Space for Y Labels left of the plot?
- if ($label_width_left > 0) {
- $left_margin += $label_width_left + $gap;
- $this->y_title_left_offset += $label_width_left + $gap;
- }
-
- // Space for Y Labels right of the plot?
- if ($label_width_right > 0) {
- $right_margin += $label_width_right + $gap;
- $this->y_title_right_offset += $label_width_right + $gap;
- }
-
- // Space for Y Ticks left of plot?
- if ($y_tick_pos == 'plotleft' || $y_tick_pos == 'both'
- || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'left')) {
- $left_margin += $y_tick_len;
- $this->y_label_left_offset = $y_tick_len + $gap;
- $this->y_title_left_offset += $y_tick_len;
- } else {
- // No Y Ticks left of plot:
- $this->y_label_left_offset = $gap;
- }
-
- // Space for Y Ticks right of plot?
- if ($y_tick_pos == 'plotright' || $y_tick_pos == 'both'
- || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'right')) {
- $right_margin += $y_tick_len;
- $this->y_label_right_offset = $y_tick_len + $gap;
- $this->y_title_right_offset += $y_tick_len;
- } else {
- // No Y Ticks right of plot:
- $this->y_label_right_offset = $gap;
- }
-
- // Label offsets for on-axis ticks:
- if ($x_tick_pos == 'yaxis') {
- $this->y_label_axis_offset = $y_tick_len + $gap;
- } else {
- $this->y_label_axis_offset = $gap;
- }
-
- // Apply the minimum margins and store in the object.
- // Do not set margins which were user-defined (see note at top of function).
- if (!isset($this->y_top_margin))
- $this->y_top_margin = max($min_margin, $top_margin);
- if (!isset($this->y_bot_margin))
- $this->y_bot_margin = max($min_margin, $bot_margin);
- if (!isset($this->x_left_margin))
- $this->x_left_margin = max($min_margin, $left_margin);
- if (!isset($this->x_right_margin))
- $this->x_right_margin = max($min_margin, $right_margin);
-
- if ($this->GetCallback('debug_scale')) {
- // (Too bad compact() doesn't work on class member variables...)
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'label_height_above' => $label_height_above,
- 'label_height_below' => $label_height_below,
- 'label_width_left' => $label_width_left,
- 'label_width_right' => $label_width_right,
- 'x_tick_len' => $x_tick_len,
- 'y_tick_len' => $y_tick_len,
- 'x_left_margin' => $this->x_left_margin,
- 'x_right_margin' => $this->x_right_margin,
- 'y_top_margin' => $this->y_top_margin,
- 'y_bot_margin' => $this->y_bot_margin,
- 'x_label_top_offset' => $this->x_label_top_offset,
- 'x_label_bot_offset' => $this->x_label_bot_offset,
- 'y_label_left_offset' => $this->y_label_left_offset,
- 'y_label_right_offset' => $this->y_label_right_offset,
- 'x_title_top_offset' => $this->x_title_top_offset,
- 'x_title_bot_offset' => $this->x_title_bot_offset,
- 'y_title_left_offset' => $this->y_title_left_offset,
- 'y_title_right_offset' => $this->y_title_right_offset));
- }
-
- return TRUE;
- }
-
- /*
- * Calculate the plot area (device coordinates) from the margins.
- * (This used to be part of SetPlotAreaPixels.)
- * The margins might come from SetMarginsPixels, SetPlotAreaPixels,
- * or CalcMargins.
- */
- protected function CalcPlotAreaPixels()
- {
- $this->plot_area = array($this->x_left_margin, $this->y_top_margin,
- $this->image_width - $this->x_right_margin,
- $this->image_height - $this->y_bot_margin);
- $this->plot_area_width = $this->plot_area[2] - $this->plot_area[0];
- $this->plot_area_height = $this->plot_area[3] - $this->plot_area[1];
-
- $this->DoCallback('debug_scale', __FUNCTION__, $this->plot_area);
- return TRUE;
- }
-
- /*
- * Set the margins in pixels (left, right, top, bottom)
- * This determines the plot area, equivalent to SetPlotAreaPixels().
- * Deferred calculations now occur in CalcPlotAreaPixels().
- */
- function SetMarginsPixels($which_lm = NULL, $which_rm = NULL, $which_tm = NULL, $which_bm = NULL)
- {
- $this->x_left_margin = $which_lm;
- $this->x_right_margin = $which_rm;
- $this->y_top_margin = $which_tm;
- $this->y_bot_margin = $which_bm;
-
- return TRUE;
- }
-
- /*
- * Sets the limits for the plot area.
- * This stores the margins, not the area. That may seem odd, but
- * the idea is to make SetPlotAreaPixels and SetMarginsPixels two
- * ways to accomplish the same thing, and the deferred calculations
- * in CalcMargins and CalcPlotAreaPixels don't need to know which
- * was used.
- * (x1, y1) - Upper left corner of the plot area
- * (x2, y2) - Lower right corner of the plot area
- */
- function SetPlotAreaPixels($x1 = NULL, $y1 = NULL, $x2 = NULL, $y2 = NULL)
- {
- $this->x_left_margin = $x1;
- if (isset($x2)) $this->x_right_margin = $this->image_width - $x2;
- else unset($this->x_right_margin);
- $this->y_top_margin = $y1;
- if (isset($y2)) $this->y_bot_margin = $this->image_height - $y2;
- else unset($this->y_bot_margin);
-
- return TRUE;
- }
-
- /*
- * Calculate the World Coordinate limits of the plot area.
- * This goes with SetPlotAreaWorld, but the calculations are
- * deferred until the graph is being drawn.
- * Uses and sets: plot_min_x, plot_max_x, plot_min_y, plot_max_y
- * These can be user-supplied or NULL to auto-calculate.
- * Pre-requisites: FindDataLimits() calculates min_x, max_x, min_y, max_y
- * which are the limits of the data to be plotted.
- *
- * The general method is this:
- * If any part of the range is user-defined (via SetPlotAreaWorld),
- * use the user-defined value.
- * Else, if this is an implicitly-defined independent variable,
- * use the fixed range of 0 to (max+1).
- * Else, if this is an explicitly-defined independent variable,
- * use the exact data range (min to max).
- * Else, this is the dependent variable, so define a range which
- * includes and exceeds the data range by a bit.
- */
- protected function CalcPlotAreaWorld()
- {
- // Data array omits X or Y?
- $implied_x = $this->datatype_implied && !$this->datatype_swapped_xy;
- $implied_y = $this->datatype_implied && $this->datatype_swapped_xy;
-
- if (isset($this->plot_min_x) && $this->plot_min_x !== '')
- $xmin = $this->plot_min_x; // Use user-provided value
- elseif ($implied_x)
- $xmin = 0; // Implied X starts at zero
- elseif ($this->datatype_swapped_xy)
- // If X is the dependent variable, leave some room below.
- $xmin = floor($this->min_x - abs($this->min_x) * 0.1);
- else
- $xmin = $this->min_x; // Otherwise just start at the min data X
-
- if (isset($this->plot_max_x) && $this->plot_max_x !== '')
- $xmax = $this->plot_max_x; // Use user-provided value
- elseif ($implied_x)
- $xmax = $this->max_x + 1; // Implied X ends after last value
- elseif ($this->datatype_swapped_xy)
- // If X is the dependent variable, leave some room above.
- $xmax = ceil($this->max_x + abs($this->max_x) * 0.1);
- else
- $xmax = $this->max_x; // Otherwise just end at the max data X
-
- if (isset($this->plot_min_y) && $this->plot_min_y !== '')
- $ymin = $this->plot_min_y; // Use user-provided value
- elseif ($implied_y)
- $ymin = 0; // Implied Y starts at zero
- elseif ($this->datatype_swapped_xy)
- $ymin = $this->min_y; // Start at min data Y
- else
- // If Y is the dependent variable, leave some room below.
- $ymin = floor($this->min_y - abs($this->min_y) * 0.1);
-
- if (isset($this->plot_max_y) && $this->plot_max_y !== '')
- $ymax = $this->plot_max_y; // Use user-provided value
- elseif ($implied_y)
- $ymax = $this->max_y + 1; // Implied Y ends after last value
- elseif ($this->datatype_swapped_xy)
- $ymax = $this->max_y; // End at max data Y
- else
- // If Y is the dependent variable, leave some room above.
- $ymax = ceil($this->max_y + abs($this->max_y) * 0.1);
-
- // Error checking
-
- if ($ymin == $ymax)
- $ymax++;
- if ($xmin == $xmax)
- $xmax++;
-
- if ($this->yscale_type == 'log') {
- if ($ymin <= 0) {
- $ymin = 1;
- }
- if ($ymax <= 0) {
- // Note: Error messages reference the user function, not this function.
- return $this->PrintError('SetPlotAreaWorld(): Log plots need data greater than 0');
- }
- }
-
- if ($ymax <= $ymin) {
- return $this->PrintError('SetPlotAreaWorld(): Error in data - max not greater than min');
- }
-
- $this->plot_min_x = $xmin;
- $this->plot_max_x = $xmax;
- $this->plot_min_y = $ymin;
- $this->plot_max_y = $ymax;
- if ($this->GetCallback('debug_scale')) {
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'plot_min_x' => $this->plot_min_x, 'plot_min_y' => $this->plot_min_y,
- 'plot_max_x' => $this->plot_max_x, 'plot_max_y' => $this->plot_max_y));
- }
- return TRUE;
- }
-
- /*
- * Stores the desired World Coordinate range of the plot.
- * The user calls this to force one or more of the range limits to
- * specific values. Anything not set will be calculated in CalcPlotAreaWorld().
- */
- function SetPlotAreaWorld($xmin=NULL, $ymin=NULL, $xmax=NULL, $ymax=NULL)
- {
- $this->plot_min_x = $xmin;
- $this->plot_max_x = $xmax;
- $this->plot_min_y = $ymin;
- $this->plot_max_y = $ymax;
- return TRUE;
- }
-
- /*
- * Calculate the width (or height) of bars for bar plots.
- * $stacked : If true, this is a stacked bar plot (1 bar per group).
- * $verticals : If false, this is a horizontal bar plot.
- * This calculates:
- * record_bar_width : Allocated width for each bar (including gaps)
- * actual_bar_width : Actual drawn width of each bar
- * bar_adjust_gap : Gap on each side of each bar (0 if they touch)
- * For the case $verticals=False, horizontal bars are being drawn,
- * but the same variable names are used. Think of "bar_width" as being
- * the width if you are standing on the Y axis looking towards positive X.
- */
- protected function CalcBarWidths($stacked, $verticals)
- {
- // group_width is the width of a group, including padding
- if ($verticals) {
- $group_width = $this->plot_area_width / $this->num_data_rows;
- } else {
- $group_width = $this->plot_area_height / $this->num_data_rows;
- }
-
- // Actual number of bar spaces in the group. This includes the drawn bars, and
- // 'bar_extra_space'-worth of extra bars.
- if ($stacked) {
- $num_spots = 1 + $this->bar_extra_space;
- } else {
- $num_spots = $this->data_columns + $this->bar_extra_space;
- }
-
- // record_bar_width is the width of each bar's allocated area.
- // If bar_width_adjust=1 this is the width of the bar, otherwise
- // the bar is centered inside record_bar_width.
- // The equation is:
- // group_frac_width * group_width = record_bar_width * num_spots
- $this->record_bar_width = $this->group_frac_width * $group_width / $num_spots;
-
- // Note that the extra space due to group_frac_width and bar_extra_space will be
- // evenly divided on each side of the group: the drawn bars are centered in the group.
-
- // Within each bar's allocated space, if bar_width_adjust=1 the bar fills the
- // space, otherwise it is centered.
- // This is the actual drawn bar width:
- $this->actual_bar_width = $this->record_bar_width * $this->bar_width_adjust;
- // This is the gap on each side of the bar (0 if bar_width_adjust=1):
- $this->bar_adjust_gap = ($this->record_bar_width - $this->actual_bar_width) / 2;
-
- if ($this->GetCallback('debug_scale')) {
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'record_bar_width' => $this->record_bar_width,
- 'actual_bar_width' => $this->actual_bar_width,
- 'bar_adjust_gap' => $this->bar_adjust_gap));
- }
- return TRUE;
- }
-
- /*
- * Calculate X and Y Axis Positions, world coordinates.
- * This needs the min/max x/y range set by CalcPlotAreaWorld.
- * It adjusts or sets x_axis_position and y_axis_position per the data.
- * Empty string means the values need to be calculated; otherwise they
- * are supplied but need to be validated against the World area.
- *
- * Note: This used to be in CalcTranslation, but CalcMargins needs it too.
- * This does not calculate the pixel values of the axes. That happens in
- * CalcTranslation, after scaling is set up (which has to happen after
- * margins are set up).
- *
- * For vertical plots, the X axis defaults to Y=0 if that is inside the plot range, else whichever
- * of the top or bottom that has the smallest absolute value (that is, the value closest to 0).
- * The Y axis defaults to the left edge. For horizontal plots, the axis roles and defaults are switched.
- */
- protected function CalcAxisPositions()
- {
- // Validate user-provided X axis position, or calculate a default if not provided:
- if ($this->x_axis_position !== '') {
- // Force user-provided X axis position to be within the plot range:
- $this->x_axis_position = min(max($this->plot_min_y, $this->x_axis_position), $this->plot_max_y);
- } elseif ($this->yscale_type == 'log') {
- // Always use 1 for X axis position on log scale plots.
- $this->x_axis_position = 1;
- } elseif ($this->datatype_swapped_xy || $this->plot_min_y > 0) {
- // Horizontal plot, or Vertical Plot with all Y > 0: Place X axis on the bottom.
- $this->x_axis_position = $this->plot_min_y;
- } elseif ($this->plot_max_y < 0) {
- // Vertical plot with all Y < 0, so place the X axis at the top.
- $this->x_axis_position = $this->plot_max_y;
- } else {
- // Vertical plot range includes Y=0, so place X axis at 0.
- $this->x_axis_position = 0;
- }
-
- // Validate user-provided Y axis position, or calculate a default if not provided:
- if ($this->y_axis_position !== '') {
- // Force user-provided Y axis position to be within the plot range:
- $this->y_axis_position = min(max($this->plot_min_x, $this->y_axis_position), $this->plot_max_x);
- } elseif ($this->xscale_type == 'log') {
- // Always use 1 for Y axis position on log scale plots.
- $this->y_axis_position = 1;
- } elseif (!$this->datatype_swapped_xy || $this->plot_min_x > 0) {
- // Vertical plot, or Horizontal Plot with all X > 0: Place Y axis on left side.
- $this->y_axis_position = $this->plot_min_x;
- } elseif ($this->plot_max_x < 0) {
- // Horizontal plot with all X < 0, so place the Y axis on the right side.
- $this->y_axis_position = $this->plot_max_x;
- } else {
- // Horizontal plot range includes X=0: place Y axis at 0.
- $this->y_axis_position = 0;
- }
-
- if ($this->GetCallback('debug_scale')) {
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'x_axis_position' => $this->x_axis_position,
- 'y_axis_position' => $this->y_axis_position));
- }
-
- return TRUE;
- }
-
- /*
- * Calculates scaling stuff...
- */
- protected function CalcTranslation()
- {
- if ($this->plot_max_x - $this->plot_min_x == 0) { // Check for div by 0
- $this->xscale = 0;
- } else {
- if ($this->xscale_type == 'log') {
- $this->xscale = $this->plot_area_width /
- (log10($this->plot_max_x) - log10($this->plot_min_x));
- } else {
- $this->xscale = $this->plot_area_width / ($this->plot_max_x - $this->plot_min_x);
- }
- }
-
- if ($this->plot_max_y - $this->plot_min_y == 0) { // Check for div by 0
- $this->yscale = 0;
- } else {
- if ($this->yscale_type == 'log') {
- $this->yscale = $this->plot_area_height /
- (log10($this->plot_max_y) - log10($this->plot_min_y));
- } else {
- $this->yscale = $this->plot_area_height / ($this->plot_max_y - $this->plot_min_y);
- }
- }
- // GD defines x = 0 at left and y = 0 at TOP so -/+ respectively
- if ($this->xscale_type == 'log') {
- $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * log10($this->plot_min_x) );
- } else {
- $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * $this->plot_min_x);
- }
- if ($this->yscale_type == 'log') {
- $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * log10($this->plot_min_y));
- } else {
- $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * $this->plot_min_y);
- }
-
- // Convert axis positions to device coordinates:
- $this->y_axis_x_pixels = $this->xtr($this->y_axis_position);
- $this->x_axis_y_pixels = $this->ytr($this->x_axis_position);
-
- if ($this->GetCallback('debug_scale')) {
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'xscale' => $this->xscale, 'yscale' => $this->yscale,
- 'plot_origin_x' => $this->plot_origin_x, 'plot_origin_y' => $this->plot_origin_y,
- 'y_axis_x_pixels' => $this->y_axis_x_pixels,
- 'x_axis_y_pixels' => $this->x_axis_y_pixels));
- }
-
- return TRUE;
- }
-
- /*
- * Translate X world coordinate into pixel coordinate
- * See CalcTranslation() for calculation of xscale.
- * Note: This function should be 'protected', but is left public for historical reasons.
- * See GetDeviceXY() for a preferred public method.
- */
- function xtr($x_world)
- {
- if ($this->xscale_type == 'log') {
- $x_pixels = $this->plot_origin_x + log10($x_world) * $this->xscale ;
- } else {
- $x_pixels = $this->plot_origin_x + $x_world * $this->xscale ;
- }
- return round($x_pixels);
- }
-
- /*
- * Translate Y world coordinate into pixel coordinate.
- * See CalcTranslation() for calculation of yscale.
- * Note: This function should be 'protected', but is left public for historical reasons.
- * See GetDeviceXY() for a preferred public method.
- */
- function ytr($y_world)
- {
- if ($this->yscale_type == 'log') {
- //minus because GD defines y = 0 at top. doh!
- $y_pixels = $this->plot_origin_y - log10($y_world) * $this->yscale ;
- } else {
- $y_pixels = $this->plot_origin_y - $y_world * $this->yscale ;
- }
- return round($y_pixels);
- }
-
- /* A public interface to xtr and ytr. Translates (x,y) in world coordinates
- * to (x,y) in device coordinates and returns them as an array.
- * Usage is: list($x_pixel, $y_pixel) = $plot->GetDeviceXY($x_world, $y_world)
- */
- function GetDeviceXY($x_world, $y_world)
- {
- if (!isset($this->xscale)) {
- return $this->PrintError("GetDeviceXY() was called before translation factors were calculated");
- }
- return array($this->xtr($x_world), $this->ytr($y_world));
- }
-
- /*
- * Calculate tick parameters: Start, end, and delta values. This is used
- * by both DrawXTicks() and DrawYTicks().
- * This currently uses the same simplistic method previously used by
- * PHPlot (basically just range/10), but splitting this out into its
- * own function is the first step in replacing the method.
- * This is also used by CalcMaxTickSize() for CalcMargins().
- *
- * $which : 'x' or 'y' : Which tick parameters to calculate
- *
- * Returns an array of 3 elements: tick_start, tick_end, tick_step
- */
- protected function CalcTicks($which)
- {
- if ($which == 'x') {
- $num_ticks = $this->num_x_ticks;
- $tick_inc = $this->x_tick_inc;
- $data_max = $this->plot_max_x;
- $data_min = $this->plot_min_x;
- $skip_lo = $this->skip_left_tick;
- $skip_hi = $this->skip_right_tick;
- } elseif ($which == 'y') {
- $num_ticks = $this->num_y_ticks;
- $tick_inc = $this->y_tick_inc;
- $data_max = $this->plot_max_y;
- $data_min = $this->plot_min_y;
- $skip_lo = $this->skip_bottom_tick;
- $skip_hi = $this->skip_top_tick;
- } else {
- return $this->PrintError("CalcTicks: Invalid usage ($which)");
- }
-
- if (!empty($tick_inc)) {
- $tick_step = $tick_inc;
- } elseif (!empty($num_ticks)) {
- $tick_step = ($data_max - $data_min) / $num_ticks;
- } else {
- $tick_step = ($data_max - $data_min) / 10;
- }
-
- // NOTE: When working with floats, because of approximations when adding $tick_step,
- // the value may not quite reach the end, or may exceed it very slightly.
- // So apply a "fudge" factor.
- $tick_start = (double)$data_min;
- $tick_end = (double)$data_max + ($data_max - $data_min) / 10000.0;
-
- if ($skip_lo)
- $tick_start += $tick_step;
-
- if ($skip_hi)
- $tick_end -= $tick_step;
-
- return array($tick_start, $tick_end, $tick_step);
- }
-
- /*
- * Calculate the size of the biggest tick label. This is used by CalcMargins().
- * For 'x' ticks, it returns the height . For 'y' ticks, it returns the width.
- * This means height along Y, or width along X - not relative to the text angle.
- * That is what we need to calculate the needed margin space.
- * (Previous versions of PHPlot estimated this, using the maximum X or Y value,
- * or maybe the longest string. That doesn't work. -10 is longer than 9, etc.
- * So this gets the actual size of each label, slow as that may be.
- */
- protected function CalcMaxTickLabelSize($which)
- {
- list($tick_start, $tick_end, $tick_step) = $this->CalcTicks($which);
-
- if ($which == 'x') {
- $font = $this->fonts['x_label'];
- $angle = $this->x_label_angle;
- } elseif ($which == 'y') {
- $font = $this->fonts['y_label'];
- $angle = $this->y_label_angle;
- } else {
- return $this->PrintError("CalcMaxTickLabelSize: Invalid usage ($which)");
- }
-
- $max_width = 0;
- $max_height = 0;
-
- // Loop over ticks, same as DrawXTicks and DrawYTicks:
- // Avoid cumulative round-off errors from $val += $delta
- $n = 0;
- $tick_val = $tick_start;
- while ($tick_val <= $tick_end) {
- $tick_label = $this->FormatLabel($which, $tick_val);
- list($width, $height) = $this->SizeText($font, $angle, $tick_label);
- if ($width > $max_width) $max_width = $width;
- if ($height > $max_height) $max_height = $height;
- $tick_val = $tick_start + ++$n * $tick_step;
- }
- if ($this->GetCallback('debug_scale')) {
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'which' => $which, 'height' => $max_height, 'width' => $max_width));
- }
-
- if ($which == 'x')
- return $max_height;
- return $max_width;
- }
-
- /*
- * Calculate the size of the biggest data label. This is used by CalcMargins().
- * For $which='x', it returns the height of labels along the top or bottom.
- * For $which='y', it returns the width of labels along the left or right sides.
- * There is only one set of data labels (the first position in each data record).
- * They normally go along the top or bottom (or both). If the data type indicates
- * X/Y swapping (which is used for horizontal bar charts), the data labels go
- * along the sides instead. So CalcMaxDataLabelSize('x') returns 0 if the
- * data is X/Y swapped, and CalcMaxDataLabelSize('y') returns 0 if the data is
- * is not X/Y swapped.
- */
- protected function CalcMaxDataLabelSize($which = 'x')
- {
- if ($which == 'x') {
- if ($this->datatype_swapped_xy)
- return 0; // Shortcut: labels aren't on top/bottom.
- $font = $this->fonts['x_label'];
- $angle = $this->x_data_label_angle;
- $format_code = 'xd';
- } elseif ($which == 'y') {
- if (!$this->datatype_swapped_xy)
- return 0; // Shortcut: labels aren't on left/right.
- $font = $this->fonts['y_label'];
- $angle = $this->y_data_label_angle;
- $format_code = 'yd';
- } else {
- return $this->PrintError("CalcMaxDataLabelSize: Invalid usage ($which)");
- }
- $max_width = 0;
- $max_height = 0;
-
- // Loop over all data labels and find the biggest:
- for ($i = 0; $i < $this->num_data_rows; $i++) {
- $label = $this->FormatLabel($format_code, $this->data[$i][0]);
- list($width, $height) = $this->SizeText($font, $angle, $label);
- if ($width > $max_width) $max_width = $width;
- if ($height > $max_height) $max_height = $height;
- }
- if ($this->GetCallback('debug_scale')) {
- $this->DoCallback('debug_scale', __FUNCTION__, array(
- 'height' => $max_height, 'width' => $max_width));
- }
-
- if ($this->datatype_swapped_xy)
- return $max_width;
- return $max_height;
- }
-
- /*
- * Set grid control defaults.
- * X grid defaults off, Y grid defaults on, except the reverse is true
- * with swapped graphs such as horizontal bars.
- */
- protected function CalcGridSettings()
- {
- if (!isset($this->draw_x_grid))
- $this->draw_x_grid = $this->datatype_swapped_xy;
- if (!isset($this->draw_y_grid))
- $this->draw_y_grid = !$this->datatype_swapped_xy;
- }
-
- /*
- * Helper for CheckLabels() - determine if there are any non-empty labels.
- * Returns True if all data labels are empty, else False.
- */
- protected function CheckLabelsAllEmpty()
- {
- for ($i = 0; $i < $this->num_data_rows; $i++)
- if ($this->data[$i][0] !== '') return FALSE;
- return TRUE;
- }
-
- /*
- * Check and set label parameters. This handles deferred processing for label
- * positioning and other label-related parameters.
- * Copy label_format from 'x' to 'xd', and 'y' to 'yd', if not already set.
- * Set x_data_label_angle from x_label_angle, if not already set.
- * Apply defaults to X and Y tick and data label positions.
- * Note: the label strings in the data array are used as X data labels in
- * the normal case, but as Y data labels in the swapped X/Y case.
- */
- protected function CheckLabels()
- {
- // The X and Y data labels are formatted the same as X and Y tick labels,
- // unless overridden. Check and apply defaults for FormatLabel here:
- if (empty($this->label_format['xd']) && !empty($this->label_format['x']))
- $this->label_format['xd'] = $this->label_format['x'];
- if (empty($this->label_format['yd']) && !empty($this->label_format['y']))
- $this->label_format['yd'] = $this->label_format['y'];
-
- // The X tick label angle setting controls X data label angles too,
- // unless overridden. Check and apply the default here:
- if (!isset($this->x_data_label_angle))
- $this->x_data_label_angle = $this->x_label_angle;
- // Note: Y data label angle defaults to zero, unlike X,
- // for compatibility with older releases.
-
- // X Label position fixups, for x_data_label_pos and x_tick_label_pos:
- if ($this->datatype_swapped_xy) {
- // Just apply defaults - there is no position conflict for X labels.
- if (!isset($this->x_tick_label_pos))
- $this->x_tick_label_pos = 'plotdown';
- if (!isset($this->x_data_label_pos))
- $this->x_data_label_pos = 'none';
- } else {
- // Apply defaults but do not allow conflict between tick and data labels.
- if (isset($this->x_data_label_pos)) {
- if (!isset($this->x_tick_label_pos)) {
- // Case: data_label_pos is set, tick_label_pos needs a default:
- if ($this->x_data_label_pos == 'none')
- $this->x_tick_label_pos = 'plotdown';
- else
- $this->x_tick_label_pos = 'none';
- }
- } elseif (isset($this->x_tick_label_pos)) {
- // Case: tick_label_pos is set, data_label_pos needs a default:
- if ($this->x_tick_label_pos == 'none')
- $this->x_data_label_pos = 'plotdown';
- else
- $this->x_data_label_pos = 'none';
- } else {
- // Case: Neither tick_label_pos nor data_label_pos is set.
- // We do not want them to be both on (as PHPlot used to do in this case).
- // Turn on data labels if any were supplied, else tick labels.
- if ($this->CheckLabelsAllEmpty()) {
- $this->x_data_label_pos = 'none';
- $this->x_tick_label_pos = 'plotdown';
- } else {
- $this->x_data_label_pos = 'plotdown';
- $this->x_tick_label_pos = 'none';
- }
- }
- }
-
- // Y Label position fixups, for y_data_label_pos and y_tick_label_pos:
- if (!$this->datatype_swapped_xy) {
- // Just apply defaults - there is no position conflict.
- if (!isset($this->y_tick_label_pos))
- $this->y_tick_label_pos = 'plotleft';
- if (!isset($this->y_data_label_pos))
- $this->y_data_label_pos = 'none';
- } else {
- // Apply defaults but do not allow conflict between tick and data labels.
- if (isset($this->y_data_label_pos)) {
- if (!isset($this->y_tick_label_pos)) {
- // Case: data_label_pos is set, tick_label_pos needs a default:
- if ($this->y_data_label_pos == 'none')
- $this->y_tick_label_pos = 'plotleft';
- else
- $this->y_tick_label_pos = 'none';
- }
- } elseif (isset($this->y_tick_label_pos)) {
- // Case: tick_label_pos is set, data_label_pos needs a default:
- if ($this->y_tick_label_pos == 'none')
- $this->y_data_label_pos = 'plotleft';
- else
- $this->y_data_label_pos = 'none';
- } else {
- // Case: Neither tick_label_pos nor data_label_pos is set.
- // Turn on data labels if any were supplied, else tick labels.
- if ($this->CheckLabelsAllEmpty()) {
- $this->y_data_label_pos = 'none';
- $this->y_tick_label_pos = 'plotleft';
- } else {
- $this->y_data_label_pos = 'plotleft';
- $this->y_tick_label_pos = 'none';
- }
- }
- }
- return TRUE;
- }
-
- /*
- * Formats a tick or data label.
- * which_pos - 'x', 'xd', 'y', or 'yd', selects formatting controls.
- * x, y are for tick labels; xd, yd are for data labels.
- * which_lab - String to format as a label.
- * Credits: Time formatting suggested by Marlin Viss
- * Custom formatting suggested by zer0x333
- * Notes:
- * Type 'title' is obsolete and retained for compatibility.
- * Class variable 'data_units_text' is retained as a suffix for 'data' type formatting for
- * backward compatibility. Since there was never a function/method to set it, there
- * could be somebody out there who sets it directly in the object.
- */
- protected function FormatLabel($which_pos, $which_lab)
- {
- // Assign a reference shortcut to the label format controls.
- // Note CheckLabels() made sure the 'xd' and 'yd' arrays are set.
- $format =& $this->label_format[$which_pos];
-
- // Don't format empty strings (especially as time or numbers), or if no type was set.
- if ($which_lab !== '' && !empty($format['type'])) {
- switch ($format['type']) {
- case 'title': // Note: This is obsolete
- $which_lab = @ $this->data[$which_lab][0];
- break;
- case 'data':
- $which_lab = $format['prefix']
- . $this->number_format($which_lab, $format['precision'])
- . $this->data_units_text // Obsolete
- . $format['suffix'];
- break;
- case 'time':
- $which_lab = strftime($format['time_format'], $which_lab);
- break;
- case 'printf':
- $which_lab = sprintf($format['printf_format'], $which_lab);
- break;
- case 'custom':
- $which_lab = call_user_func($format['custom_callback'], $which_lab, $format['custom_arg']);
- break;
-
- }
- }
- return $which_lab;
- }
-
-/////////////////////////////////////////////
-/////////////// TICKS
-/////////////////////////////////////////////
-
- /*
- * Set the step (interval) between X ticks.
- * Use either this or SetNumXTicks(), not both, to control the X tick marks.
- */
- function SetXTickIncrement($which_ti='')
- {
- $this->x_tick_inc = $which_ti;
- if (!empty($which_ti)) {
- $this->num_x_ticks = '';
- }
- return TRUE;
- }
-
- /*
- * Set the step (interval) between Y ticks.
- * Use either this or SetNumYTicks(), not both, to control the Y tick marks.
- */
- function SetYTickIncrement($which_ti='')
- {
- $this->y_tick_inc = $which_ti;
- if (!empty($which_ti)) {
- $this->num_y_ticks = '';
- }
- return TRUE;
- }
-
- /*
- * Set the number of X tick marks.
- * Use either this or SetXTickIncrement(), not both, to control the X tick marks.
- */
- function SetNumXTicks($which_nt='')
- {
- $this->num_x_ticks = $which_nt;
- if (!empty($which_nt)) {
- $this->x_tick_inc = '';
- }
- return TRUE;
- }
-
- /*
- * Set the number of Y tick marks.
- * Use either this or SetYTickIncrement(), not both, to control the Y tick marks.
- */
- function SetNumYTicks($which_nt='')
- {
- $this->num_y_ticks = $which_nt;
- if (!empty($which_nt)) {
- $this->y_tick_inc = ''; //either use num_y_ticks or y_tick_inc, not both
- }
- return TRUE;
- }
-
- /*
- * Set the position for the X tick marks.
- * These can be above the plot, below, both positions, at the X axis, or suppressed.
- */
- function SetXTickPos($which_tp)
- {
- $this->x_tick_pos = $this->CheckOption($which_tp, 'plotdown, plotup, both, xaxis, none',
- __FUNCTION__);
- return (boolean)$this->x_tick_pos;
- }
-
- /*
- * Set the position for the Y tick marks.
- * These can be left of the plot, right, both positions, at the Y axis, or suppressed.
- */
- function SetYTickPos($which_tp)
- {
- $this->y_tick_pos = $this->CheckOption($which_tp, 'plotleft, plotright, both, yaxis, none',
- __FUNCTION__);
- return (boolean)$this->y_tick_pos;
- }
-
- /*
- * Skip the top-most Y axis tick mark and label if $skip is true.
- */
- function SetSkipTopTick($skip)
- {
- $this->skip_top_tick = (bool)$skip;
- return TRUE;
- }
-
- /*
- * Skip the bottom-most Y axis tick mark and label if $skip is true.
- */
- function SetSkipBottomTick($skip)
- {
- $this->skip_bottom_tick = (bool)$skip;
- return TRUE;
- }
-
- /*
- * Skip the left-most X axis tick mark and label if $skip is true.
- */
- function SetSkipLeftTick($skip)
- {
- $this->skip_left_tick = (bool)$skip;
- return TRUE;
- }
-
- /*
- * Skip the right-most X axis tick mark and label if $skip is true.
- */
- function SetSkipRightTick($skip)
- {
- $this->skip_right_tick = (bool)$skip;
- return TRUE;
- }
-
- /*
- * Set the outer length of X tick marks to $which_xln pixels.
- * This is the part of the tick mark that sticks out from the plot area.
- */
- function SetXTickLength($which_xln)
- {
- $this->x_tick_length = $which_xln;
- return TRUE;
- }
-
- /*
- * Set the outer length of Y tick marks to $which_yln pixels.
- * This is the part of the tick mark that sticks out from the plot area.
- */
- function SetYTickLength($which_yln)
- {
- $this->y_tick_length = $which_yln;
- return TRUE;
- }
-
- /*
- * Set the crossing length of X tick marks to $which_xc pixels.
- * This is the part of the tick mark that sticks into the plot area.
- */
- function SetXTickCrossing($which_xc)
- {
- $this->x_tick_cross = $which_xc;
- return TRUE;
- }
-
- /*
- * Set the crossing length of Y tick marks to $which_yc pixels.
- * This is the part of the tick mark that sticks into the plot area.
- */
- function SetYTickCrossing($which_yc)
- {
- $this->y_tick_cross = $which_yc;
- return TRUE;
- }
-
-/////////////////////////////////////////////
-//////////////////// GENERIC DRAWING
-/////////////////////////////////////////////
-
- /*
- * Fill the image background, with a tiled image file or solid color.
- */
- protected function DrawBackground()
- {
- // Don't draw this twice if drawing two plots on one image
- if (empty($this->done['background'])) {
- if (isset($this->bgimg)) { // If bgimg is defined, use it
- $this->tile_img($this->bgimg, 0, 0, $this->image_width, $this->image_height, $this->bgmode);
- } else { // Else use solid color
- ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height,
- $this->ndx_bg_color);
- }
- $this->done['background'] = TRUE;
- }
- return TRUE;
- }
-
- /*
- * Fill the plot area background, with a tiled image file or solid color.
- */
- protected function DrawPlotAreaBackground()
- {
- if (isset($this->plotbgimg)) {
- $this->tile_img($this->plotbgimg, $this->plot_area[0], $this->plot_area[1],
- $this->plot_area_width, $this->plot_area_height, $this->plotbgmode);
- } elseif ($this->draw_plot_area_background) {
- ImageFilledRectangle($this->img, $this->plot_area[0], $this->plot_area[1],
- $this->plot_area[2], $this->plot_area[3], $this->ndx_plot_bg_color);
- }
- return TRUE;
- }
-
- /*
- * Tiles an image at some given coordinates.
- * $file : Filename of the picture to be used as tile.
- * $xorig : X device coordinate of where the tile is to begin.
- * $yorig : Y device coordinate of where the tile is to begin.
- * $width : Width of the area to be tiled.
- * $height : Height of the area to be tiled.
- * $mode : Tiling mode. One of 'centeredtile', 'tile', 'scale'.
- */
- protected function tile_img($file, $xorig, $yorig, $width, $height, $mode)
- {
- $im = $this->GetImage($file, $tile_width, $tile_height);
- if (!$im)
- return FALSE; // GetImage already produced an error message.
-
- if ($mode == 'scale') {
- imagecopyresampled($this->img, $im, $xorig, $yorig, 0, 0, $width, $height,
- $tile_width, $tile_height);
- return TRUE;
- }
-
- if ($mode == 'centeredtile') {
- $x0 = - floor($tile_width/2); // Make the tile look better
- $y0 = - floor($tile_height/2);
- } else { // Accept anything else as $mode == 'tile'
- $x0 = 0;
- $y0 = 0;
- }
-
- // Draw the tile onto a temporary image first.
- $tmp = imagecreate($width, $height);
- if (! $tmp)
- return $this->PrintError('tile_img(): Could not create image resource.');
-
- for ($x = $x0; $x < $width; $x += $tile_width)
- for ($y = $y0; $y < $height; $y += $tile_height)
- imagecopy($tmp, $im, $x, $y, 0, 0, $tile_width, $tile_height);
-
- // Copy the temporary image onto the final one.
- imagecopy($this->img, $tmp, $xorig, $yorig, 0,0, $width, $height);
-
- // Free resources
- imagedestroy($tmp);
- imagedestroy($im);
-
- return TRUE;
- }
-
- /*
- * Return the image border width.
- * This is used by CalcMargins() and DrawImageBorder().
- */
- protected function GetImageBorderWidth()
- {
- if ($this->image_border_type == 'none')
- return 0; // No border
- if (!empty($this->image_border_width))
- return $this->image_border_width; // Specified border width
- if ($this->image_border_type == 'raised')
- return 2; // Default for raised border is 2 pixels.
- return 1; // Default for other border types is 1 pixel.
- }
-
- /*
- * Draws a border around the final image.
- * Note: 'plain' draws a flat border using the dark shade of the border color.
- * This probably should have been written to use the actual border color, but
- * it is too late to fix it without changing plot appearances. Therefore a
- * new type 'solid' was added to use the SetImageBorderColor color.
- */
- protected function DrawImageBorder()
- {
- // Do nothing if already drawn, or if no border has been set.
- if ($this->image_border_type == 'none' || !empty($this->done['border']))
- return TRUE;
- $width = $this->GetImageBorderWidth();
- $color1 = $this->ndx_i_border;
- $color2 = $this->ndx_i_border_dark;
- $ex = $this->image_width - 1;
- $ey = $this->image_height - 1;
- switch ($this->image_border_type) {
- case 'raised':
- // Top and left lines use border color, right and bottom use the darker shade.
- // Drawing order matters in the upper right and lower left corners.
- for ($i = 0; $i < $width; $i++, $ex--, $ey--) {
- imageline($this->img, $i, $i, $ex, $i, $color1); // Top
- imageline($this->img, $ex, $i, $ex, $ey, $color2); // Right
- imageline($this->img, $i, $i, $i, $ey, $color1); // Left
- imageline($this->img, $i, $ey, $ex, $ey, $color2); // Bottom
- }
- break;
- case 'plain': // See note above re colors
- $color1 = $color2;
- // Fall through
- case 'solid':
- for ($i = 0; $i < $width; $i++, $ex--, $ey--) {
- imagerectangle($this->img, $i, $i, $ex, $ey, $color1);
- }
- break;
- default:
- return $this->PrintError(
- "DrawImageBorder(): unknown image_border_type: '$this->image_border_type'");
- }
- $this->done['border'] = TRUE; // Border should only be drawn once per image.
- return TRUE;
- }
-
- /*
- * Draws the main title on the graph.
- * The title must not be drawn more than once (in the case of multiple plots
- * on the image), because TTF text antialiasing makes it look bad.
- */
- protected function DrawTitle()
- {
- if (!empty($this->done['title']) || $this->title_txt === '')
- return TRUE;
-
- // Center of the image:
- $xpos = $this->image_width / 2;
-
- // Place it at almost at the top
- $ypos = $this->title_offset;
-
- $this->DrawText($this->fonts['title'], 0, $xpos, $ypos,
- $this->ndx_title_color, $this->title_txt, 'center', 'top');
-
- $this->done['title'] = TRUE;
- return TRUE;
- }
-
- /*
- * Draws the X-Axis Title
- */
- protected function DrawXTitle()
- {
- if ($this->x_title_pos == 'none')
- return TRUE;
-
- // Center of the plot
- $xpos = ($this->plot_area[2] + $this->plot_area[0]) / 2;
-
- // Upper title
- if ($this->x_title_pos == 'plotup' || $this->x_title_pos == 'both') {
- $ypos = $this->plot_area[1] - $this->x_title_top_offset;
- $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_x_title_color,
- $this->x_title_txt, 'center', 'bottom');
- }
- // Lower title
- if ($this->x_title_pos == 'plotdown' || $this->x_title_pos == 'both') {
- $ypos = $this->plot_area[3] + $this->x_title_bot_offset;
- $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_x_title_color,
- $this->x_title_txt, 'center', 'top');
- }
- return TRUE;
- }
-
- /*
- * Draws the Y-Axis Title
- */
- protected function DrawYTitle()
- {
- if ($this->y_title_pos == 'none')
- return TRUE;
-
- // Center the title vertically to the plot area
- $ypos = ($this->plot_area[3] + $this->plot_area[1]) / 2;
-
- if ($this->y_title_pos == 'plotleft' || $this->y_title_pos == 'both') {
- $xpos = $this->plot_area[0] - $this->y_title_left_offset;
- $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_y_title_color,
- $this->y_title_txt, 'right', 'center');
- }
- if ($this->y_title_pos == 'plotright' || $this->y_title_pos == 'both') {
- $xpos = $this->plot_area[2] + $this->y_title_right_offset;
- $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_y_title_color,
- $this->y_title_txt, 'left', 'center');
- }
-
- return TRUE;
- }
-
- /*
- * Draw the X axis, including ticks and labels, and X (vertical) grid lines.
- */
- protected function DrawXAxis()
- {
- // Draw ticks, labels and grid
- $this->DrawXTicks();
-
- //Draw X Axis at Y = x_axis_y_pixels, unless suppressed (See SetXAxisPosition)
- if (empty($this->suppress_x_axis)) {
- ImageLine($this->img, $this->plot_area[0]+1, $this->x_axis_y_pixels,
- $this->plot_area[2]-1, $this->x_axis_y_pixels, $this->ndx_grid_color);
- }
- return TRUE;
- }
-
- /*
- * Draw the Y axis, including ticks and labels, and Y (horizontal) grid lines.
- * Horizontal grid lines overwrite horizontal axis with y=0, so call this first, then DrawXAxis()
- */
- protected function DrawYAxis()
- {
- // Draw ticks, labels and grid
- $this->DrawYTicks();
-
- // Draw Y axis at X = y_axis_x_pixels, unless suppressed (See SetYAxisPosition)
- if (empty($this->suppress_y_axis)) {
- ImageLine($this->img, $this->y_axis_x_pixels, $this->plot_area[1],
- $this->y_axis_x_pixels, $this->plot_area[3], $this->ndx_grid_color);
- }
- return TRUE;
- }
-
- /*
- * Draw one X tick mark and its tick label.
- * $which_xlab : Formatted X value for the label.
- * $which_xpix : X device coordinate for this tick mark.
- */
- protected function DrawXTick($which_xlab, $which_xpix)
- {
- // Ticks on X axis
- if ($this->x_tick_pos == 'xaxis') {
- ImageLine($this->img, $which_xpix, $this->x_axis_y_pixels - $this->x_tick_cross,
- $which_xpix, $this->x_axis_y_pixels + $this->x_tick_length, $this->ndx_tick_color);
- }
-
- // Ticks on top of the Plot Area
- if ($this->x_tick_pos == 'plotup' || $this->x_tick_pos == 'both') {
- ImageLine($this->img, $which_xpix, $this->plot_area[1] - $this->x_tick_length,
- $which_xpix, $this->plot_area[1] + $this->x_tick_cross, $this->ndx_tick_color);
- }
-
- // Ticks on bottom of Plot Area
- if ($this->x_tick_pos == 'plotdown' || $this->x_tick_pos == 'both') {
- ImageLine($this->img, $which_xpix, $this->plot_area[3] + $this->x_tick_length,
- $which_xpix, $this->plot_area[3] - $this->x_tick_cross, $this->ndx_tick_color);
- }
-
- // Label on X axis
- if ($this->x_tick_label_pos == 'xaxis') {
- $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
- $which_xpix, $this->x_axis_y_pixels + $this->x_label_axis_offset,
- $this->ndx_text_color, $which_xlab, 'center', 'top');
- }
-
- // Label on top of the Plot Area
- if ($this->x_tick_label_pos == 'plotup' || $this->x_tick_label_pos == 'both') {
- $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
- $which_xpix, $this->plot_area[1] - $this->x_label_top_offset,
- $this->ndx_text_color, $which_xlab, 'center', 'bottom');
- }
-
- // Label on bottom of the Plot Area
- if ($this->x_tick_label_pos == 'plotdown' || $this->x_tick_label_pos == 'both') {
- $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
- $which_xpix, $this->plot_area[3] + $this->x_label_bot_offset,
- $this->ndx_text_color, $which_xlab, 'center', 'top');
- }
- return TRUE;
- }
-
- /*
- * Draw one Y tick mark and its tick label. Called from DrawYTicks() and DrawXAxis()
- * $which_ylab : Formatted Y value for the label.
- * $which_ypix : Y device coordinate for this tick mark.
- */
- protected function DrawYTick($which_ylab, $which_ypix)
- {
- // Ticks on Y axis
- if ($this->y_tick_pos == 'yaxis') {
- ImageLine($this->img, $this->y_axis_x_pixels - $this->y_tick_length, $which_ypix,
- $this->y_axis_x_pixels + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
- }
-
- // Ticks to the left of the Plot Area
- if (($this->y_tick_pos == 'plotleft') || ($this->y_tick_pos == 'both') ) {
- ImageLine($this->img, $this->plot_area[0] - $this->y_tick_length, $which_ypix,
- $this->plot_area[0] + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
- }
-
- // Ticks to the right of the Plot Area
- if (($this->y_tick_pos == 'plotright') || ($this->y_tick_pos == 'both') ) {
- ImageLine($this->img, $this->plot_area[2] + $this->y_tick_length, $which_ypix,
- $this->plot_area[2] - $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
- }
-
- // Labels on Y axis
- if ($this->y_tick_label_pos == 'yaxis') {
- $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
- $this->y_axis_x_pixels - $this->y_label_axis_offset, $which_ypix,
- $this->ndx_text_color, $which_ylab, 'right', 'center');
- }
-
- // Labels to the left of the plot area
- if ($this->y_tick_label_pos == 'plotleft' || $this->y_tick_label_pos == 'both') {
- $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
- $this->plot_area[0] - $this->y_label_left_offset, $which_ypix,
- $this->ndx_text_color, $which_ylab, 'right', 'center');
- }
- // Labels to the right of the plot area
- if ($this->y_tick_label_pos == 'plotright' || $this->y_tick_label_pos == 'both') {
- $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
- $this->plot_area[2] + $this->y_label_right_offset, $which_ypix,
- $this->ndx_text_color, $which_ylab, 'left', 'center');
- }
- return TRUE;
- }
-
- /*
- * Draws Grid, Ticks and Tick Labels along X-Axis
- * Ticks and tick labels can be down of plot only, up of plot only,
- * both on up and down of plot, or crossing a user defined X-axis
- *
- * Original vertical code submitted by Marlin Viss
- */
- protected function DrawXTicks()
- {
- // Sets the line style for IMG_COLOR_STYLED lines (grid)
- if ($this->dashed_grid) {
- $this->SetDashedStyle($this->ndx_light_grid_color);
- $style = IMG_COLOR_STYLED;
- } else {
- $style = $this->ndx_light_grid_color;
- }
-
- // Calculate the tick start, end, and step:
- list($x_start, $x_end, $delta_x) = $this->CalcTicks('x');
-
- // Loop, avoiding cumulative round-off errors from $x_tmp += $delta_x
- $n = 0;
- $x_tmp = $x_start;
- while ($x_tmp <= $x_end) {
- $xlab = $this->FormatLabel('x', $x_tmp);
- $x_pixels = $this->xtr($x_tmp);
-
- // Vertical grid lines
- if ($this->draw_x_grid) {
- ImageLine($this->img, $x_pixels, $this->plot_area[1], $x_pixels, $this->plot_area[3], $style);
- }
-
- // Draw tick mark(s)
- $this->DrawXTick($xlab, $x_pixels);
-
- // Step to next X, without accumulating error
- $x_tmp = $x_start + ++$n * $delta_x;
- }
- return TRUE;
- }
-
- /*
- * Draw the grid, ticks, and tick labels along the Y axis.
- * Ticks and tick labels can be left of plot only, right of plot only,
- * both on the left and right of plot, or crossing a user defined Y-axis
- */
- protected function DrawYTicks()
- {
- // Sets the line style for IMG_COLOR_STYLED lines (grid)
- if ($this->dashed_grid) {
- $this->SetDashedStyle($this->ndx_light_grid_color);
- $style = IMG_COLOR_STYLED;
- } else {
- $style = $this->ndx_light_grid_color;
- }
-
- // Calculate the tick start, end, and step:
- list($y_start, $y_end, $delta_y) = $this->CalcTicks('y');
-
- // Loop, avoiding cumulative round-off errors from $y_tmp += $delta_y
- $n = 0;
- $y_tmp = $y_start;
- while ($y_tmp <= $y_end) {
- $ylab = $this->FormatLabel('y', $y_tmp);
- $y_pixels = $this->ytr($y_tmp);
-
- // Horizontal grid line
- if ($this->draw_y_grid) {
- ImageLine($this->img, $this->plot_area[0]+1, $y_pixels, $this->plot_area[2]-1,
- $y_pixels, $style);
- }
-
- // Draw tick mark(s)
- $this->DrawYTick($ylab, $y_pixels);
-
- // Step to next Y, without accumulating error
- $y_tmp = $y_start + ++$n * $delta_y;
- }
- return TRUE;
- }
-
- /*
- * Draw a border around the plot area. See SetPlotBorderType.
- * Note: SetPlotBorderType sets plot_border_type to an array, but
- * it won't be an array if it defaults or is set directly (backward compatibility).
- */
- protected function DrawPlotBorder()
- {
- $pbt = (array)$this->plot_border_type;
- $sides = 0; // Bitmap: 1=left 2=top 4=right 8=bottom
- $map = array('left' => 1, 'plotleft' => 1, 'right' => 4, 'plotright' => 4, 'top' => 2,
- 'bottom' => 8, 'both' => 5, 'sides' => 5, 'full' => 15, 'none' => 0);
- foreach ($pbt as $option) $sides |= $map[$option];
- if ($sides == 15) { // Border on all 4 sides
- imagerectangle($this->img, $this->plot_area[0], $this->plot_area[1],
- $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
- } else {
- if ($sides & 1) // Left
- imageline($this->img, $this->plot_area[0], $this->plot_area[1],
- $this->plot_area[0], $this->plot_area[3], $this->ndx_grid_color);
- if ($sides & 2) // Top
- imageline($this->img, $this->plot_area[0], $this->plot_area[1],
- $this->plot_area[2], $this->plot_area[1], $this->ndx_grid_color);
- if ($sides & 4) // Right
- imageline($this->img, $this->plot_area[2], $this->plot_area[1],
- $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
- if ($sides & 8) // Bottom
- imageline($this->img, $this->plot_area[0], $this->plot_area[3],
- $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
- }
- return TRUE;
- }
-
- /*
- * Draw the data value label associated with a point in the plot.
- * These are labels that show the value (dependent variable, usually Y) of the data point,
- * and are drawn within the plot area (not to be confused with axis data labels).
- *
- * $x_or_y : Specify 'x' or 'y' labels. This selects font, angle, and formatting.
- * $x_world, $y_world : World coordinates of the text (see also x/y_adjustment).
- * $text : The text to draw, after formatting with FormatLabel().
- * $halign, $valign : Selects from 9-point text alignment.
- * $x_adjustment, $y_adjustment : Text position offsets, in device coordinates.
- * $min_width, $min_height : If supplied, suppress the text if it will not fit.
- * Returns True, if the text was drawn, or False, if it will not fit.
- */
- protected function DrawDataValueLabel($x_or_y, $x_world, $y_world, $text, $halign, $valign,
- $x_adjustment=0, $y_adjustment=0, $min_width=NULL, $min_height=NULL)
- {
- if ($x_or_y == 'x') {
- $angle = $this->x_data_label_angle;
- $font = $this->fonts['x_label'];
- $formatted_text = $this->FormatLabel('xd', $text);
- } else { // Assumed 'y'
- $angle = $this->y_data_label_angle;
- $font = $this->fonts['y_label'];
- $formatted_text = $this->FormatLabel('yd', $text);
- }
- $color = $this->ndx_title_color; // Currently this is the same for X and Y labels
-
- // Check to see if the text fits in the available space, if requested.
- if (isset($min_width) || isset($min_height)) {
- list($width, $height) = $this->SizeText($font, $angle, $formatted_text);
- if ((isset($min_width) && ($min_width - $width) < 2)
- || (isset($min_height) && ($min_height - $height) < 2))
- return FALSE;
- }
-
- $this->DrawText($font, $angle, $this->xtr($x_world) + $x_adjustment,
- $this->ytr($y_world) + $y_adjustment,
- $color, $formatted_text, $halign, $valign);
- return TRUE;
- }
-
- /*
- * Draws the axis data label associated with a point in the plot.
- * This is different from x_labels drawn by DrawXTicks() and care
- * should be taken not to draw both, as they'd probably overlap.
- * Calling of this function in DrawLines(), etc is decided after x_data_label_pos value.
- * Leave the last parameter out, to avoid the drawing of vertical lines, no matter
- * what the setting is (for plots that need it, like DrawSquared())
- */
- protected function DrawXDataLabel($xlab, $xpos, $row=FALSE)
- {
- $xlab = $this->FormatLabel('xd', $xlab);
-
- // Labels below the plot area
- if ($this->x_data_label_pos == 'plotdown' || $this->x_data_label_pos == 'both')
- $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle,
- $xpos, $this->plot_area[3] + $this->x_label_bot_offset,
- $this->ndx_text_color, $xlab, 'center', 'top');
-
- // Labels above the plot area
- if ($this->x_data_label_pos == 'plotup' || $this->x_data_label_pos == 'both')
- $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle,
- $xpos, $this->plot_area[1] - $this->x_label_top_offset,
- $this->ndx_text_color, $xlab, 'center', 'bottom');
-
- // $row=0 means this is the first row. $row=FALSE means don't do any rows.
- if ($row !== FALSE && $this->draw_x_data_label_lines)
- $this->DrawXDataLine($xpos, $row);
- return TRUE;
- }
-
- /*
- * Draw a data label along the Y axis or side.
- * This is used by horizontal plots.
- */
- protected function DrawYDataLabel($ylab, $ypos)
- {
- $ylab = $this->FormatLabel('yd', $ylab);
-
- // Labels left of the plot area
- if ($this->y_data_label_pos == 'plotleft' || $this->y_data_label_pos == 'both')
- $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle,
- $this->plot_area[0] - $this->y_label_left_offset, $ypos,
- $this->ndx_text_color, $ylab, 'right', 'center');
-
- // Labels right of the plot area
- if ($this->y_data_label_pos == 'plotright' || $this->y_data_label_pos == 'both')
- $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle,
- $this->plot_area[2] + $this->y_label_right_offset, $ypos,
- $this->ndx_text_color, $ylab, 'left', 'center');
- return TRUE;
- }
-
- /*
- * Draws Vertical lines from data points up and down.
- * Which lines are drawn depends on the value of x_data_label_pos,
- * and whether this is at all done or not, on draw_x_data_label_lines
- *
- * $xpos : position in pixels of the line.
- * $row : index of the data row being drawn.
- */
- protected function DrawXDataLine($xpos, $row)
- {
- // Sets the line style for IMG_COLOR_STYLED lines (grid)
- if ($this->dashed_grid) {
- $this->SetDashedStyle($this->ndx_light_grid_color);
- $style = IMG_COLOR_STYLED;
- } else {
- $style = $this->ndx_light_grid_color;
- }
-
- if ($this->x_data_label_pos == 'both') {
- // Lines from the bottom up
- ImageLine($this->img, $xpos, $this->plot_area[3], $xpos, $this->plot_area[1], $style);
- } elseif ($this->x_data_label_pos == 'plotdown' && isset($this->data_max[$row])) {
- // Lines from the bottom of the plot up to the max Y value at this X:
- $ypos = $this->ytr($this->data_max[$row]);
- ImageLine($this->img, $xpos, $ypos, $xpos, $this->plot_area[3], $style);
- } elseif ($this->x_data_label_pos == 'plotup' && isset($this->data_min[$row])) {
- // Lines from the top of the plot down to the min Y value at this X:
- $ypos = $this->ytr($this->data_min[$row]);
- ImageLine($this->img, $xpos, $this->plot_area[1], $xpos, $ypos, $style);
- }
- return TRUE;
- }
-
- /*
- * Draws the graph legend
- * This is called by DrawGraph only if $this->legend is not empty.
- * Base code submitted by Marlin Viss
- */
- protected function DrawLegend()
- {
- $font = &$this->fonts['legend'];
-
- // Find maximum legend label line width.
- $max_width = 0;
- foreach ($this->legend as $line) {
- list($width, $unused) = $this->SizeText($font, 0, $line);
- if ($width > $max_width) $max_width = $width;
- }
-
- // Use the font parameters to size the color boxes:
- $char_w = $font['width'];
- $char_h = $font['height'];
- $line_spacing = $this->GetLineSpacing($font);
-
- // Normalize text alignment and colorbox alignment variables:
- $text_align = isset($this->legend_text_align) ? $this->legend_text_align : 'right';
- $colorbox_align = isset($this->legend_colorbox_align) ? $this->legend_colorbox_align : 'right';
-
- // Sizing parameters:
- $v_margin = $char_h/2; // Between vertical borders and labels
- $dot_height = $char_h + $line_spacing; // Height of the small colored boxes
- // Color boxes are $char_w wide, but can be adjusted using legend_colorbox_width:
- $colorbox_width = $char_w;
- if (isset($this->legend_colorbox_width))
- $colorbox_width *= $this->legend_colorbox_width;
-
- // Overall legend box width e.g.: | space colorbox space text space |
- // where each space adds $char_w, and colorbox adds $char_w * its width adjustment.
- if (($draw_colorbox = ($colorbox_align != 'none'))) {
- $width = $max_width + 3 * $char_w + $colorbox_width;
- } else {
- $width = $max_width + 2 * $char_w;
- }
-
- //////// Calculate box position
- // User-defined position specified?
- if ( !isset($this->legend_x_pos) || !isset($this->legend_y_pos)) {
- // No, use default
- $box_start_x = $this->plot_area[2] - $width - $this->safe_margin;
- $box_start_y = $this->plot_area[1] + $this->safe_margin;
- } elseif (isset($this->legend_xy_world)) {
- // User-defined position in world-coordinates (See SetLegendWorld).
- $box_start_x = $this->xtr($this->legend_x_pos);
- $box_start_y = $this->ytr($this->legend_y_pos);
- } else {
- // User-defined position in pixel coordinates.
- $box_start_x = $this->legend_x_pos;
- $box_start_y = $this->legend_y_pos;
- }
-
- // Lower right corner
- $box_end_y = $box_start_y + $dot_height*(count($this->legend)) + 2*$v_margin;
- $box_end_x = $box_start_x + $width;
-
- // Draw outer box
- ImageFilledRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y,
- $this->ndx_bg_color);
- ImageRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y,
- $this->ndx_grid_color);
-
- $color_index = 0;
- $max_color_index = count($this->ndx_data_colors) - 1;
-
- // Calculate color box and text horizontal positions.
- if (!$draw_colorbox) {
- if ($text_align == 'left')
- $x_pos = $box_start_x + $char_w;
- else
- $x_pos = $box_end_x - $char_w;
- } elseif ($colorbox_align == 'left') {
- $dot_left_x = $box_start_x + $char_w;
- $dot_right_x = $dot_left_x + $colorbox_width;
- if ($text_align == 'left')
- $x_pos = $dot_right_x + $char_w;
- else
- $x_pos = $box_end_x - $char_w;
- } else { // $colorbox_align == 'right'
- $dot_right_x = $box_end_x - $char_w;
- $dot_left_x = $dot_right_x - $colorbox_width;
- if ($text_align == 'left')
- $x_pos = $box_start_x + $char_w;
- else
- $x_pos = $dot_left_x - $char_w;
- }
-
- // Calculate starting position of first text line. The bottom of each color box
- // lines up with the bottom (baseline) of its text line.
- $y_pos = $box_start_y + $v_margin + $dot_height;
-
- foreach ($this->legend as $leg) {
- // Draw text with requested alignment:
- $this->DrawText($font, 0, $x_pos, $y_pos, $this->ndx_text_color, $leg, $text_align, 'bottom');
- if ($draw_colorbox) {
- // Draw a box in the data color
- $y1 = $y_pos - $dot_height + 1;
- $y2 = $y_pos - 1;
- ImageFilledRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2,
- $this->ndx_data_colors[$color_index]);
- // Draw a rectangle around the box
- ImageRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2,
- $this->ndx_text_color);
- }
- $y_pos += $dot_height;
-
- $color_index++;
- if ($color_index > $max_color_index)
- $color_index = 0;
- }
- return TRUE;
- }
-
-/////////////////////////////////////////////
-//////////////////// PLOT DRAWING HELPERS
-/////////////////////////////////////////////
-
- /*
- * Get data color to use for plotting.
- * $row, $idx : Index arguments for the current data point.
- * &$vars : Variable storage. Caller makes an empty array, and this function uses it.
- * &$data_color : Returned result - Color index for the data point.
- * $extra : Extra info flag passed through to data color callback.
- */
- protected function GetDataColor($row, $idx, &$vars, &$data_color, $extra = 0)
- {
- // Initialize or extract variables:
- if (empty($vars)) {
- $custom_color = (bool)$this->GetCallback('data_color');
- $num_data_colors = count($this->ndx_data_colors);
- $vars = compact('custom_color', 'num_data_colors');
- } else {
- extract($vars);
- }
-
- // Select the colors.
- if ($custom_color) {
- $col_i = $this->DoCallback('data_color', $row, $idx, $extra); // Custom color index
- $data_color = $this->ndx_data_colors[$col_i % $num_data_colors];
- } else {
- $data_color = $this->ndx_data_colors[$idx];
- }
- }
-
- /*
- * Get data color and error bar color to use for plotting.
- * $row, $idx : Index arguments for the current bar.
- * &$vars : Variable storage. Caller makes an empty array, and this function uses it.
- * &$data_color : Returned result - Color index for the data (bar fill)
- * &$error_color : Returned result - Color index for the error bars
- * $extra : Extra info flag passed through to data color callback.
- */
- protected function GetDataErrorColors($row, $idx, &$vars, &$data_color, &$error_color, $extra = 0)
- {
- // Initialize or extract variables:
- if (empty($vars)) {
- $this->NeedErrorBarColors(); // This plot needs error bar colors.
- $custom_color = (bool)$this->GetCallback('data_color');
- $num_data_colors = count($this->ndx_data_colors);
- $num_error_colors = count($this->ndx_error_bar_colors);
- $vars = compact('custom_color', 'num_data_colors', 'num_error_colors');
- } else {
- extract($vars);
- }
-
- // Select the colors.
- if ($custom_color) {
- $col_i = $this->DoCallback('data_color', $row, $idx, $extra); // Custom color index
- $data_color = $this->ndx_data_colors[$col_i % $num_data_colors];
- $error_color = $this->ndx_error_bar_colors[$col_i % $num_error_colors];
- } else {
- $data_color = $this->ndx_data_colors[$idx];
- $error_color = $this->ndx_error_bar_colors[$idx];
- }
- }
-
- /*
- * Get colors to use for a bar chart. There is a data color, and either a border color
- * or a shading color (data dark color).
- * $row, $idx : Index arguments for the current bar.
- * &$vars : Variable storage. Caller makes an empty array, and this function uses it.
- * &$data_color : Returned result - Color index for the data (bar fill).
- * &$alt_color : Returned result - Color index for the shading or outline.
- */
- protected function GetBarColors($row, $idx, &$vars, &$data_color, &$alt_color)
- {
- // Initialize or extract variables:
- if (empty($vars)) {
- if ($this->shading > 0) // This plot needs dark colors if shading is on.
- $this->NeedDataDarkColors();
- $custom_color = (bool)$this->GetCallback('data_color');
- $num_data_colors = count($this->ndx_data_colors);
- $num_border_colors = count($this->ndx_data_border_colors);
- $vars = compact('custom_color', 'num_data_colors', 'num_border_colors');
- } else {
- extract($vars);
- }
-
- // Select the colors.
- if ($custom_color) {
- $col_i = $this->DoCallback('data_color', $row, $idx); // Custom color index
- $i_data = $col_i % $num_data_colors; // Index for data colors and dark colors
- $i_border = $col_i % $num_border_colors; // Index for data borders (if used)
- } else {
- $i_data = $i_border = $idx;
- }
- $data_color = $this->ndx_data_colors[$i_data];
- if ($this->shading > 0) {
- $alt_color = $this->ndx_data_dark_colors[$i_data];
- } else {
- $alt_color = $this->ndx_data_border_colors[$i_border];
- }
- }
-
- /*
- * Draws a styled dot. Uses world coordinates.
- * The list of supported shapes can also be found in SetPointShapes().
- * All shapes are drawn using a 3x3 grid, centered on the data point.
- * The center is (x_mid, y_mid) and the corners are (x1, y1) and (x2, y2).
- * $record is the 0-based index that selects the shape and size.
- */
- protected function DrawDot($x_world, $y_world, $record, $color)
- {
- $index = $record % $this->point_counts;
- $point_size = $this->point_sizes[$index];
-
- $half_point = (int)($point_size / 2);
-
- $x_mid = $this->xtr($x_world);
- $y_mid = $this->ytr($y_world);
-
- $x1 = $x_mid - $half_point;
- $x2 = $x_mid + $half_point;
- $y1 = $y_mid - $half_point;
- $y2 = $y_mid + $half_point;
-
- switch ($this->point_shapes[$index]) {
- case 'halfline':
- ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color);
- break;
- case 'line':
- ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
- break;
- case 'plus':
- ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
- ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color);
- break;
- case 'cross':
- ImageLine($this->img, $x1, $y1, $x2, $y2, $color);
- ImageLine($this->img, $x1, $y2, $x2, $y1, $color);
- break;
- case 'circle':
- ImageArc($this->img, $x_mid, $y_mid, $point_size, $point_size, 0, 360, $color);
- break;
- case 'dot':
- ImageFilledEllipse($this->img, $x_mid, $y_mid, $point_size, $point_size, $color);
- break;
- case 'diamond':
- $arrpoints = array( $x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2);
- ImageFilledPolygon($this->img, $arrpoints, 4, $color);
- break;
- case 'triangle':
- $arrpoints = array( $x1, $y_mid, $x2, $y_mid, $x_mid, $y2);
- ImageFilledPolygon($this->img, $arrpoints, 3, $color);
- break;
- case 'trianglemid':
- $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y_mid);
- ImageFilledPolygon($this->img, $arrpoints, 3, $color);
- break;
- case 'yield':
- $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y2);
- ImageFilledPolygon($this->img, $arrpoints, 3, $color);
- break;
- case 'delta':
- $arrpoints = array( $x1, $y2, $x2, $y2, $x_mid, $y1);
- ImageFilledPolygon($this->img, $arrpoints, 3, $color);
- break;
- case 'star':
- ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
- ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color);
- ImageLine($this->img, $x1, $y1, $x2, $y2, $color);
- ImageLine($this->img, $x1, $y2, $x2, $y1, $color);
- break;
- case 'hourglass':
- $arrpoints = array( $x1, $y1, $x2, $y1, $x1, $y2, $x2, $y2);
- ImageFilledPolygon($this->img, $arrpoints, 4, $color);
- break;
- case 'bowtie':
- $arrpoints = array( $x1, $y1, $x1, $y2, $x2, $y1, $x2, $y2);
- ImageFilledPolygon($this->img, $arrpoints, 4, $color);
- break;
- case 'target':
- ImageFilledRectangle($this->img, $x1, $y1, $x_mid, $y_mid, $color);
- ImageFilledRectangle($this->img, $x_mid, $y_mid, $x2, $y2, $color);
- ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color);
- break;
- case 'box':
- ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color);
- break;
- case 'home': /* As in: "home plate" (baseball), also looks sort of like a house. */
- $arrpoints = array( $x1, $y2, $x2, $y2, $x2, $y_mid, $x_mid, $y1, $x1, $y_mid);
- ImageFilledPolygon($this->img, $arrpoints, 5, $color);
- break;
- case 'up':
- ImagePolygon($this->img, array($x_mid, $y1, $x2, $y2, $x1, $y2), 3, $color);
- break;
- case 'down':
- ImagePolygon($this->img, array($x_mid, $y2, $x1, $y1, $x2, $y1), 3, $color);
- break;
- case 'none': /* Special case, no point shape here */
- break;
- default: /* Also 'rect' */
- ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color);
- break;
- }
- return TRUE;
- }
-
- /*
- * Draw a bar (or segment of a bar), with optional shading or border.
- * This is used by the bar and stackedbar plots, vertical and horizontal.
- * $x1, $y1 : One corner of the bar.
- * $x2, $y2 : Other corner of the bar.
- * $data_color : Color index to use for the bar fill.
- * $alt_color : Color index to use for the shading (if shading is on), else for the border.
- * Note the same color is NOT used for shading and border - just the same argument.
- * See GetBarColors() for where these arguments come from.
- * $shade_top : Shade the top? (Suppressed for downward stack segments except first.)
- * $shade_side : Shade the right side? (Suppressed for leftward stack segments except first.)
- * Only one of $shade_top or $shade_side can be FALSE. Both default to TRUE.
- */
- protected function DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color,
- $shade_top = TRUE, $shade_side = TRUE)
- {
- // Sort the points so x1,y1 is upper left and x2,y2 is lower right. This
- // is needed in order to get the shading right, and imagerectangle may require it.
- if ($x1 > $x2) {
- $t = $x1; $x1 = $x2; $x2 = $t;
- }
- if ($y1 > $y2) {
- $t = $y1; $y1 = $y2; $y2 = $t;
- }
-
- // Draw the bar
- ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $data_color);
-
- // Draw a shade, or a border.
- if (($shade = $this->shading) > 0) {
- if ($shade_top && $shade_side) {
- $npts = 6;
- $pts = array($x1, $y1, $x1 + $shade, $y1 - $shade, $x2 + $shade, $y1 - $shade,
- $x2 + $shade, $y2 - $shade, $x2, $y2, $x2, $y1);
- } else {
- $npts = 4;
- if ($shade_top) { // Suppress side shading
- $pts = array($x1, $y1, $x1 + $shade, $y1 - $shade, $x2 + $shade, $y1 - $shade, $x2, $y1);
- } else { // Suppress top shading
- $pts = array($x2, $y2, $x2, $y1, $x2 + $shade, $y1 - $shade, $x2 + $shade, $y2 - $shade);
- }
- }
- ImageFilledPolygon($this->img, $pts, $npts, $alt_color);
- } else {
- ImageRectangle($this->img, $x1, $y1, $x2,$y2, $alt_color);
- }
- }
-
- /*
- * Draw an Error Bar set. Used by DrawDotsError and DrawLinesError
- */
- protected function DrawYErrorBar($x_world, $y_world, $error_height, $error_bar_type, $color)
- {
- $x1 = $this->xtr($x_world);
- $y1 = $this->ytr($y_world);
- $y2 = $this->ytr($y_world+$error_height) ;
-
- ImageSetThickness($this->img, $this->error_bar_line_width);
- ImageLine($this->img, $x1, $y1 , $x1, $y2, $color);
- if ($error_bar_type == 'tee') {
- ImageLine($this->img, $x1-$this->error_bar_size, $y2, $x1+$this->error_bar_size, $y2, $color);
- }
- ImageSetThickness($this->img, 1);
- return TRUE;
- }
-
-/////////////////////////////////////////////
-//////////////////// PLOT DRAWING
-/////////////////////////////////////////////
-
- /*
- * Draws a pie chart. Data is 'text-data', 'data-data', or 'text-data-single'.
- *
- * For text-data-single, the data array contains records with an ignored label,
- * and one Y value. Each record defines a sector of the pie, as a portion of
- * the sum of all Y values.
- *
- * For text-data and data-data, the data array contains records with an ignored label,
- * an ignored X value (for data-data only), and N (N>=1) Y values per record.
- * The pie chart will be produced with N segments. The relative size of the first
- * sector of the pie is the sum of the first Y data value in each record, etc.
- *
- * Note: With text-data-single, the data labels could be used, but are not currently.
- *
- * If there are no valid data points > 0 at all, just draw nothing. It may seem more correct to
- * raise an error, but all of the other plot types handle it this way implicitly. DrawGraph
- * checks for an empty data array, but this is different: a non-empty data array with no Y values,
- * or all Y=0.
- */
- protected function DrawPieChart()
- {
- if (!$this->CheckDataType('text-data, text-data-single, data-data'))
- return FALSE;
-
- // Allocate dark colors only if they will be used for shading.
- if ($this->shading > 0)
- $this->NeedDataDarkColors();
-
- $xpos = $this->plot_area[0] + $this->plot_area_width/2;
- $ypos = $this->plot_area[1] + $this->plot_area_height/2;
- $diameter = min($this->plot_area_width, $this->plot_area_height);
- $radius = $diameter/2;
-
- $num_slices = $this->data_columns; // See CheckDataArray which calculates this for us.
- if ($num_slices < 1) return TRUE; // Give up early if there is no data at all.
- $sumarr = array_fill(0, $num_slices, 0);
-
- if ($this->datatype_pie_single) {
- // text-data-single: One data column per row, one pie slice per row.
- for ($i = 0; $i < $num_slices; $i++) {
- // $legend[$i] = $this->data[$i][0]; // Note: Labels are not used yet
- if (is_numeric($this->data[$i][1]))
- $sumarr[$i] = abs($this->data[$i][1]);
- }
- } else {
- // text-data: Sum each column (skipping label), one pie slice per column.
- // data-data: Sum each column (skipping X value and label), one pie slice per column.
- $skip = ($this->datatype_implied) ? 1 : 2; // Leading values to skip in each row.
- for ($i = 0; $i < $this->num_data_rows; $i++) {
- for ($j = $skip; $j < $this->num_recs[$i]; $j++) {
- if (is_numeric($this->data[$i][$j]))
- $sumarr[$j-$skip] += abs($this->data[$i][$j]);
- }
- }
- }
-
- $total = array_sum($sumarr);
-
- if ($total == 0) {
- // There are either no valid data points, or all are 0.
- // See top comment about why not to make this an error.
- return TRUE;
- }
-
- if ($this->shading) {
- $diam2 = $diameter / 2;
- } else {
- $diam2 = $diameter;
- }
- $max_data_colors = count($this->ndx_data_colors);
-
- // Use the Y label format precision, with default value:
- if (isset($this->label_format['y']['precision']))
- $precision = $this->label_format['y']['precision'];
- else
- $precision = 1;
-
- for ($h = $this->shading; $h >= 0; $h--) {
- $color_index = 0;
- $start_angle = 0;
- $end_angle = 0;
- for ($j = 0; $j < $num_slices; $j++) {
- $val = $sumarr[$j];
-
- // For shaded pies: the last one (at the top of the "stack") has a brighter color:
- if ($h == 0)
- $slicecol = $this->ndx_data_colors[$color_index];
- else
- $slicecol = $this->ndx_data_dark_colors[$color_index];
-
- $label_txt = $this->number_format(($val / $total * 100), $precision) . '%';
- $val = 360 * ($val / $total);
-
- // NOTE that imagefilledarc measures angles CLOCKWISE (go figure why),
- // so the pie chart would start clockwise from 3 o'clock, would it not be
- // for the reversal of start and end angles in imagefilledarc()
- // Also note ImageFilledArc only takes angles in integer degrees, and if the
- // the start and end angles match then you get a full circle not a zero-width
- // pie. This is bad. So skip any zero-size wedge. On the other hand, we cannot
- // let cumulative error from rounding to integer result in missing wedges. So
- // keep the running total as a float, and round the angles. It should not
- // be necessary to check that the last wedge ends at 360 degrees.
- $start_angle = $end_angle;
- $end_angle += $val;
- // This method of conversion to integer - truncate after reversing it - was
- // chosen to match the implicit method of PHPlot<=5.0.4 to get the same slices.
- $arc_start_angle = (int)(360 - $start_angle);
- $arc_end_angle = (int)(360 - $end_angle);
-
- if ($arc_start_angle > $arc_end_angle) {
- $mid_angle = deg2rad($end_angle - ($val / 2));
-
- // Draw the slice
- ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
- $arc_end_angle, $arc_start_angle,
- $slicecol, IMG_ARC_PIE);
-
- // Draw the labels only once
- if ($h == 0) {
- // Draw the outline
- if (! $this->shading)
- ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
- $arc_end_angle, $arc_start_angle, $this->ndx_grid_color,
- IMG_ARC_PIE | IMG_ARC_EDGED |IMG_ARC_NOFILL);
-
- // The '* 1.2' trick is to get labels out of the pie chart so there are more
- // chances they can be seen in small sectors.
- $label_x = $xpos + ($diameter * 1.2 * cos($mid_angle)) * $this->label_scale_position;
- $label_y = $ypos+$h - ($diam2 * 1.2 * sin($mid_angle)) * $this->label_scale_position;
-
- $this->DrawText($this->fonts['generic'], 0, $label_x, $label_y, $this->ndx_grid_color,
- $label_txt, 'center', 'center');
- }
- }
- if (++$color_index >= $max_data_colors)
- $color_index = 0;
- } // end for
- } // end for
- return TRUE;
- }
-
- /*
- * Draw the points and errors bars for an error plot of types points and linepoints
- * Supports only data-data-error format, with each row of the form
- * array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...)
- * This is called from DrawDots, with data type already checked.
- * $paired is true for linepoints error plots, to make sure elements are
- * only drawn once. If true, data labels are drawn by DrawLinesError, and error
- * bars are drawn by DrawDotsError. (This choice is for backwards compatibility.)
- */
- protected function DrawDotsError($paired = FALSE)
- {
- // Adjust the point shapes and point sizes arrays:
- $this->CheckPointParams();
-
- $gcvars = array(); // For GetDataErrorColors, which initializes and uses this.
- // Special flag for data color callback to indicate the 'points' part of 'linepoints':
- $alt_flag = $paired ? 1 : 0;
-
- for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (title)
-
- $x_now = $this->data[$row][$record++]; // Read it, advance record index
-
- $x_now_pixels = $this->xtr($x_now); // Absolute coordinates.
-
- // Draw X Data labels?
- if ($this->x_data_label_pos != 'none' && !$paired)
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
- // Now go for Y, E+, E-
- for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
- if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
-
- // Select the colors:
- $this->GetDataErrorColors($row, $idx, $gcvars, $data_color, $error_color, $alt_flag);
-
- // Y:
- $y_now = $this->data[$row][$record++];
- $this->DrawDot($x_now, $y_now, $idx, $data_color);
-
- // Error +
- $val = $this->data[$row][$record++];
- $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape, $error_color);
- // Error -
- $val = $this->data[$row][$record++];
- $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape, $error_color);
- } else {
- $record += 3; // Skip over missing Y and its error values
- }
- }
- }
- return TRUE;
- }
-
- /*
- * Draw a points plot, or the points for a linepoints plot
- * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
- * Points plot with error bars (data-data-error format) is redirected to DrawDotsError.
- * $paired is true for linepoints plots, to make sure elements are only drawn once.
- */
- protected function DrawDots($paired = FALSE)
- {
- if (!$this->CheckDataType('text-data, data-data, data-data-error'))
- return FALSE;
- if ($this->datatype_error_bars)
- return $this->DrawDotsError($paired); // Redirect for points+errorbars plot
-
- // Adjust the point shapes and point sizes arrays:
- $this->CheckPointParams();
-
- $gcvars = array(); // For GetDataColor, which initializes and uses this.
- // Special flag for data color callback to indicate the 'points' part of 'linepoints':
- $alt_flag = $paired ? 1 : 0;
-
- // Data Value Labels? (Skip if doing the points from a linepoints plot)
- $do_dvls = !$paired && $this->CheckDataValueLabels($this->y_data_label_pos,
- $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align);
-
- for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
- $rec = 1; // Skip record #0 (data label)
-
- if ($this->datatype_implied) // Implied X values?
- $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
- else
- $x_now = $this->data[$row][$rec++]; // Read it, advance record index
-
- $x_now_pixels = $this->xtr($x_now);
-
- // Draw X Data labels?
- if (!$paired && $this->x_data_label_pos != 'none')
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
- // Proceed with Y values
- for ($idx = 0;$rec < $this->num_recs[$row]; $rec++, $idx++) {
- if (is_numeric($this->data[$row][$rec])) { // Allow for missing Y data
- $y_now = (double)$this->data[$row][$rec];
-
- // Select the color:
- $this->GetDataColor($row, $idx, $gcvars, $data_color, $alt_flag);
- // Draw the marker:
- $this->DrawDot($x_now, $y_now, $idx, $data_color);
-
- // Draw data value labels?
- if ($do_dvls) {
- $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align,
- $dvl_x_off, $dvl_y_off);
- }
- }
- }
- }
- return TRUE;
- }
-
- /*
- * Draw a Thin Bar Line plot, also known as an Impulse plot.
- * A clean, fast routine for when you just want charts like stock volume charts.
- * Supports data-data and text-data formats for vertical plots,
- * and data-data-yx and text-data-yx for horizontal plots.
- * Note that although this plot type supports multiple data sets, it rarely makes
- * sense to have more than 1, because the lines will overlay.
- * This one function does both vertical and horizontal plots. "iv" is used for the
- * independent variable (X for vertical plots, Y for horizontal) and "dv" is used
- * for the dependent variable (Y for vertical plots, X for horizontal).
- */
- protected function DrawThinBarLines()
- {
- if (!$this->CheckDataType('text-data, data-data, text-data-yx, data-data-yx'))
- return FALSE;
-
- $gcvars = array(); // For GetDataColor, which initializes and uses this.
-
- for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
- $rec = 1; // Skip record #0 (data label)
-
- if ($this->datatype_implied) // Implied independent variable values?
- $iv_now = 0.5 + $cnt++; // Place text-data at 0.5, 1.5, 2.5, etc...
- else
- $iv_now = $this->data[$row][$rec++]; // Read it, advance record index
-
- if ($this->datatype_swapped_xy) {
- $y_now_pixels = $this->ytr($iv_now);
- // Draw Y Data labels?
- if ($this->y_data_label_pos != 'none')
- $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels);
- } else {
- $x_now_pixels = $this->xtr($iv_now);
- // Draw X Data labels?
- if ($this->x_data_label_pos != 'none')
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
- }
-
- // Proceed with dependent values
- for ($idx = 0; $rec < $this->num_recs[$row]; $rec++, $idx++) {
- if (is_numeric($this->data[$row][$rec])) { // Allow for missing data
- $dv = $this->data[$row][$rec];
- ImageSetThickness($this->img, $this->line_widths[$idx]);
-
- // Select the color:
- $this->GetDataColor($row, $idx, $gcvars, $data_color);
-
- if ($this->datatype_swapped_xy) {
- // Draw a line from user defined y axis position right (or left) to xtr($dv)
- ImageLine($this->img, $this->y_axis_x_pixels, $y_now_pixels,
- $this->xtr($dv), $y_now_pixels, $data_color);
- } else {
- // Draw a line from user defined x axis position up (or down) to ytr($dv)
- ImageLine($this->img, $x_now_pixels, $this->x_axis_y_pixels,
- $x_now_pixels, $this->ytr($dv), $data_color);
- }
- }
- }
- }
-
- ImageSetThickness($this->img, 1);
- return TRUE;
- }
-
- /*
- * Draw an 'area' or 'stacked area' plot.
- * Both of these fill the area between lines, but in the stacked area graph the Y values
- * are accumulated for each X, same as stacked bars. In the regular area graph, the areas
- * are filled in order from the X axis up to each Y (so the Y values for each X need to be
- * in decreasing order in this case).
- * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
- * Notes:
- * All Y values must be >= 0. (If any Y<0 the absolute value is used.)
- * Missing data points are NOT handled. (They are counted as 0.)
- * All rows must have the same number of Y points, or an error image will be produced.
- */
- protected function DrawArea($do_stacked = FALSE)
- {
- if (!$this->CheckDataType('text-data, data-data'))
- return FALSE;
-
- $n = $this->num_data_rows; // Number of X values
-
- // These arrays store the device X and Y coordinates for all lines:
- $xd = array();
- $yd = array();
-
- // Make sure each row has the same number of values. Note records_per_group is max(num_recs).
- if ($this->records_per_group != min($this->num_recs)) {
- return $this->PrintError("DrawArea(): Data array must contain the same number"
- . " of Y values for each X");
- }
-
- // Calculate the Y value for each X, and store the device
- // coordinates into the xd and yd arrays.
- // For stacked area plots, the Y values accumulate.
- for ($row = 0; $row < $n; $row++) {
- $rec = 1; // Skip record #0 (data label)
-
- if ($this->datatype_implied) // Implied X values?
- $x_now = 0.5 + $row; // Place text-data at X = 0.5, 1.5, 2.5, etc...
- else
- $x_now = $this->data[$row][$rec++]; // Read it, advance record index
-
- $x_now_pixels = $this->xtr($x_now);
-
- if ($this->x_data_label_pos != 'none') // Draw X Data labels?
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
-
- // Store the X value.
- // There is an artificial Y value at the axis. For 'area' it goes
- // at the end; for stackedarea it goes before the start.
- $xd[$row] = $x_now_pixels;
- $yd[$row] = array();
- if ($do_stacked)
- $yd[$row][] = $this->x_axis_y_pixels;
-
- // Store the Y values for this X.
- // All Y values are clipped to the x axis which should be zero but can be moved.
- $y = 0;
- while ($rec < $this->records_per_group) {
- if (is_numeric($this->data[$row][$rec])) { // Treat missing values as 0.
- $y += abs($this->data[$row][$rec]);
- }
- $yd[$row][] = $this->ytr(max($this->x_axis_position, $y));
- if (!$do_stacked) $y = 0;
- $rec++;
- }
-
- if (!$do_stacked)
- $yd[$row][] = $this->x_axis_y_pixels;
- }
-
- // Now draw the filled polygons.
- // Note data_columns is the number of Y points (columns excluding label and X), and the
- // number of entries in the yd[] arrays is data_columns+1.
- $prev_row = 0;
- for ($row = 1; $row <= $this->data_columns; $row++) { // 1 extra for X axis artificial row
- $pts = array();
- // Previous data set forms top (for area) or bottom (for stackedarea):
- for ($j = 0; $j < $n; $j++) {
- $pts[] = $xd[$j];
- $pts[] = $yd[$j][$prev_row];
- }
- // Current data set forms bottom (for area) or top (for stackedarea):
- for ($j = $n- 1; $j >= 0; $j--) {
- $pts[] = $xd[$j];
- $pts[] = $yd[$j][$row];
- }
- // Draw it:
- ImageFilledPolygon($this->img, $pts, $n * 2, $this->ndx_data_colors[$prev_row]);
-
- $prev_row = $row;
- }
- return TRUE;
- }
-
- /*
- * Draw a line plot, or the lines part of a linepoints plot
- * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
- * Line plot with error bars (data-data-error format) is redirected to DrawLinesError.
- * $paired is true for linepoints plots, to make sure elements are only drawn once.
- */
- protected function DrawLines($paired = FALSE)
- {
- if (!$this->CheckDataType('text-data, data-data, data-data-error'))
- return FALSE;
- if ($this->datatype_error_bars)
- return $this->DrawLinesError($paired); // Redirect for lines+errorbar plot
-
- // Flag array telling if the current point is valid, one element per plot line.
- // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point.
- $start_lines = array_fill(0, $this->data_columns, FALSE);
-
- $gcvars = array(); // For GetDataColor, which initializes and uses this.
-
- // Data Value Labels?
- $do_dvls = $this->CheckDataValueLabels($this->y_data_label_pos,
- $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align);
-
- for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- if ($this->datatype_implied) // Implied X values?
- $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
- else
- $x_now = $this->data[$row][$record++]; // Read it, advance record index
-
- $x_now_pixels = $this->xtr($x_now); // Absolute coordinates
-
- if ($this->x_data_label_pos != 'none') // Draw X Data labels?
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
- for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
- if (($line_style = $this->line_styles[$idx]) == 'none')
- continue; //Allow suppressing entire line, useful with linepoints
- if (is_numeric($this->data[$row][$record])) { //Allow for missing Y data
- $y_now = (double)$this->data[$row][$record];
- $y_now_pixels = $this->ytr($y_now);
-
- if ($start_lines[$idx]) {
- // Set line width, revert it to normal at the end
- ImageSetThickness($this->img, $this->line_widths[$idx]);
-
- // Select the color:
- $this->GetDataColor($row, $idx, $gcvars, $data_color);
-
- if ($line_style == 'dashed') {
- $this->SetDashedStyle($data_color);
- $data_color = IMG_COLOR_STYLED;
- }
- ImageLine($this->img, $x_now_pixels, $y_now_pixels,
- $lastx[$idx], $lasty[$idx], $data_color);
- }
-
- // Draw data value labels?
- if ($do_dvls) {
- $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align,
- $dvl_x_off, $dvl_y_off);
- }
-
- $lasty[$idx] = $y_now_pixels;
- $lastx[$idx] = $x_now_pixels;
- $start_lines[$idx] = TRUE;
- } elseif ($this->draw_broken_lines) { // Y data missing, leave a gap.
- $start_lines[$idx] = FALSE;
- }
- } // end for
- } // end for
-
- ImageSetThickness($this->img, 1); // Revert to original state for lines to be drawn later.
- return TRUE;
- }
-
- /*
- * Draw lines with error bars for an error plot of types lines and linepoints
- * Supports only data-data-error format, with each row of the form
- * array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...)
- * This is called from DrawLines, with data type already checked.
- * $paired is true for linepoints error plots, to make sure elements are
- * only drawn once. If true, data labels are drawn by DrawLinesError, and error
- * bars are drawn by DrawDotsError. (This choice is for backwards compatibility.)
- */
- protected function DrawLinesError($paired = FALSE)
- {
- $start_lines = array_fill(0, $this->data_columns, FALSE);
-
- $gcvars = array(); // For GetDataErrorColors, which initializes and uses this.
-
- for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- $x_now = $this->data[$row][$record++]; // Read X value, advance record index
-
- $x_now_pixels = $this->xtr($x_now); // Absolute coordinates.
-
- if ($this->x_data_label_pos != 'none') // Draw X Data labels?
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
- // Now go for Y, E+, E-
- for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
- if (($line_style = $this->line_styles[$idx]) == 'none')
- continue; //Allow suppressing entire line, useful with linepoints
- if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
-
- // Select the colors:
- $this->GetDataErrorColors($row, $idx, $gcvars, $data_color, $error_color);
-
- // Y
- $y_now = $this->data[$row][$record++];
- $y_now_pixels = $this->ytr($y_now);
-
- if ($start_lines[$idx]) {
- ImageSetThickness($this->img, $this->line_widths[$idx]);
-
- if ($line_style == 'dashed') {
- $this->SetDashedStyle($data_color);
- $data_color = IMG_COLOR_STYLED;
- }
- ImageLine($this->img, $x_now_pixels, $y_now_pixels,
- $lastx[$idx], $lasty[$idx], $data_color);
- }
-
- if ($paired) {
- $record += 2; // Skip error bars - done in the 'points' part of 'linepoints'.
- } else {
- // Error+
- $val = $this->data[$row][$record++];
- $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape, $error_color);
-
- // Error-
- $val = $this->data[$row][$record++];
- $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape, $error_color);
- }
-
- // Update indexes:
- $start_lines[$idx] = TRUE; // Tells us if we already drew the first column of points,
- // thus having $lastx and $lasty ready for the next column.
- $lastx[$idx] = $x_now_pixels;
- $lasty[$idx] = $y_now_pixels;
-
- } else {
- $record += 3; // Skip over missing Y and its error values
- if ($this->draw_broken_lines) {
- $start_lines[$idx] = FALSE;
- }
- }
- } // end for
- } // end for
-
- ImageSetThickness($this->img, 1); // Revert to original state for lines to be drawn later.
- return TRUE;
- }
-
- /*
- * Draw a Lines+Points plot (linepoints).
- * This just uses DrawLines and DrawDots. They handle the error-bar case themselves.
- */
- protected function DrawLinePoints()
- {
- // This check is redundant, as DrawLines and DrawDots do it, but left here as insurance.
- if (!$this->CheckDataType('text-data, data-data, data-data-error'))
- return FALSE;
- $this->DrawLines(TRUE);
- $this->DrawDots(TRUE);
- return TRUE;
- }
-
- /*
- * Draw a Squared Line plot.
- * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
- * This is based on DrawLines(), with one more line drawn for each point.
- */
- protected function DrawSquared()
- {
- if (!$this->CheckDataType('text-data, data-data'))
- return FALSE;
-
- // Flag array telling if the current point is valid, one element per plot line.
- // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point.
- $start_lines = array_fill(0, $this->data_columns, FALSE);
-
- $gcvars = array(); // For GetDataColor, which initializes and uses this.
-
- // Data Value Labels?
- $do_dvls = $this->CheckDataValueLabels($this->y_data_label_pos,
- $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align);
-
- for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- if ($this->datatype_implied) // Implied X values?
- $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
- else
- $x_now = $this->data[$row][$record++]; // Read it, advance record index
-
- $x_now_pixels = $this->xtr($x_now); // Absolute coordinates
-
- if ($this->x_data_label_pos != 'none') // Draw X Data labels?
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); // notice there is no last param.
-
- // Draw Lines
- for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
- if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
- $y_now = (double)$this->data[$row][$record];
- $y_now_pixels = $this->ytr($y_now);
-
- if ($start_lines[$idx]) {
- // Set line width, revert it to normal at the end
- ImageSetThickness($this->img, $this->line_widths[$idx]);
-
- // Select the color:
- $this->GetDataColor($row, $idx, $gcvars, $data_color);
-
- if ($this->line_styles[$idx] == 'dashed') {
- $this->SetDashedStyle($data_color);
- $data_color = IMG_COLOR_STYLED;
- }
- ImageLine($this->img, $lastx[$idx], $lasty[$idx],
- $x_now_pixels, $lasty[$idx], $data_color);
- ImageLine($this->img, $x_now_pixels, $lasty[$idx],
- $x_now_pixels, $y_now_pixels, $data_color);
- }
-
- // Draw data value labels?
- if ($do_dvls) {
- $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align,
- $dvl_x_off, $dvl_y_off);
- }
-
- $lastx[$idx] = $x_now_pixels;
- $lasty[$idx] = $y_now_pixels;
- $start_lines[$idx] = TRUE;
- } elseif ($this->draw_broken_lines) { // Y data missing, leave a gap.
- $start_lines[$idx] = FALSE;
- }
- }
- } // end while
-
- ImageSetThickness($this->img, 1);
- return TRUE;
- }
-
- /*
- * Draw a Bar chart
- * Supports text-data format, with each row in the form array(label, y1, y2, y3, ...)
- * Horizontal bars (text-data-yx format) are sent to DrawHorizBars() instead.
- */
- protected function DrawBars()
- {
- if (!$this->CheckDataType('text-data, text-data-yx'))
- return FALSE;
- if ($this->datatype_swapped_xy)
- return $this->DrawHorizBars();
- $this->CalcBarWidths(FALSE, TRUE); // Calculate bar widths for unstacked, vertical
-
- // This is the X offset from the bar group's label center point to the left side of the first bar
- // in the group. See also CalcBarWidths above.
- $x_first_bar = ($this->data_columns * $this->record_bar_width) / 2 - $this->bar_adjust_gap;
-
- $gcvars = array(); // For GetBarColors, which initializes and uses this.
-
- for ($row = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- $x_now_pixels = $this->xtr(0.5 + $row); // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
- if ($this->x_data_label_pos != 'none') // Draw X Data labels?
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
-
- // Lower left X of first bar in the group:
- $x1 = $x_now_pixels - $x_first_bar;
-
- // Draw the bars in the group:
- for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
- if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
- $y = $this->data[$row][$record];
- $x2 = $x1 + $this->actual_bar_width;
-
- if (($upgoing_bar = $y >= $this->x_axis_position)) {
- $y1 = $this->ytr($y);
- $y2 = $this->x_axis_y_pixels;
- } else {
- $y1 = $this->x_axis_y_pixels;
- $y2 = $this->ytr($y);
- }
-
- // Select the colors:
- $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
-
- // Draw the bar, and the shade or border:
- $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color);
-
- // Draw optional data labels above the bars (or below, for negative values).
- if ( $this->y_data_label_pos == 'plotin') {
- if ($upgoing_bar) {
- $v_align = 'bottom';
- $y_offset = -5 - $this->shading;
- } else {
- $v_align = 'top';
- $y_offset = 2;
- }
- $this->DrawDataValueLabel('y', $row+0.5, $y, $y, 'center', $v_align,
- ($idx + 0.5) * $this->record_bar_width - $x_first_bar, $y_offset);
- }
- }
- // Step to next bar in group:
- $x1 += $this->record_bar_width;
- } // end for
- } // end for
- return TRUE;
- }
-
- /*
- * Draw a Horizontal Bar chart
- * Supports only text-data-yx format, with each row in the form array(label, x1, x2, x3, ...)
- * Note that the data values are X not Y, and the bars are drawn horizontally.
- * This is called from DrawBars, which has already checked the data type.
- */
- protected function DrawHorizBars()
- {
- $this->CalcBarWidths(FALSE, FALSE); // Calculate bar widths for unstacked, vertical
-
- // This is the Y offset from the bar group's label center point to the bottom of the first bar
- // in the group. See also CalcBarWidths above.
- $y_first_bar = ($this->data_columns * $this->record_bar_width) / 2 - $this->bar_adjust_gap;
-
- $gcvars = array(); // For GetBarColors, which initializes and uses this.
-
- for ($row = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- $y_now_pixels = $this->ytr(0.5 + $row); // Place bars at Y=0.5, 1.5, 2.5, etc...
-
- if ($this->y_data_label_pos != 'none') // Draw Y Data Labels?
- $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels);
-
- // Lower left Y of first bar in the group:
- $y1 = $y_now_pixels + $y_first_bar;
-
- // Draw the bars in the group:
- for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
- if (is_numeric($this->data[$row][$record])) { // Allow for missing X data
- $x = $this->data[$row][$record];
- $y2 = $y1 - $this->actual_bar_width;
-
- if (($rightwards_bar = $x >= $this->y_axis_position)) {
- $x1 = $this->xtr($x);
- $x2 = $this->y_axis_x_pixels;
- } else {
- $x1 = $this->y_axis_x_pixels;
- $x2 = $this->xtr($x);
- }
-
- // Select the colors:
- $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
-
- // Draw the bar, and the shade or border:
- $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color);
-
- // Draw optional data labels to the right of the bars (or left, if the bar
- // goes left of the Y axis line).
- if ($this->x_data_label_pos == 'plotin') {
- if ($rightwards_bar) {
- $h_align = 'left';
- $x_offset = 5 + $this->shading;
- } else {
- $h_align = 'right';
- $x_offset = -2;
- }
- $this->DrawDataValueLabel('x', $x, $row+0.5, $x, $h_align, 'center',
- $x_offset, $y_first_bar - ($idx + 0.5) * $this->record_bar_width);
- }
-
- }
- // Step to next bar in group:
- $y1 -= $this->record_bar_width;
- } // end for
- } // end for
-
- return TRUE;
- }
-
- /*
- * Draw a Stacked Bar chart
- * Supports text-data format, with each row in the form array(label, y1, y2, y3, ...)
- * Horizontal stacked bars (text-data-yx format) are sent to DrawHorizStackedBars() instead.
- * Original stacked bars idea by Laurent Kruk < lolok at users.sourceforge.net >
- */
- protected function DrawStackedBars()
- {
- if (!$this->CheckDataType('text-data, text-data-yx'))
- return FALSE;
- if ($this->datatype_swapped_xy)
- return $this->DrawHorizStackedBars();
- $this->CalcBarWidths(TRUE, TRUE); // Calculate bar widths for stacked, vertical
-
- // This is the X offset from the bar's label center point to the left side of the bar.
- $x_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap;
-
- $gcvars = array(); // For GetBarColors, which initializes and uses this.
-
- // Determine if any data labels are on:
- $data_labels_within = ($this->y_data_label_pos == 'plotstack');
- $data_labels_end = $data_labels_within || ($this->y_data_label_pos == 'plotin');
- $data_label_y_offset = -5 - $this->shading; // For upward labels only.
-
- for ($row = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- $x_now_pixels = $this->xtr(0.5 + $row); // Place text-data at X = 0.5, 1.5, 2.5, etc...
-
- if ($this->x_data_label_pos != 'none') // Draw X Data labels?
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
-
- // Lower left and lower right X of the bars in this stack:
- $x1 = $x_now_pixels - $x_first_bar;
- $x2 = $x1 + $this->actual_bar_width;
-
- // Draw the bar segments in this stack.
- $wy1 = 0; // World coordinates Y1, current sum of values
- $wy2 = $this->x_axis_position; // World coordinates Y2, last drawn value
- $first = TRUE;
-
- for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
-
- // Skip missing Y values, and ignore Y=0 values.
- if (is_numeric($this->data[$row][$record])
- && ($this_y = $this->data[$row][$record]) != 0) {
-
- // First non-zero value sets the direction, $upward. Note this compares to 0,
- // not the axis position. Segments are based at 0 but clip to the axis.
- if ($first)
- $upward = ($this_y > 0);
-
- $wy1 += $this_y; // Keep the running total for this bar stack
-
- // Draw nothing if this segment would not increase the bar height.
- // Upward bars: draw if wy1>wy2. Downward bars: Draw if wy1<wy2.
- if (($wy1 < $wy2) XOR $upward) {
-
- $y1 = $this->ytr($wy1); // Convert to device coordinates. $y1 is outermost value.
- $y2 = $this->ytr($wy2); // $y2 is innermost (closest to axis).
-
- // Select the colors:
- $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
-
- // Draw the bar, and the shade or border:
- $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color,
- // Only shade the top for upward bars, or the first segment of downward bars:
- $upward || $first, TRUE);
-
- // Draw optional data label for this bar segment just inside the end.
- // Text value is the current Y, but position is the cumulative Y.
- // The label is only drawn if it fits in the segment height |y2-y1|.
- if ($data_labels_within) {
- $this->DrawDataValueLabel('y', $row+0.5, $wy1, $this_y,
- 'center', $upward ? 'top' : 'bottom',
- 0, $upward ? 3 : -3, NULL, abs($y1 - $y2));
- }
- // Mark the new end of the bar, conditional on segment height > 0.
- $wy2 = $wy1;
- }
- $first = FALSE;
- }
- } // end for
-
- // Draw optional data label above the bar with the total value.
- // Value is wy1 (total value), but position is wy2 (end of the bar stack).
- // These differ only with wrong-direction segments, or a stack completely clipped by the axis.
- if ($data_labels_end) {
- $this->DrawDataValueLabel('y', $row+0.5, $wy2, $wy1, 'center', $upward ? 'bottom' : 'top',
- 0, $upward ? $data_label_y_offset : 5);
- }
- } // end for
- return TRUE;
- }
-
- /*
- * Draw a Horizontal Stacked Bar chart
- * Supports only text-data-yx format, with each row in the form array(label, x1, x2, x3, ...)
- * Note that the data values are X not Y, and the bars are drawn horizontally.
- * This is called from DrawStackedBars, which has already checked the data type.
- */
- protected function DrawHorizStackedBars()
- {
- $this->CalcBarWidths(TRUE, FALSE); // Calculate bar widths for stacked, horizontal
-
- // This is the Y offset from the bar's label center point to the bottom of the bar
- $y_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap;
-
- $gcvars = array(); // For GetBarColors, which initializes and uses this.
-
- // Determine if any data labels are on:
- $data_labels_within = ($this->x_data_label_pos == 'plotstack');
- $data_labels_end = $data_labels_within || ($this->x_data_label_pos == 'plotin');
- $data_label_x_offset = 5 + $this->shading; // For rightward labels only
-
- for ($row = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- $y_now_pixels = $this->ytr(0.5 + $row); // Place bars at Y=0.5, 1.5, 2.5, etc...
-
- if ($this->y_data_label_pos != 'none') // Draw Y Data labels?
- $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels);
-
- // Lower left and upper left Y of the bars in this stack:
- $y1 = $y_now_pixels + $y_first_bar;
- $y2 = $y1 - $this->actual_bar_width;
-
- // Draw the bar segments in this stack:
- $wx1 = 0; // World coordinates X1, current sum of values
- $wx2 = $this->y_axis_position; // World coordinates X2, last drawn value
- $first = TRUE;
-
- for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
-
- // Skip missing X values, and ignore X<0 values.
- if (is_numeric($this->data[$row][$record])
- && ($this_x = $this->data[$row][$record]) != 0) {
-
- // First non-zero value sets the direction, $rightward. Note this compares to 0,
- // not the axis position. Segments are based at 0 but clip to the axis.
- if ($first)
- $rightward = ($this_x > 0);
-
- $wx1 += $this_x; // Keep the running total for this bar stack
-
- // Draw nothing if this segment would not increase the bar length.
- // Rightward bars: draw if wx1>wx2. Leftward bars: Draw if wx1<wx2.
- if (($wx1 < $wx2) XOR $rightward) {
-
- $x1 = $this->xtr($wx1); // Convert to device coordinates. $x1 is outermost value.
- $x2 = $this->xtr($wx2); // $x2 is innermost (closest to axis).
-
- // Select the colors:
- $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
-
- // Draw the bar, and the shade or border:
- $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color,
- // Only shade the side for rightward bars, or the first segment of leftward bars:
- TRUE, $rightward || $first);
- // Draw optional data label for this bar segment just inside the end.
- // Text value is the current X, but position is the cumulative X.
- // The label is only drawn if it fits in the segment width |x2-x1|.
- if ($data_labels_within) {
- $this->DrawDataValueLabel('x', $wx1, $row+0.5, $this_x,
- $rightward ? 'right' : 'left', 'center',
- $rightward ? -3 : 3, 0, abs($x1 - $x2), NULL);
- }
- // Mark the new end of the bar, conditional on segment width > 0.
- $wx2 = $wx1;
- }
- $first = FALSE;
- }
- } // end for
-
- // Draw optional data label right of the bar with the total value.
- // Value is wx1 (total value), but position is wx2 (end of the bar stack).
- // These differ only with wrong-direction segments, or a stack completely clipped by the axis.
- if ($data_labels_end) {
- $this->DrawDataValueLabel('x', $wx2, $row+0.5, $wx1, $rightward ? 'left' : 'right', 'center',
- $rightward ? $data_label_x_offset : -5, 0);
- }
- } // end for
- return TRUE;
- }
-
- /*
- * Draw a financial "Open/High/Low/Close" (OHLC) plot, including candlestick plots.
- * Data format can be text-data (label, Yo, Yh, Yl, Yc) or data-data (label, X, Yo, Yh, Yl, Yc).
- * Yo="Opening price", Yc="Closing price", Yl="Low price", Yh="High price".
- * Each row must have exactly 4 Y values. No multiple data sets, no missing values.
- * There are 3 subtypes, selected by $draw_candles and $always_fill.
- * $draw_candles $always_fill Description:
- * FALSE N/A A basic OHLC chart with a vertical line for price range, horizontal
- * tick marks on left for opening price and right for closing price.
- * TRUE FALSE A candlestick plot with filled body indicating close down, outline
- * for closing up, and vertical wicks for low and high prices.
- * TRUE TRUE A candlestick plot where the candle bodies are always filled.
- * These map to 3 plot types per the $plots[] array.
- *
- * Data color usage: If closes down: If closes up or unchanged:
- * Candlestick body, ohlc range line: color 0 color 1
- * Candlestick wicks, ohlc tick marks: color 2 color 3
- * There are three member variables that control the width (candlestick body or tick marks):
- * ohlc_max_width, ohlc_min_width, ohlc_frac_width
- * (There is no API to change them at this time.)
- */
- protected function DrawOHLC($draw_candles, $always_fill = FALSE)
- {
- if (!$this->CheckDataType('text-data, data-data'))
- return FALSE;
-
- // Assign name of GD function to draw candlestick bodies for stocks that close up.
- $draw_body_close_up = $always_fill ? 'imagefilledrectangle' : 'imagerectangle';
-
- // These 3 variables control the calculation of the half-width of the candle body, or length of
- // the tick marks. This is scaled based on the plot density, but within tight limits.
- $min_width = isset($this->ohlc_min_width) ? $this->ohlc_min_width : 2;
- $max_width = isset($this->ohlc_max_width) ? $this->ohlc_max_width : 8;
- $width_factor = isset($this->ohlc_frac_width) ? $this->ohlc_frac_width : 0.3;
- $dw = max($min_width, min($max_width,
- (int)($width_factor * $this->plot_area_width / $this->num_data_rows)));
-
- // Get line widths to use: index 0 for body/stroke, 1 for wick/tick.
- list($body_thickness, $wick_thickness) = $this->line_widths;
-
- $gcvars = array(); // For GetDataColor, which initializes and uses this.
-
- for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
- $record = 1; // Skip record #0 (data label)
-
- if ($this->datatype_implied) // Implied X values?
- $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
- else
- $x_now = $this->data[$row][$record++]; // Read it, advance record index
-
- $x_now_pixels = $this->xtr($x_now); // Convert X to device coordinates
- $x_left = $x_now_pixels - $dw;
- $x_right = $x_now_pixels + $dw;
-
- if ($this->x_data_label_pos != 'none') // Draw X Data labels?
- $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
-
- // Require and use 4 numeric values in each row.
- if ($this->num_recs[$row] - $record != 4
- || !is_numeric($yo = $this->data[$row][$record++])
- || !is_numeric($yh = $this->data[$row][$record++])
- || !is_numeric($yl = $this->data[$row][$record++])
- || !is_numeric($yc = $this->data[$row][$record++])) {
- return $this->PrintError("DrawOHLC: row $row must have 4 values.");
- }
-
- // Set device coordinates for each value and direction flag:
- $yh_pixels = $this->ytr($yh);
- $yl_pixels = $this->ytr($yl);
- $yc_pixels = $this->ytr($yc);
- $yo_pixels = $this->ytr($yo);
- $closed_up = $yc >= $yo;
-
- // Get data colors and line thicknesses:
- if ($closed_up) {
- $this->GetDataColor($row, 1, $gcvars, $body_color); // Color 1 for body, closing up
- $this->GetDataColor($row, 3, $gcvars, $ext_color); // Color 3 for wicks/ticks
- } else {
- $this->GetDataColor($row, 0, $gcvars, $body_color); // Color 0 for body, closing down
- $this->GetDataColor($row, 2, $gcvars, $ext_color); // Color 2 for wicks/ticks
- }
- imagesetthickness($this->img, $body_thickness);
-
- if ($draw_candles) {
- // Note: Unlike ImageFilledRectangle, ImageRectangle 'requires' its arguments in
- // order with upper left corner first.
- if ($closed_up) {
- $yb1_pixels = $yc_pixels; // Upper body Y
- $yb2_pixels = $yo_pixels; // Lower body Y
- $draw_body = $draw_body_close_up;
- // Avoid a PHP/GD bug resulting in "T"-shaped ends to zero height unfilled rectangle:
- if ($yb1_pixels == $yb2_pixels)
- $draw_body = 'imagefilledrectangle';
- } else {
- $yb1_pixels = $yo_pixels;
- $yb2_pixels = $yc_pixels;
- $draw_body = 'imagefilledrectangle';
- }
-
- // Draw candle body
- $draw_body($this->img, $x_left, $yb1_pixels, $x_right, $yb2_pixels, $body_color);
-
- // Draw upper and lower wicks, if they have height. (In device coords, that's dY<0)
- imagesetthickness($this->img, $wick_thickness);
- if ($yh_pixels < $yb1_pixels) {
- imageline($this->img, $x_now_pixels, $yb1_pixels, $x_now_pixels, $yh_pixels, $ext_color);
- }
- if ($yl_pixels > $yb2_pixels) {
- imageline($this->img, $x_now_pixels, $yb2_pixels, $x_now_pixels, $yl_pixels, $ext_color);
- }
- } else {
- // Basic OHLC
- imageline($this->img, $x_now_pixels, $yl_pixels, $x_now_pixels, $yh_pixels, $body_color);
- imagesetthickness($this->img, $wick_thickness);
- imageline($this->img, $x_left, $yo_pixels, $x_now_pixels, $yo_pixels, $ext_color);
- imageline($this->img, $x_right, $yc_pixels, $x_now_pixels, $yc_pixels, $ext_color);
- }
- imagesetthickness($this->img, 1);
- }
- return TRUE;
- }
-
- /*
- * Draw the graph.
- * This is the function that performs the actual drawing, after all
- * the parameters and data are set up.
- * It also outputs the finished image, unless told not to.
- * Note: It is possible for this to be called multiple times.
- */
- function DrawGraph()
- {
- // Test for missing image, missing data, empty data:
- if (!$this->CheckDataArray())
- return FALSE; // Error message already reported.
-
- // Set defaults then import plot type configuration:
- $draw_axes = TRUE;
- $draw_arg = array(); // Default is: no arguments to the drawing function
- extract(PHPlot::$plots[$this->plot_type]);
-
- // Allocate colors for the plot:
- $this->SetColorIndexes();
-
- // Get maxima and minima for scaling:
- if (!$this->FindDataLimits())
- return FALSE;
-
- // Set plot area world values (plot_max_x, etc.):
- if (!$this->CalcPlotAreaWorld())
- return FALSE;
-
- // Calculate X and Y axis positions in World Coordinates:
- $this->CalcAxisPositions();
-
- // Process label-related parameters:
- $this->CheckLabels();
-
- // Apply grid defaults:
- $this->CalcGridSettings();
-
- // Calculate the plot margins, if needed.
- // For pie charts, set the $maximize argument to maximize space usage.
- $this->CalcMargins(!$draw_axes);
-
- // Calculate the actual plot area in device coordinates:
- $this->CalcPlotAreaPixels();
-
- // Calculate the mapping between world and device coordinates:
- $this->CalcTranslation();
-
- // Pad color and style arrays to fit records per group:
- $this->PadArrays();
- $this->DoCallback('draw_setup');
-
- $this->DrawBackground();
- $this->DrawImageBorder();
- $this->DoCallback('draw_image_background');
-
- $this->DrawPlotAreaBackground();
- $this->DoCallback('draw_plotarea_background', $this->plot_area);
-
- $this->DrawTitle();
- if ($draw_axes) { // If no axes (pie chart), no axis titles either
- $this->DrawXTitle();
- $this->DrawYTitle();
- }
- $this->DoCallback('draw_titles');
-
- if ($draw_axes && ! $this->grid_at_foreground) { // Usually one wants grids to go back, but...
- $this->DrawYAxis(); // Y axis must be drawn before X axis (see DrawYAxis())
- $this->DrawXAxis();
- $this->DoCallback('draw_axes');
- }
-
- // Call the plot-type drawing method:
- call_user_func_array(array($this, $draw_method), $draw_arg);
- $this->DoCallback('draw_graph', $this->plot_area);
-
- if ($draw_axes && $this->grid_at_foreground) { // Usually one wants grids to go back, but...
- $this->DrawYAxis(); // Y axis must be drawn before X axis (see DrawYAxis())
- $this->DrawXAxis();
- $this->DoCallback('draw_axes');
- }
-
- if ($draw_axes) {
- $this->DrawPlotBorder();
- $this->DoCallback('draw_border');
- }
-
- if ($this->legend) {
- $this->DrawLegend();
- $this->DoCallback('draw_legend');
- }
- $this->DoCallback('draw_all', $this->plot_area);
-
- if ($this->print_image && !$this->PrintImage())
- return FALSE;
-
- return TRUE;
- }
-
-/////////////////////////////////////////////
-////////////////// DEPRECATED METHODS
-/////////////////////////////////////////////
-
- /*
- * Note on deprecated methods - as these pre-date the PHPlot Reference
- * Manual, and there is minimal documentation about them, I have neither
- * removed them nor changed them. They are not tested or documented, and
- * should not be used.
- */
-
- /*
- * Deprecated, use SetYTickPos()
- */
- function SetDrawVertTicks($which_dvt)
- {
- if ($which_dvt != 1)
- $this->SetYTickPos('none');
- return TRUE;
- }
-
- /*
- * Deprecated, use SetXTickPos()
- */
- function SetDrawHorizTicks($which_dht)
- {
- if ($which_dht != 1)
- $this->SetXTickPos('none');
- return TRUE;
- }
-
- /*
- * Deprecated - use SetNumXTicks()
- */
- function SetNumHorizTicks($n)
- {
- return $this->SetNumXTicks($n);
- }
-
- /*
- * Deprecated - use SetNumYTicks()
- */
- function SetNumVertTicks($n)
- {
- return $this->SetNumYTicks($n);
- }
-
- /*
- * Deprecated - use SetXTickIncrement()
- */
- function SetHorizTickIncrement($inc)
- {
- return $this->SetXTickIncrement($inc);
- }
-
- /*
- * Deprecated - use SetYTickIncrement()
- */
- function SetVertTickIncrement($inc)
- {
- return $this->SetYTickIncrement($inc);
- }
-
- /*
- * Deprecated - use SetYTickPos()
- */
- function SetVertTickPosition($which_tp)
- {
- return $this->SetYTickPos($which_tp);
- }
-
- /*
- * Deprecated - use SetXTickPos()
- */
- function SetHorizTickPosition($which_tp)
- {
- return $this->SetXTickPos($which_tp);
- }
-
- /*
- * Deprecated - use SetFont()
- */
- function SetTitleFontSize($which_size)
- {
- return $this->SetFont('title', $which_size);
- }
-
- /*
- * Deprecated - use SetFont()
- */
- function SetAxisFontSize($which_size)
- {
- $this->SetFont('x_label', $which_size);
- $this->SetFont('y_label', $which_size);
- }
-
- /*
- * Deprecated - use SetFont()
- */
- function SetSmallFontSize($which_size)
- {
- return $this->SetFont('generic', $which_size);
- }
-
- /*
- * Deprecated - use SetFont()
- */
- function SetXLabelFontSize($which_size)
- {
- return $this->SetFont('x_title', $which_size);
- }
-
- /*
- * Deprecated - use SetFont()
- */
- function SetYLabelFontSize($which_size)
- {
- return $this->SetFont('y_title', $which_size);
- }
-
- /*
- * Deprecated - use SetXTitle()
- */
- function SetXLabel($which_xlab)
- {
- return $this->SetXTitle($which_xlab);
- }
-
- /*
- * Deprecated - use SetYTitle()
- */
- function SetYLabel($which_ylab)
- {
- return $this->SetYTitle($which_ylab);
- }
-
- /*
- * Deprecated - use SetXTickLength() and SetYTickLength() instead.
- */
- function SetTickLength($which_tl)
- {
- $this->SetXTickLength($which_tl);
- $this->SetYTickLength($which_tl);
- return TRUE;
- }
-
- /*
- * Deprecated - use SetYLabelType()
- */
- function SetYGridLabelType($which_yglt)
- {
- return $this->SetYLabelType($which_yglt);
- }
-
- /*
- * Deprecated - use SetXLabelType()
- */
- function SetXGridLabelType($which_xglt)
- {
- return $this->SetXLabelType($which_xglt);
- }
- /*
- * Deprecated - use SetYTickLabelPos()
- */
- function SetYGridLabelPos($which_yglp)
- {
- return $this->SetYTickLabelPos($which_yglp);
- }
- /*
- * Deprecated - use SetXTickLabelPos()
- */
- function SetXGridLabelPos($which_xglp)
- {
- return $this->SetXTickLabelPos($which_xglp);
- }
-
- /*
- * Deprecated - use SetXtitle()
- */
- function SetXTitlePos($xpos)
- {
- $this->x_title_pos = $xpos;
- return TRUE;
- }
-
- /*
- * Deprecated - use SetYTitle()
- */
- function SetYTitlePos($xpos)
- {
- $this->y_title_pos = $xpos;
- return TRUE;
- }
-
- /*
- * Deprecated - use SetXDataLabelPos()
- */
- function SetDrawXDataLabels($which_dxdl)
- {
- if ($which_dxdl == '1' )
- $this->SetXDataLabelPos('plotdown');
- else
- $this->SetXDataLabelPos('none');
- }
-
- /*
- * Deprecated - use SetPlotAreaPixels()
- */
- function SetNewPlotAreaPixels($x1, $y1, $x2, $y2)
- {
- return $this->SetPlotAreaPixels($x1, $y1, $x2, $y2);
- }
-
- /*
- * Deprecated - use SetLineWidths().
- */
- function SetLineWidth($which_lw)
- {
-
- $this->SetLineWidths($which_lw);
-
- if (!$this->error_bar_line_width) {
- $this->SetErrorBarLineWidth($which_lw);
- }
- return TRUE;
- }
-
- /*
- * Deprecated - use SetPointShapes().
- */
- function SetPointShape($which_pt)
- {
- $this->SetPointShapes($which_pt);
- return TRUE;
- }
-
- /*
- * Deprecated - use SetPointSizes().
- */
- function SetPointSize($which_ps)
- {
- $this->SetPointSizes($which_ps);
- return TRUE;
- }
-}
-
-/*
- * The PHPlot_truecolor class extends PHPlot to use GD truecolor images.
- */
-
-class PHPlot_truecolor extends PHPlot
-{
- /*
- * PHPlot Truecolor variation constructor: Create a PHPlot_truecolor object and initialize it.
- * Note this does NOT call the parent (PHPlot) constructor. It duplicates the code here.
- * Everything is the same as the PHPlot constructor except for imagecreatetruecolor.
- *
- * Parameters are the same as PHPlot:
- * $which_width : Image width in pixels.
- * $which_height : Image height in pixels.
- * $which_output_file : Filename for output.
- * $which_input_file : Path to a file to be used as background.
- */
- function __construct($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
- {
- $this->SetRGBArray($this->color_array);
-
- if ($which_output_file)
- $this->SetOutputFile($which_output_file);
-
- if ($which_input_file) {
- $this->SetInputFile($which_input_file);
- } else {
- $this->image_width = $which_width;
- $this->image_height = $which_height;
-
- $this->img = imagecreatetruecolor($this->image_width, $this->image_height);
- if (! $this->img)
- return $this->PrintError('PHPlot_truecolor(): Could not create image resource.');
- }
-
- $this->SetDefaultStyles();
- $this->SetDefaultFonts();
- }
-}
+++ /dev/null
-<?php
-/* $Id: rgb.inc.php,v 1.2 2009/06/12 01:58:35 lbayuk Exp $ */
-/*
- * This is a large color map which can be used by PHPlot via
- * $plot->SetRGBArray('large')
- * For more information on PHPlot see http://sourceforge.net/projects/phplot/
- *
- * rgb.inc.php comes with PHPlot but is derived from the X11 rgb.txt color
- * database file, which contains no specific copyright notice. It may be
- * covered by X.Org, XFree86, or MIT/X11 copyright and license, all of which
- * allow redistribution on terms which are less strict than the LGPL which
- * covers PHPlot.
- */
-$ColorArray = array(
- "snow" => array(255, 250, 250),
- "ghost white" => array(248, 248, 255),
- "GhostWhite" => array(248, 248, 255),
- "white smoke" => array(245, 245, 245),
- "WhiteSmoke" => array(245, 245, 245),
- "gainsboro" => array(220, 220, 220),
- "floral white" => array(255, 250, 240),
- "FloralWhite" => array(255, 250, 240),
- "old lace" => array(253, 245, 230),
- "OldLace" => array(253, 245, 230),
- "linen" => array(250, 240, 230),
- "antique white" => array(250, 235, 215),
- "AntiqueWhite" => array(250, 235, 215),
- "papaya whip" => array(255, 239, 213),
- "PapayaWhip" => array(255, 239, 213),
- "blanched almond" => array(255, 235, 205),
- "BlanchedAlmond" => array(255, 235, 205),
- "bisque" => array(255, 228, 196),
- "peach puff" => array(255, 218, 185),
- "PeachPuff" => array(255, 218, 185),
- "navajo white" => array(255, 222, 173),
- "NavajoWhite" => array(255, 222, 173),
- "moccasin" => array(255, 228, 181),
- "cornsilk" => array(255, 248, 220),
- "ivory" => array(255, 255, 240),
- "lemon chiffon" => array(255, 250, 205),
- "LemonChiffon" => array(255, 250, 205),
- "seashell" => array(255, 245, 238),
- "honeydew" => array(240, 255, 240),
- "mint cream" => array(245, 255, 250),
- "MintCream" => array(245, 255, 250),
- "azure" => array(240, 255, 255),
- "alice blue" => array(240, 248, 255),
- "AliceBlue" => array(240, 248, 255),
- "lavender" => array(230, 230, 250),
- "lavender blush" => array(255, 240, 245),
- "LavenderBlush" => array(255, 240, 245),
- "misty rose" => array(255, 228, 225),
- "MistyRose" => array(255, 228, 225),
- "white" => array(255, 255, 255),
- "black" => array( 0, 0, 0),
- "dark slate gray" => array( 47, 79, 79),
- "DarkSlateGray" => array( 47, 79, 79),
- "dark slate grey" => array( 47, 79, 79),
- "DarkSlateGrey" => array( 47, 79, 79),
- "dim gray" => array(105, 105, 105),
- "DimGray" => array(105, 105, 105),
- "dim grey" => array(105, 105, 105),
- "DimGrey" => array(105, 105, 105),
- "slate gray" => array(112, 128, 144),
- "SlateGray" => array(112, 128, 144),
- "slate grey" => array(112, 128, 144),
- "SlateGrey" => array(112, 128, 144),
- "light slate gray" => array(119, 136, 153),
- "LightSlateGray" => array(119, 136, 153),
- "light slate grey" => array(119, 136, 153),
- "LightSlateGrey" => array(119, 136, 153),
- "gray" => array(190, 190, 190),
- "grey" => array(190, 190, 190),
- "light grey" => array(211, 211, 211),
- "LightGrey" => array(211, 211, 211),
- "light gray" => array(211, 211, 211),
- "LightGray" => array(211, 211, 211),
- "midnight blue" => array( 25, 25, 112),
- "MidnightBlue" => array( 25, 25, 112),
- "navy" => array( 0, 0, 128),
- "navy blue" => array( 0, 0, 128),
- "NavyBlue" => array( 0, 0, 128),
- "cornflower blue" => array(100, 149, 237),
- "CornflowerBlue" => array(100, 149, 237),
- "dark slate blue" => array( 72, 61, 139),
- "DarkSlateBlue" => array( 72, 61, 139),
- "slate blue" => array(106, 90, 205),
- "SlateBlue" => array(106, 90, 205),
- "medium slate blue" => array(123, 104, 238),
- "MediumSlateBlue" => array(123, 104, 238),
- "light slate blue" => array(132, 112, 255),
- "LightSlateBlue" => array(132, 112, 255),
- "medium blue" => array( 0, 0, 205),
- "MediumBlue" => array( 0, 0, 205),
- "royal blue" => array( 65, 105, 225),
- "RoyalBlue" => array( 65, 105, 225),
- "blue" => array( 0, 0, 255),
- "dodger blue" => array( 30, 144, 255),
- "DodgerBlue" => array( 30, 144, 255),
- "deep sky blue" => array( 0, 191, 255),
- "DeepSkyBlue" => array( 0, 191, 255),
- "sky blue" => array(135, 206, 235),
- "SkyBlue" => array(135, 206, 235),
- "light sky blue" => array(135, 206, 250),
- "LightSkyBlue" => array(135, 206, 250),
- "steel blue" => array( 70, 130, 180),
- "SteelBlue" => array( 70, 130, 180),
- "light steel blue" => array(176, 196, 222),
- "LightSteelBlue" => array(176, 196, 222),
- "light blue" => array(173, 216, 230),
- "LightBlue" => array(173, 216, 230),
- "powder blue" => array(176, 224, 230),
- "PowderBlue" => array(176, 224, 230),
- "pale turquoise" => array(175, 238, 238),
- "PaleTurquoise" => array(175, 238, 238),
- "dark turquoise" => array( 0, 206, 209),
- "DarkTurquoise" => array( 0, 206, 209),
- "medium turquoise" => array( 72, 209, 204),
- "MediumTurquoise" => array( 72, 209, 204),
- "turquoise" => array( 64, 224, 208),
- "cyan" => array( 0, 255, 255),
- "light cyan" => array(224, 255, 255),
- "LightCyan" => array(224, 255, 255),
- "cadet blue" => array( 95, 158, 160),
- "CadetBlue" => array( 95, 158, 160),
- "medium aquamarine" => array(102, 205, 170),
- "MediumAquamarine" => array(102, 205, 170),
- "aquamarine" => array(127, 255, 212),
- "dark green" => array( 0, 100, 0),
- "DarkGreen" => array( 0, 100, 0),
- "dark olive green" => array( 85, 107, 47),
- "DarkOliveGreen" => array( 85, 107, 47),
- "dark sea green" => array(143, 188, 143),
- "DarkSeaGreen" => array(143, 188, 143),
- "sea green" => array( 46, 139, 87),
- "SeaGreen" => array( 46, 139, 87),
- "medium sea green" => array( 60, 179, 113),
- "MediumSeaGreen" => array( 60, 179, 113),
- "light sea green" => array( 32, 178, 170),
- "LightSeaGreen" => array( 32, 178, 170),
- "pale green" => array(152, 251, 152),
- "PaleGreen" => array(152, 251, 152),
- "spring green" => array( 0, 255, 127),
- "SpringGreen" => array( 0, 255, 127),
- "lawn green" => array(124, 252, 0),
- "LawnGreen" => array(124, 252, 0),
- "green" => array( 0, 255, 0),
- "chartreuse" => array(127, 255, 0),
- "medium spring green" => array( 0, 250, 154),
- "MediumSpringGreen" => array( 0, 250, 154),
- "green yellow" => array(173, 255, 47),
- "GreenYellow" => array(173, 255, 47),
- "lime green" => array( 50, 205, 50),
- "LimeGreen" => array( 50, 205, 50),
- "yellow green" => array(154, 205, 50),
- "YellowGreen" => array(154, 205, 50),
- "forest green" => array( 34, 139, 34),
- "ForestGreen" => array( 34, 139, 34),
- "olive drab" => array(107, 142, 35),
- "OliveDrab" => array(107, 142, 35),
- "dark khaki" => array(189, 183, 107),
- "DarkKhaki" => array(189, 183, 107),
- "khaki" => array(240, 230, 140),
- "pale goldenrod" => array(238, 232, 170),
- "PaleGoldenrod" => array(238, 232, 170),
- "light goldenrod yellow" => array(250, 250, 210),
- "LightGoldenrodYellow" => array(250, 250, 210),
- "light yellow" => array(255, 255, 224),
- "LightYellow" => array(255, 255, 224),
- "yellow" => array(255, 255, 0),
- "gold" => array(255, 215, 0),
- "light goldenrod" => array(238, 221, 130),
- "LightGoldenrod" => array(238, 221, 130),
- "goldenrod" => array(218, 165, 32),
- "dark goldenrod" => array(184, 134, 11),
- "DarkGoldenrod" => array(184, 134, 11),
- "rosy brown" => array(188, 143, 143),
- "RosyBrown" => array(188, 143, 143),
- "indian red" => array(205, 92, 92),
- "IndianRed" => array(205, 92, 92),
- "saddle brown" => array(139, 69, 19),
- "SaddleBrown" => array(139, 69, 19),
- "sienna" => array(160, 82, 45),
- "peru" => array(205, 133, 63),
- "burlywood" => array(222, 184, 135),
- "beige" => array(245, 245, 220),
- "wheat" => array(245, 222, 179),
- "sandy brown" => array(244, 164, 96),
- "SandyBrown" => array(244, 164, 96),
- "tan" => array(210, 180, 140),
- "chocolate" => array(210, 105, 30),
- "firebrick" => array(178, 34, 34),
- "brown" => array(165, 42, 42),
- "dark salmon" => array(233, 150, 122),
- "DarkSalmon" => array(233, 150, 122),
- "salmon" => array(250, 128, 114),
- "light salmon" => array(255, 160, 122),
- "LightSalmon" => array(255, 160, 122),
- "orange" => array(255, 165, 0),
- "dark orange" => array(255, 140, 0),
- "DarkOrange" => array(255, 140, 0),
- "coral" => array(255, 127, 80),
- "light coral" => array(240, 128, 128),
- "LightCoral" => array(240, 128, 128),
- "tomato" => array(255, 99, 71),
- "orange red" => array(255, 69, 0),
- "OrangeRed" => array(255, 69, 0),
- "red" => array(255, 0, 0),
- "hot pink" => array(255, 105, 180),
- "HotPink" => array(255, 105, 180),
- "deep pink" => array(255, 20, 147),
- "DeepPink" => array(255, 20, 147),
- "pink" => array(255, 192, 203),
- "light pink" => array(255, 182, 193),
- "LightPink" => array(255, 182, 193),
- "pale violet red" => array(219, 112, 147),
- "PaleVioletRed" => array(219, 112, 147),
- "maroon" => array(176, 48, 96),
- "medium violet red" => array(199, 21, 133),
- "MediumVioletRed" => array(199, 21, 133),
- "violet red" => array(208, 32, 144),
- "VioletRed" => array(208, 32, 144),
- "magenta" => array(255, 0, 255),
- "violet" => array(238, 130, 238),
- "plum" => array(221, 160, 221),
- "orchid" => array(218, 112, 214),
- "medium orchid" => array(186, 85, 211),
- "MediumOrchid" => array(186, 85, 211),
- "dark orchid" => array(153, 50, 204),
- "DarkOrchid" => array(153, 50, 204),
- "dark violet" => array(148, 0, 211),
- "DarkViolet" => array(148, 0, 211),
- "blue violet" => array(138, 43, 226),
- "BlueViolet" => array(138, 43, 226),
- "purple" => array(160, 32, 240),
- "medium purple" => array(147, 112, 219),
- "MediumPurple" => array(147, 112, 219),
- "thistle" => array(216, 191, 216),
- "snow1" => array(255, 250, 250),
- "snow2" => array(238, 233, 233),
- "snow3" => array(205, 201, 201),
- "snow4" => array(139, 137, 137),
- "seashell1" => array(255, 245, 238),
- "seashell2" => array(238, 229, 222),
- "seashell3" => array(205, 197, 191),
- "seashell4" => array(139, 134, 130),
- "AntiqueWhite1" => array(255, 239, 219),
- "AntiqueWhite2" => array(238, 223, 204),
- "AntiqueWhite3" => array(205, 192, 176),
- "AntiqueWhite4" => array(139, 131, 120),
- "bisque1" => array(255, 228, 196),
- "bisque2" => array(238, 213, 183),
- "bisque3" => array(205, 183, 158),
- "bisque4" => array(139, 125, 107),
- "PeachPuff1" => array(255, 218, 185),
- "PeachPuff2" => array(238, 203, 173),
- "PeachPuff3" => array(205, 175, 149),
- "PeachPuff4" => array(139, 119, 101),
- "NavajoWhite1" => array(255, 222, 173),
- "NavajoWhite2" => array(238, 207, 161),
- "NavajoWhite3" => array(205, 179, 139),
- "NavajoWhite4" => array(139, 121, 94),
- "LemonChiffon1" => array(255, 250, 205),
- "LemonChiffon2" => array(238, 233, 191),
- "LemonChiffon3" => array(205, 201, 165),
- "LemonChiffon4" => array(139, 137, 112),
- "cornsilk1" => array(255, 248, 220),
- "cornsilk2" => array(238, 232, 205),
- "cornsilk3" => array(205, 200, 177),
- "cornsilk4" => array(139, 136, 120),
- "ivory1" => array(255, 255, 240),
- "ivory2" => array(238, 238, 224),
- "ivory3" => array(205, 205, 193),
- "ivory4" => array(139, 139, 131),
- "honeydew1" => array(240, 255, 240),
- "honeydew2" => array(224, 238, 224),
- "honeydew3" => array(193, 205, 193),
- "honeydew4" => array(131, 139, 131),
- "LavenderBlush1" => array(255, 240, 245),
- "LavenderBlush2" => array(238, 224, 229),
- "LavenderBlush3" => array(205, 193, 197),
- "LavenderBlush4" => array(139, 131, 134),
- "MistyRose1" => array(255, 228, 225),
- "MistyRose2" => array(238, 213, 210),
- "MistyRose3" => array(205, 183, 181),
- "MistyRose4" => array(139, 125, 123),
- "azure1" => array(240, 255, 255),
- "azure2" => array(224, 238, 238),
- "azure3" => array(193, 205, 205),
- "azure4" => array(131, 139, 139),
- "SlateBlue1" => array(131, 111, 255),
- "SlateBlue2" => array(122, 103, 238),
- "SlateBlue3" => array(105, 89, 205),
- "SlateBlue4" => array( 71, 60, 139),
- "RoyalBlue1" => array( 72, 118, 255),
- "RoyalBlue2" => array( 67, 110, 238),
- "RoyalBlue3" => array( 58, 95, 205),
- "RoyalBlue4" => array( 39, 64, 139),
- "blue1" => array( 0, 0, 255),
- "blue2" => array( 0, 0, 238),
- "blue3" => array( 0, 0, 205),
- "blue4" => array( 0, 0, 139),
- "DodgerBlue1" => array( 30, 144, 255),
- "DodgerBlue2" => array( 28, 134, 238),
- "DodgerBlue3" => array( 24, 116, 205),
- "DodgerBlue4" => array( 16, 78, 139),
- "SteelBlue1" => array( 99, 184, 255),
- "SteelBlue2" => array( 92, 172, 238),
- "SteelBlue3" => array( 79, 148, 205),
- "SteelBlue4" => array( 54, 100, 139),
- "DeepSkyBlue1" => array( 0, 191, 255),
- "DeepSkyBlue2" => array( 0, 178, 238),
- "DeepSkyBlue3" => array( 0, 154, 205),
- "DeepSkyBlue4" => array( 0, 104, 139),
- "SkyBlue1" => array(135, 206, 255),
- "SkyBlue2" => array(126, 192, 238),
- "SkyBlue3" => array(108, 166, 205),
- "SkyBlue4" => array( 74, 112, 139),
- "LightSkyBlue1" => array(176, 226, 255),
- "LightSkyBlue2" => array(164, 211, 238),
- "LightSkyBlue3" => array(141, 182, 205),
- "LightSkyBlue4" => array( 96, 123, 139),
- "SlateGray1" => array(198, 226, 255),
- "SlateGray2" => array(185, 211, 238),
- "SlateGray3" => array(159, 182, 205),
- "SlateGray4" => array(108, 123, 139),
- "LightSteelBlue1" => array(202, 225, 255),
- "LightSteelBlue2" => array(188, 210, 238),
- "LightSteelBlue3" => array(162, 181, 205),
- "LightSteelBlue4" => array(110, 123, 139),
- "LightBlue1" => array(191, 239, 255),
- "LightBlue2" => array(178, 223, 238),
- "LightBlue3" => array(154, 192, 205),
- "LightBlue4" => array(104, 131, 139),
- "LightCyan1" => array(224, 255, 255),
- "LightCyan2" => array(209, 238, 238),
- "LightCyan3" => array(180, 205, 205),
- "LightCyan4" => array(122, 139, 139),
- "PaleTurquoise1" => array(187, 255, 255),
- "PaleTurquoise2" => array(174, 238, 238),
- "PaleTurquoise3" => array(150, 205, 205),
- "PaleTurquoise4" => array(102, 139, 139),
- "CadetBlue1" => array(152, 245, 255),
- "CadetBlue2" => array(142, 229, 238),
- "CadetBlue3" => array(122, 197, 205),
- "CadetBlue4" => array( 83, 134, 139),
- "turquoise1" => array( 0, 245, 255),
- "turquoise2" => array( 0, 229, 238),
- "turquoise3" => array( 0, 197, 205),
- "turquoise4" => array( 0, 134, 139),
- "cyan1" => array( 0, 255, 255),
- "cyan2" => array( 0, 238, 238),
- "cyan3" => array( 0, 205, 205),
- "cyan4" => array( 0, 139, 139),
- "DarkSlateGray1" => array(151, 255, 255),
- "DarkSlateGray2" => array(141, 238, 238),
- "DarkSlateGray3" => array(121, 205, 205),
- "DarkSlateGray4" => array( 82, 139, 139),
- "aquamarine1" => array(127, 255, 212),
- "aquamarine2" => array(118, 238, 198),
- "aquamarine3" => array(102, 205, 170),
- "aquamarine4" => array( 69, 139, 116),
- "DarkSeaGreen1" => array(193, 255, 193),
- "DarkSeaGreen2" => array(180, 238, 180),
- "DarkSeaGreen3" => array(155, 205, 155),
- "DarkSeaGreen4" => array(105, 139, 105),
- "SeaGreen1" => array( 84, 255, 159),
- "SeaGreen2" => array( 78, 238, 148),
- "SeaGreen3" => array( 67, 205, 128),
- "SeaGreen4" => array( 46, 139, 87),
- "PaleGreen1" => array(154, 255, 154),
- "PaleGreen2" => array(144, 238, 144),
- "PaleGreen3" => array(124, 205, 124),
- "PaleGreen4" => array( 84, 139, 84),
- "SpringGreen1" => array( 0, 255, 127),
- "SpringGreen2" => array( 0, 238, 118),
- "SpringGreen3" => array( 0, 205, 102),
- "SpringGreen4" => array( 0, 139, 69),
- "green1" => array( 0, 255, 0),
- "green2" => array( 0, 238, 0),
- "green3" => array( 0, 205, 0),
- "green4" => array( 0, 139, 0),
- "chartreuse1" => array(127, 255, 0),
- "chartreuse2" => array(118, 238, 0),
- "chartreuse3" => array(102, 205, 0),
- "chartreuse4" => array( 69, 139, 0),
- "OliveDrab1" => array(192, 255, 62),
- "OliveDrab2" => array(179, 238, 58),
- "OliveDrab3" => array(154, 205, 50),
- "OliveDrab4" => array(105, 139, 34),
- "DarkOliveGreen1" => array(202, 255, 112),
- "DarkOliveGreen2" => array(188, 238, 104),
- "DarkOliveGreen3" => array(162, 205, 90),
- "DarkOliveGreen4" => array(110, 139, 61),
- "khaki1" => array(255, 246, 143),
- "khaki2" => array(238, 230, 133),
- "khaki3" => array(205, 198, 115),
- "khaki4" => array(139, 134, 78),
- "LightGoldenrod1" => array(255, 236, 139),
- "LightGoldenrod2" => array(238, 220, 130),
- "LightGoldenrod3" => array(205, 190, 112),
- "LightGoldenrod4" => array(139, 129, 76),
- "LightYellow1" => array(255, 255, 224),
- "LightYellow2" => array(238, 238, 209),
- "LightYellow3" => array(205, 205, 180),
- "LightYellow4" => array(139, 139, 122),
- "yellow1" => array(255, 255, 0),
- "yellow2" => array(238, 238, 0),
- "yellow3" => array(205, 205, 0),
- "yellow4" => array(139, 139, 0),
- "gold1" => array(255, 215, 0),
- "gold2" => array(238, 201, 0),
- "gold3" => array(205, 173, 0),
- "gold4" => array(139, 117, 0),
- "goldenrod1" => array(255, 193, 37),
- "goldenrod2" => array(238, 180, 34),
- "goldenrod3" => array(205, 155, 29),
- "goldenrod4" => array(139, 105, 20),
- "DarkGoldenrod1" => array(255, 185, 15),
- "DarkGoldenrod2" => array(238, 173, 14),
- "DarkGoldenrod3" => array(205, 149, 12),
- "DarkGoldenrod4" => array(139, 101, 8),
- "RosyBrown1" => array(255, 193, 193),
- "RosyBrown2" => array(238, 180, 180),
- "RosyBrown3" => array(205, 155, 155),
- "RosyBrown4" => array(139, 105, 105),
- "IndianRed1" => array(255, 106, 106),
- "IndianRed2" => array(238, 99, 99),
- "IndianRed3" => array(205, 85, 85),
- "IndianRed4" => array(139, 58, 58),
- "sienna1" => array(255, 130, 71),
- "sienna2" => array(238, 121, 66),
- "sienna3" => array(205, 104, 57),
- "sienna4" => array(139, 71, 38),
- "burlywood1" => array(255, 211, 155),
- "burlywood2" => array(238, 197, 145),
- "burlywood3" => array(205, 170, 125),
- "burlywood4" => array(139, 115, 85),
- "wheat1" => array(255, 231, 186),
- "wheat2" => array(238, 216, 174),
- "wheat3" => array(205, 186, 150),
- "wheat4" => array(139, 126, 102),
- "tan1" => array(255, 165, 79),
- "tan2" => array(238, 154, 73),
- "tan3" => array(205, 133, 63),
- "tan4" => array(139, 90, 43),
- "chocolate1" => array(255, 127, 36),
- "chocolate2" => array(238, 118, 33),
- "chocolate3" => array(205, 102, 29),
- "chocolate4" => array(139, 69, 19),
- "firebrick1" => array(255, 48, 48),
- "firebrick2" => array(238, 44, 44),
- "firebrick3" => array(205, 38, 38),
- "firebrick4" => array(139, 26, 26),
- "brown1" => array(255, 64, 64),
- "brown2" => array(238, 59, 59),
- "brown3" => array(205, 51, 51),
- "brown4" => array(139, 35, 35),
- "salmon1" => array(255, 140, 105),
- "salmon2" => array(238, 130, 98),
- "salmon3" => array(205, 112, 84),
- "salmon4" => array(139, 76, 57),
- "LightSalmon1" => array(255, 160, 122),
- "LightSalmon2" => array(238, 149, 114),
- "LightSalmon3" => array(205, 129, 98),
- "LightSalmon4" => array(139, 87, 66),
- "orange1" => array(255, 165, 0),
- "orange2" => array(238, 154, 0),
- "orange3" => array(205, 133, 0),
- "orange4" => array(139, 90, 0),
- "DarkOrange1" => array(255, 127, 0),
- "DarkOrange2" => array(238, 118, 0),
- "DarkOrange3" => array(205, 102, 0),
- "DarkOrange4" => array(139, 69, 0),
- "coral1" => array(255, 114, 86),
- "coral2" => array(238, 106, 80),
- "coral3" => array(205, 91, 69),
- "coral4" => array(139, 62, 47),
- "tomato1" => array(255, 99, 71),
- "tomato2" => array(238, 92, 66),
- "tomato3" => array(205, 79, 57),
- "tomato4" => array(139, 54, 38),
- "OrangeRed1" => array(255, 69, 0),
- "OrangeRed2" => array(238, 64, 0),
- "OrangeRed3" => array(205, 55, 0),
- "OrangeRed4" => array(139, 37, 0),
- "red1" => array(255, 0, 0),
- "red2" => array(238, 0, 0),
- "red3" => array(205, 0, 0),
- "red4" => array(139, 0, 0),
- "DeepPink1" => array(255, 20, 147),
- "DeepPink2" => array(238, 18, 137),
- "DeepPink3" => array(205, 16, 118),
- "DeepPink4" => array(139, 10, 80),
- "HotPink1" => array(255, 110, 180),
- "HotPink2" => array(238, 106, 167),
- "HotPink3" => array(205, 96, 144),
- "HotPink4" => array(139, 58, 98),
- "pink1" => array(255, 181, 197),
- "pink2" => array(238, 169, 184),
- "pink3" => array(205, 145, 158),
- "pink4" => array(139, 99, 108),
- "LightPink1" => array(255, 174, 185),
- "LightPink2" => array(238, 162, 173),
- "LightPink3" => array(205, 140, 149),
- "LightPink4" => array(139, 95, 101),
- "PaleVioletRed1" => array(255, 130, 171),
- "PaleVioletRed2" => array(238, 121, 159),
- "PaleVioletRed3" => array(205, 104, 137),
- "PaleVioletRed4" => array(139, 71, 93),
- "maroon1" => array(255, 52, 179),
- "maroon2" => array(238, 48, 167),
- "maroon3" => array(205, 41, 144),
- "maroon4" => array(139, 28, 98),
- "VioletRed1" => array(255, 62, 150),
- "VioletRed2" => array(238, 58, 140),
- "VioletRed3" => array(205, 50, 120),
- "VioletRed4" => array(139, 34, 82),
- "magenta1" => array(255, 0, 255),
- "magenta2" => array(238, 0, 238),
- "magenta3" => array(205, 0, 205),
- "magenta4" => array(139, 0, 139),
- "orchid1" => array(255, 131, 250),
- "orchid2" => array(238, 122, 233),
- "orchid3" => array(205, 105, 201),
- "orchid4" => array(139, 71, 137),
- "plum1" => array(255, 187, 255),
- "plum2" => array(238, 174, 238),
- "plum3" => array(205, 150, 205),
- "plum4" => array(139, 102, 139),
- "MediumOrchid1" => array(224, 102, 255),
- "MediumOrchid2" => array(209, 95, 238),
- "MediumOrchid3" => array(180, 82, 205),
- "MediumOrchid4" => array(122, 55, 139),
- "DarkOrchid1" => array(191, 62, 255),
- "DarkOrchid2" => array(178, 58, 238),
- "DarkOrchid3" => array(154, 50, 205),
- "DarkOrchid4" => array(104, 34, 139),
- "purple1" => array(155, 48, 255),
- "purple2" => array(145, 44, 238),
- "purple3" => array(125, 38, 205),
- "purple4" => array( 85, 26, 139),
- "MediumPurple1" => array(171, 130, 255),
- "MediumPurple2" => array(159, 121, 238),
- "MediumPurple3" => array(137, 104, 205),
- "MediumPurple4" => array( 93, 71, 139),
- "thistle1" => array(255, 225, 255),
- "thistle2" => array(238, 210, 238),
- "thistle3" => array(205, 181, 205),
- "thistle4" => array(139, 123, 139),
- "gray0" => array( 0, 0, 0),
- "grey0" => array( 0, 0, 0),
- "gray1" => array( 3, 3, 3),
- "grey1" => array( 3, 3, 3),
- "gray2" => array( 5, 5, 5),
- "grey2" => array( 5, 5, 5),
- "gray3" => array( 8, 8, 8),
- "grey3" => array( 8, 8, 8),
- "gray4" => array( 10, 10, 10),
- "grey4" => array( 10, 10, 10),
- "gray5" => array( 13, 13, 13),
- "grey5" => array( 13, 13, 13),
- "gray6" => array( 15, 15, 15),
- "grey6" => array( 15, 15, 15),
- "gray7" => array( 18, 18, 18),
- "grey7" => array( 18, 18, 18),
- "gray8" => array( 20, 20, 20),
- "grey8" => array( 20, 20, 20),
- "gray9" => array( 23, 23, 23),
- "grey9" => array( 23, 23, 23),
- "gray10" => array( 26, 26, 26),
- "grey10" => array( 26, 26, 26),
- "gray11" => array( 28, 28, 28),
- "grey11" => array( 28, 28, 28),
- "gray12" => array( 31, 31, 31),
- "grey12" => array( 31, 31, 31),
- "gray13" => array( 33, 33, 33),
- "grey13" => array( 33, 33, 33),
- "gray14" => array( 36, 36, 36),
- "grey14" => array( 36, 36, 36),
- "gray15" => array( 38, 38, 38),
- "grey15" => array( 38, 38, 38),
- "gray16" => array( 41, 41, 41),
- "grey16" => array( 41, 41, 41),
- "gray17" => array( 43, 43, 43),
- "grey17" => array( 43, 43, 43),
- "gray18" => array( 46, 46, 46),
- "grey18" => array( 46, 46, 46),
- "gray19" => array( 48, 48, 48),
- "grey19" => array( 48, 48, 48),
- "gray20" => array( 51, 51, 51),
- "grey20" => array( 51, 51, 51),
- "gray21" => array( 54, 54, 54),
- "grey21" => array( 54, 54, 54),
- "gray22" => array( 56, 56, 56),
- "grey22" => array( 56, 56, 56),
- "gray23" => array( 59, 59, 59),
- "grey23" => array( 59, 59, 59),
- "gray24" => array( 61, 61, 61),
- "grey24" => array( 61, 61, 61),
- "gray25" => array( 64, 64, 64),
- "grey25" => array( 64, 64, 64),
- "gray26" => array( 66, 66, 66),
- "grey26" => array( 66, 66, 66),
- "gray27" => array( 69, 69, 69),
- "grey27" => array( 69, 69, 69),
- "gray28" => array( 71, 71, 71),
- "grey28" => array( 71, 71, 71),
- "gray29" => array( 74, 74, 74),
- "grey29" => array( 74, 74, 74),
- "gray30" => array( 77, 77, 77),
- "grey30" => array( 77, 77, 77),
- "gray31" => array( 79, 79, 79),
- "grey31" => array( 79, 79, 79),
- "gray32" => array( 82, 82, 82),
- "grey32" => array( 82, 82, 82),
- "gray33" => array( 84, 84, 84),
- "grey33" => array( 84, 84, 84),
- "gray34" => array( 87, 87, 87),
- "grey34" => array( 87, 87, 87),
- "gray35" => array( 89, 89, 89),
- "grey35" => array( 89, 89, 89),
- "gray36" => array( 92, 92, 92),
- "grey36" => array( 92, 92, 92),
- "gray37" => array( 94, 94, 94),
- "grey37" => array( 94, 94, 94),
- "gray38" => array( 97, 97, 97),
- "grey38" => array( 97, 97, 97),
- "gray39" => array( 99, 99, 99),
- "grey39" => array( 99, 99, 99),
- "gray40" => array(102, 102, 102),
- "grey40" => array(102, 102, 102),
- "gray41" => array(105, 105, 105),
- "grey41" => array(105, 105, 105),
- "gray42" => array(107, 107, 107),
- "grey42" => array(107, 107, 107),
- "gray43" => array(110, 110, 110),
- "grey43" => array(110, 110, 110),
- "gray44" => array(112, 112, 112),
- "grey44" => array(112, 112, 112),
- "gray45" => array(115, 115, 115),
- "grey45" => array(115, 115, 115),
- "gray46" => array(117, 117, 117),
- "grey46" => array(117, 117, 117),
- "gray47" => array(120, 120, 120),
- "grey47" => array(120, 120, 120),
- "gray48" => array(122, 122, 122),
- "grey48" => array(122, 122, 122),
- "gray49" => array(125, 125, 125),
- "grey49" => array(125, 125, 125),
- "gray50" => array(127, 127, 127),
- "grey50" => array(127, 127, 127),
- "gray51" => array(130, 130, 130),
- "grey51" => array(130, 130, 130),
- "gray52" => array(133, 133, 133),
- "grey52" => array(133, 133, 133),
- "gray53" => array(135, 135, 135),
- "grey53" => array(135, 135, 135),
- "gray54" => array(138, 138, 138),
- "grey54" => array(138, 138, 138),
- "gray55" => array(140, 140, 140),
- "grey55" => array(140, 140, 140),
- "gray56" => array(143, 143, 143),
- "grey56" => array(143, 143, 143),
- "gray57" => array(145, 145, 145),
- "grey57" => array(145, 145, 145),
- "gray58" => array(148, 148, 148),
- "grey58" => array(148, 148, 148),
- "gray59" => array(150, 150, 150),
- "grey59" => array(150, 150, 150),
- "gray60" => array(153, 153, 153),
- "grey60" => array(153, 153, 153),
- "gray61" => array(156, 156, 156),
- "grey61" => array(156, 156, 156),
- "gray62" => array(158, 158, 158),
- "grey62" => array(158, 158, 158),
- "gray63" => array(161, 161, 161),
- "grey63" => array(161, 161, 161),
- "gray64" => array(163, 163, 163),
- "grey64" => array(163, 163, 163),
- "gray65" => array(166, 166, 166),
- "grey65" => array(166, 166, 166),
- "gray66" => array(168, 168, 168),
- "grey66" => array(168, 168, 168),
- "gray67" => array(171, 171, 171),
- "grey67" => array(171, 171, 171),
- "gray68" => array(173, 173, 173),
- "grey68" => array(173, 173, 173),
- "gray69" => array(176, 176, 176),
- "grey69" => array(176, 176, 176),
- "gray70" => array(179, 179, 179),
- "grey70" => array(179, 179, 179),
- "gray71" => array(181, 181, 181),
- "grey71" => array(181, 181, 181),
- "gray72" => array(184, 184, 184),
- "grey72" => array(184, 184, 184),
- "gray73" => array(186, 186, 186),
- "grey73" => array(186, 186, 186),
- "gray74" => array(189, 189, 189),
- "grey74" => array(189, 189, 189),
- "gray75" => array(191, 191, 191),
- "grey75" => array(191, 191, 191),
- "gray76" => array(194, 194, 194),
- "grey76" => array(194, 194, 194),
- "gray77" => array(196, 196, 196),
- "grey77" => array(196, 196, 196),
- "gray78" => array(199, 199, 199),
- "grey78" => array(199, 199, 199),
- "gray79" => array(201, 201, 201),
- "grey79" => array(201, 201, 201),
- "gray80" => array(204, 204, 204),
- "grey80" => array(204, 204, 204),
- "gray81" => array(207, 207, 207),
- "grey81" => array(207, 207, 207),
- "gray82" => array(209, 209, 209),
- "grey82" => array(209, 209, 209),
- "gray83" => array(212, 212, 212),
- "grey83" => array(212, 212, 212),
- "gray84" => array(214, 214, 214),
- "grey84" => array(214, 214, 214),
- "gray85" => array(217, 217, 217),
- "grey85" => array(217, 217, 217),
- "gray86" => array(219, 219, 219),
- "grey86" => array(219, 219, 219),
- "gray87" => array(222, 222, 222),
- "grey87" => array(222, 222, 222),
- "gray88" => array(224, 224, 224),
- "grey88" => array(224, 224, 224),
- "gray89" => array(227, 227, 227),
- "grey89" => array(227, 227, 227),
- "gray90" => array(229, 229, 229),
- "grey90" => array(229, 229, 229),
- "gray91" => array(232, 232, 232),
- "grey91" => array(232, 232, 232),
- "gray92" => array(235, 235, 235),
- "grey92" => array(235, 235, 235),
- "gray93" => array(237, 237, 237),
- "grey93" => array(237, 237, 237),
- "gray94" => array(240, 240, 240),
- "grey94" => array(240, 240, 240),
- "gray95" => array(242, 242, 242),
- "grey95" => array(242, 242, 242),
- "gray96" => array(245, 245, 245),
- "grey96" => array(245, 245, 245),
- "gray97" => array(247, 247, 247),
- "grey97" => array(247, 247, 247),
- "gray98" => array(250, 250, 250),
- "grey98" => array(250, 250, 250),
- "gray99" => array(252, 252, 252),
- "grey99" => array(252, 252, 252),
- "gray100" => array(255, 255, 255)
-);
+++ /dev/null
-Smarty is supported only in PHP 4.0.6 or later.
-
-Smarty versions previous to 2.0 require the PEAR libraries. Be sure to include
-the path to the PEAR libraries in your php include_path. Config_file.class.php
-uses the PEAR library for its error handling routines. PEAR comes with the PHP
-distribution. Unix users check /usr/local/lib/php, windows users check
-C:/php/pear.
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-\f
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
+++ /dev/null
-2007-09-27 TAKAGI Masahiro <matakagi@gmail.com>
-
- * docs/ja/designers/language-custom-functions/language-function-html-checkboxes.xml:
- sync with en.
-
-2007-09-27 Monte Ohrt <monte@ohrt.com>
-
- * docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml:
- remove redundant attribute
-
-2007-09-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/id/programmers/plugins/plugins-functions.xml:
- removed errornous whitespace
-
-2007-09-18 Zaenal Mutaqin <zaenalm@gmail.com>
-
- * docs/id/designers/language-basic-syntax/language-escaping.xml
- docs/id/designers/language-basic-syntax/language-math.xml
- docs/id/designers/language-basic-syntax/language-syntax-attributes.xml
- docs/id/designers/language-basic-syntax/language-syntax-comments.xml
- docs/id/designers/language-basic-syntax/language-syntax-functions.xml
- docs/id/designers/language-basic-syntax/language-syntax-quotes.xml
- docs/id/designers/language-basic-syntax/language-syntax-variables.xml
- docs/id/designers/language-builtin-functions/language-function-capture.xml
- docs/id/designers/language-builtin-functions/language-function-config-load.xml
- docs/id/designers/language-builtin-functions/language-function-foreach.xml
- docs/id/designers/language-builtin-functions/language-function-if.xml
- docs/id/designers/language-builtin-functions/language-function-include-php.xml
- docs/id/designers/language-builtin-functions/language-function-include.xml
- docs/id/designers/language-builtin-functions/language-function-insert.xml
- docs/id/designers/language-builtin-functions/language-function-ldelim.xml
- docs/id/designers/language-builtin-functions/language-function-literal.xml
- docs/id/designers/language-builtin-functions/language-function-php.xml
- docs/id/designers/language-builtin-functions/language-function-section.xml
- docs/id/designers/language-builtin-functions/language-function-strip.xml
- docs/id/designers/language-custom-functions/language-function-assign.xml
- docs/id/designers/language-custom-functions/language-function-counter.xml
- docs/id/designers/language-custom-functions/language-function-cycle.xml
- docs/id/designers/language-custom-functions/language-function-debug.xml
- docs/id/designers/language-custom-functions/language-function-eval.xml
- docs/id/designers/language-custom-functions/language-function-fetch.xml
- docs/id/designers/language-custom-functions/language-function-html-checkboxes.xml
- docs/id/designers/language-custom-functions/language-function-html-image.xml
- docs/id/designers/language-custom-functions/language-function-html-options.xml
- docs/id/designers/language-custom-functions/language-function-html-radios.xml
- docs/id/designers/language-custom-functions/language-function-html-select-date.xml
- docs/id/designers/language-custom-functions/language-function-html-select-time.xml
- docs/id/designers/language-custom-functions/language-function-html-table.xml
- docs/id/designers/language-custom-functions/language-function-mailto.xml
- docs/id/designers/language-custom-functions/language-function-math.xml
- docs/id/designers/language-custom-functions/language-function-popup-init.xml
- docs/id/designers/language-custom-functions/language-function-popup.xml
- docs/id/designers/language-custom-functions/language-function-textformat.xml
- docs/id/designers/language-modifiers/language-modifier-capitalize.xml
- docs/id/designers/language-modifiers/language-modifier-cat.xml
- docs/id/designers/language-modifiers/language-modifier-count-characters.xml
- docs/id/designers/language-modifiers/language-modifier-count-paragraphs.xml
- docs/id/designers/language-modifiers/language-modifier-count-sentences.xml
- docs/id/designers/language-modifiers/language-modifier-count-words.xml
- docs/id/designers/language-modifiers/language-modifier-date-format.xml
- docs/id/designers/language-modifiers/language-modifier-default.xml
- docs/id/designers/language-modifiers/language-modifier-escape.xml
- docs/id/designers/language-modifiers/language-modifier-indent.xml
- docs/id/designers/language-modifiers/language-modifier-lower.xml
- docs/id/designers/language-modifiers/language-modifier-nl2br.xml
- docs/id/designers/language-modifiers/language-modifier-regex-replace.xml
- docs/id/designers/language-modifiers/language-modifier-replace.xml
- docs/id/designers/language-modifiers/language-modifier-spacify.xml
- docs/id/designers/language-modifiers/language-modifier-string-format.xml
- docs/id/designers/language-modifiers/language-modifier-strip-tags.xml
- docs/id/designers/language-modifiers/language-modifier-strip.xml
- docs/id/designers/language-modifiers/language-modifier-truncate.xml
- docs/id/designers/language-modifiers/language-modifier-upper.xml
- docs/id/designers/language-modifiers/language-modifier-wordwrap.xml
- docs/id/designers/language-variables/language-assigned-variables.xml
- docs/id/designers/language-variables/language-config-variables.xml
- docs/id/designers/language-variables/language-variables-smarty.xml
- docs/id/programmers/advanced-features/advanced-features-objects.xml
- docs/id/programmers/advanced-features/advanced-features-outputfilters.xml
- docs/id/programmers/advanced-features/advanced-features-postfilters.xml
- docs/id/programmers/advanced-features/advanced-features-prefilters.xml
- docs/id/programmers/advanced-features/section-template-cache-handler-func.xml
- docs/id/programmers/advanced-features/template-resources.xml
- docs/id/programmers/api-functions/api-append-by-ref.xml
- docs/id/programmers/api-functions/api-append.xml
- docs/id/programmers/api-functions/api-assign-by-ref.xml
- docs/id/programmers/api-functions/api-assign.xml
- docs/id/programmers/api-functions/api-clear-all-assign.xml
- docs/id/programmers/api-functions/api-clear-all-cache.xml
- docs/id/programmers/api-functions/api-clear-assign.xml
- docs/id/programmers/api-functions/api-clear-cache.xml
- docs/id/programmers/api-functions/api-clear-compiled-tpl.xml
- docs/id/programmers/api-functions/api-clear-config.xml
- docs/id/programmers/api-functions/api-config-load.xml
- docs/id/programmers/api-functions/api-display.xml
- docs/id/programmers/api-functions/api-fetch.xml
- docs/id/programmers/api-functions/api-get-config-vars.xml
- docs/id/programmers/api-functions/api-get-registered-object.xml
- docs/id/programmers/api-functions/api-get-template-vars.xml
- docs/id/programmers/api-functions/api-is-cached.xml
- docs/id/programmers/api-functions/api-load-filter.xml
- docs/id/programmers/api-functions/api-register-block.xml
- docs/id/programmers/api-functions/api-register-compiler-function.xml
- docs/id/programmers/api-functions/api-register-function.xml
- docs/id/programmers/api-functions/api-register-modifier.xml
- docs/id/programmers/api-functions/api-register-object.xml
- docs/id/programmers/api-functions/api-register-outputfilter.xml
- docs/id/programmers/api-functions/api-register-postfilter.xml
- docs/id/programmers/api-functions/api-register-prefilter.xml
- docs/id/programmers/api-functions/api-register-resource.xml
- docs/id/programmers/api-functions/api-template-exists.xml
- docs/id/programmers/api-functions/api-trigger-error.xml
- docs/id/programmers/api-functions/api-unregister-block.xml
- docs/id/programmers/api-functions/api-unregister-compiler-function.xml
- docs/id/programmers/api-functions/api-unregister-function.xml
- docs/id/programmers/api-functions/api-unregister-modifier.xml
- docs/id/programmers/api-functions/api-unregister-object.xml
- docs/id/programmers/api-functions/api-unregister-outputfilter.xml
- docs/id/programmers/api-functions/api-unregister-postfilter.xml
- docs/id/programmers/api-functions/api-unregister-prefilter.xml
- docs/id/programmers/api-functions/api-unregister-resource.xml
- docs/id/programmers/api-variables/variable-autoload-filters.xml
- docs/id/programmers/api-variables/variable-cache-dir.xml
- docs/id/programmers/api-variables/variable-cache-handler-func.xml
- docs/id/programmers/api-variables/variable-cache-lifetime.xml
- docs/id/programmers/api-variables/variable-cache-modified-check.xml
- docs/id/programmers/api-variables/variable-caching.xml
- docs/id/programmers/api-variables/variable-compile-check.xml
- docs/id/programmers/api-variables/variable-compile-dir.xml
- docs/id/programmers/api-variables/variable-compile-id.xml
- docs/id/programmers/api-variables/variable-compiler-class.xml
- docs/id/programmers/api-variables/variable-config-booleanize.xml
- docs/id/programmers/api-variables/variable-config-dir.xml
- docs/id/programmers/api-variables/variable-config-fix-newlines.xml
- docs/id/programmers/api-variables/variable-config-overwrite.xml
- docs/id/programmers/api-variables/variable-config-read-hidden.xml
- docs/id/programmers/api-variables/variable-debug-tpl.xml
- docs/id/programmers/api-variables/variable-debugging-ctrl.xml
- docs/id/programmers/api-variables/variable-debugging.xml
- docs/id/programmers/api-variables/variable-default-modifiers.xml
- docs/id/programmers/api-variables/variable-default-resource-type.xml
- docs/id/programmers/api-variables/variable-default-template-handler-func.xml
- docs/id/programmers/api-variables/variable-error-reporting.xml
- docs/id/programmers/api-variables/variable-force-compile.xml
- docs/id/programmers/api-variables/variable-left-delimiter.xml
- docs/id/programmers/api-variables/variable-php-handling.xml
- docs/id/programmers/api-variables/variable-plugins-dir.xml
- docs/id/programmers/api-variables/variable-request-use-auto-globals.xml
- docs/id/programmers/api-variables/variable-request-vars-order.xml
- docs/id/programmers/api-variables/variable-right-delimiter.xml
- docs/id/programmers/api-variables/variable-secure-dir.xml
- docs/id/programmers/api-variables/variable-security-settings.xml
- docs/id/programmers/api-variables/variable-security.xml
- docs/id/programmers/api-variables/variable-template-dir.xml
- docs/id/programmers/api-variables/variable-trusted-dir.xml
- docs/id/programmers/api-variables/variable-use-sub-dirs.xml
- docs/id/programmers/caching/caching-cacheable.xml
- docs/id/programmers/caching/caching-groups.xml
- docs/id/programmers/caching/caching-multiple-caches.xml
- docs/id/programmers/caching/caching-setting-up.xml
- docs/id/programmers/plugins/plugins-block-functions.xml
- docs/id/programmers/plugins/plugins-compiler-functions.xml
- docs/id/programmers/plugins/plugins-functions.xml
- docs/id/programmers/plugins/plugins-howto.xml
- docs/id/programmers/plugins/plugins-inserts.xml
- docs/id/programmers/plugins/plugins-modifiers.xml
- docs/id/programmers/plugins/plugins-naming-conventions.xml
- docs/id/programmers/plugins/plugins-outputfilters.xml
- docs/id/programmers/plugins/plugins-prefilters-postfilters.xml
- docs/id/programmers/plugins/plugins-resources.xml
- docs/id/programmers/plugins/plugins-writing.xml:
- Typos correction and all translated now.
-
-2007-09-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/id/bookinfo.xml
- docs/id/getting-started.xml
- docs/id/language-defs.ent
- docs/id/language-snippets.ent
- docs/id/livedocs.ent
- docs/id/preface.xml:
- added indonesian docs - thanks Zaenal Mutaqin
-
- * docs/scripts/generate_web.php:
- raise pcre.backtrack_limit - thanks to takagi
-
-2007-09-16 Monte Ohrt <monte@ohrt.com>
-
- * libs/Smarty_Compiler.class.php:
- fix typo
-
-2007-08-22 George Miroshnikov <support@infinity.com.ua>
-
- * docs/ru/getting-started.xml
- docs/ru/getting-started.xml:
- Sync with EN.
-
-2007-08-01 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- add append feature to capture
-
-2007-06-24 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
-
- * docs/ja/getting-started.xml:
- sync with en.
-
-2007-06-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/Makefile.in:
- reverted accidently modified file
-
- * docs/Makefile.in
- docs/de/getting-started.xml:
- sync with en
-
- * docs/en/getting-started.xml:
- fixed link to ini_set(). thanks to Lee Yunyoung.
-
-2007-06-18 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
-
- * docs/ja/language-snippets.ent
- docs/ja/programmers/api-functions/api-register-outputfilter.xml
- docs/ja/programmers/api-functions/api-register-postfilter.xml
- docs/ja/programmers/api-functions/api-register-prefilter.xml:
- sync with en.
-
-2007-06-18 Danilo Buerger <danilo@blizzz.org>
-
- * docs/en/language-snippets.ent
- docs/en/programmers/api-functions/api-register-outputfilter.xml
- docs/en/programmers/api-functions/api-register-postfilter.xml
- docs/en/programmers/api-functions/api-register-prefilter.xml:
- Updated docs according to the changes from the previous commit
-
- * NEWS
- libs/Smarty.class.php:
- Added the ability to (un)register multiple filters of the same type with
- the same method name but different class name. Before it was not possible
- due to the fact that only the method name was used to distinguish between
- different filters of the same type. This does however not allow (same as
- before) to register multiple filters of the same type with the same method
- and class name (i.e. different instances of the same class).
-
-2007-05-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/compiler.assign.php:
- fixed typo
-
-2007-05-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed calling registered objects' methods with an empty argument list.
- thanks marcello
-
-2007-05-03 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
-
- * docs/ja/designers/language-variables.xml
- docs/ja/designers/language-builtin-functions/language-function-config-load.xml
- docs/ja/designers/language-builtin-functions/language-function-foreach.xml
- docs/ja/designers/language-builtin-functions/language-function-if.xml
- docs/ja/designers/language-modifiers/language-modifier-cat.xml
- docs/ja/designers/language-modifiers/language-modifier-wordwrap.xml
- docs/ja/designers/language-variables/language-variables-smarty.xml:
- sync with en.
-
-2007-05-03 Monte Ohrt <monte@ohrt.com>
-
- * docs/en/designers/language-variables.xml
- docs/en/designers/language-builtin-functions/language-function-config-load.xml
- docs/en/designers/language-builtin-functions/language-function-foreach.xml
- docs/en/designers/language-builtin-functions/language-function-if.xml
- docs/en/designers/language-modifiers/language-modifier-cat.xml
- docs/en/designers/language-modifiers/language-modifier-wordwrap.xml
- docs/en/designers/language-variables/language-variables-smarty.xml:
- update documentation corrections from marcello in the forums. Thanks
- marcello!
-
-2007-04-22 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
-
- * docs/ja/programmers/advanced-features.xml
- docs/ja/programmers/api-functions.xml
- docs/ja/programmers/api-variables.xml:
- corrected the garbled text.
-
-2007-04-21 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
-
- * docs/ja/bookinfo.xml
- docs/ja/getting-started.xml
- docs/ja/language-defs.ent
- docs/ja/language-snippets.ent
- docs/ja/livedocs.ent
- docs/ja/make_chm_index.html
- docs/ja/preface.xml
- docs/ja/translation.xml
- docs/ja/appendixes/bugs.xml
- docs/ja/appendixes/resources.xml
- docs/ja/appendixes/tips.xml
- docs/ja/appendixes/troubleshooting.xml
- docs/ja/designers/chapter-debugging-console.xml
- docs/ja/designers/config-files.xml
- docs/ja/designers/language-basic-syntax.xml
- docs/ja/designers/language-builtin-functions.xml
- docs/ja/designers/language-combining-modifiers.xml
- docs/ja/designers/language-custom-functions.xml
- docs/ja/designers/language-modifiers.xml
- docs/ja/designers/language-variables.xml
- docs/ja/designers/language-basic-syntax/language-escaping.xml
- docs/ja/designers/language-basic-syntax/language-math.xml
- docs/ja/designers/language-basic-syntax/language-syntax-attributes.xml
- docs/ja/designers/language-basic-syntax/language-syntax-comments.xml
- docs/ja/designers/language-basic-syntax/language-syntax-functions.xml
- docs/ja/designers/language-basic-syntax/language-syntax-quotes.xml
- docs/ja/designers/language-basic-syntax/language-syntax-variables.xml
- docs/ja/designers/language-builtin-functions/language-function-capture.xml
- docs/ja/designers/language-builtin-functions/language-function-config-load.xml
- docs/ja/designers/language-builtin-functions/language-function-foreach.xml
- docs/ja/designers/language-builtin-functions/language-function-if.xml
- docs/ja/designers/language-builtin-functions/language-function-include-php.xml
- docs/ja/designers/language-builtin-functions/language-function-include.xml
- docs/ja/designers/language-builtin-functions/language-function-insert.xml
- docs/ja/designers/language-builtin-functions/language-function-ldelim.xml
- docs/ja/designers/language-builtin-functions/language-function-literal.xml
- docs/ja/designers/language-builtin-functions/language-function-php.xml
- docs/ja/designers/language-builtin-functions/language-function-section.xml
- docs/ja/designers/language-builtin-functions/language-function-strip.xml
- docs/ja/designers/language-custom-functions/language-function-assign.xml
- docs/ja/designers/language-custom-functions/language-function-counter.xml
- docs/ja/designers/language-custom-functions/language-function-cycle.xml
- docs/ja/designers/language-custom-functions/language-function-debug.xml
- docs/ja/designers/language-custom-functions/language-function-eval.xml
- docs/ja/designers/language-custom-functions/language-function-fetch.xml
- docs/ja/designers/language-custom-functions/language-function-html-checkboxes.xml
- docs/ja/designers/language-custom-functions/language-function-html-image.xml
- docs/ja/designers/language-custom-functions/language-function-html-options.xml
- docs/ja/designers/language-custom-functions/language-function-html-radios.xml
- docs/ja/designers/language-custom-functions/language-function-html-select-date.xml
- docs/ja/designers/language-custom-functions/language-function-html-select-time.xml
- docs/ja/designers/language-custom-functions/language-function-html-table.xml
- docs/ja/designers/language-custom-functions/language-function-mailto.xml
- docs/ja/designers/language-custom-functions/language-function-math.xml
- docs/ja/designers/language-custom-functions/language-function-popup-init.xml
- docs/ja/designers/language-custom-functions/language-function-popup.xml
- docs/ja/designers/language-custom-functions/language-function-textformat.xml
- docs/ja/designers/language-modifiers/language-modifier-capitalize.xml
- docs/ja/designers/language-modifiers/language-modifier-cat.xml
- docs/ja/designers/language-modifiers/language-modifier-count-characters.xml
- docs/ja/designers/language-modifiers/language-modifier-count-paragraphs.xml
- docs/ja/designers/language-modifiers/language-modifier-count-sentences.xml
- docs/ja/designers/language-modifiers/language-modifier-count-words.xml
- docs/ja/designers/language-modifiers/language-modifier-date-format.xml
- docs/ja/designers/language-modifiers/language-modifier-default.xml
- docs/ja/designers/language-modifiers/language-modifier-escape.xml
- docs/ja/designers/language-modifiers/language-modifier-indent.xml
- docs/ja/designers/language-modifiers/language-modifier-lower.xml
- docs/ja/designers/language-modifiers/language-modifier-nl2br.xml
- docs/ja/designers/language-modifiers/language-modifier-regex-replace.xml
- docs/ja/designers/language-modifiers/language-modifier-replace.xml
- docs/ja/designers/language-modifiers/language-modifier-spacify.xml
- docs/ja/designers/language-modifiers/language-modifier-string-format.xml
- docs/ja/designers/language-modifiers/language-modifier-strip-tags.xml
- docs/ja/designers/language-modifiers/language-modifier-strip.xml
- docs/ja/designers/language-modifiers/language-modifier-truncate.xml
- docs/ja/designers/language-modifiers/language-modifier-upper.xml
- docs/ja/designers/language-modifiers/language-modifier-wordwrap.xml
- docs/ja/designers/language-variables/language-assigned-variables.xml
- docs/ja/designers/language-variables/language-config-variables.xml
- docs/ja/designers/language-variables/language-variables-smarty.xml
- docs/ja/programmers/advanced-features.xml
- docs/ja/programmers/api-functions.xml
- docs/ja/programmers/api-variables.xml
- docs/ja/programmers/caching.xml
- docs/ja/programmers/plugins.xml
- docs/ja/programmers/smarty-constants.xml
- docs/ja/programmers/advanced-features/advanced-features-objects.xml
- docs/ja/programmers/advanced-features/advanced-features-outputfilters.xml
- docs/ja/programmers/advanced-features/advanced-features-postfilters.xml
- docs/ja/programmers/advanced-features/advanced-features-prefilters.xml
- docs/ja/programmers/advanced-features/section-template-cache-handler-func.xml
- docs/ja/programmers/advanced-features/template-resources.xml
- docs/ja/programmers/api-functions/api-append-by-ref.xml
- docs/ja/programmers/api-functions/api-append.xml
- docs/ja/programmers/api-functions/api-assign-by-ref.xml
- docs/ja/programmers/api-functions/api-assign.xml
- docs/ja/programmers/api-functions/api-clear-all-assign.xml
- docs/ja/programmers/api-functions/api-clear-all-cache.xml
- docs/ja/programmers/api-functions/api-clear-assign.xml
- docs/ja/programmers/api-functions/api-clear-cache.xml
- docs/ja/programmers/api-functions/api-clear-compiled-tpl.xml
- docs/ja/programmers/api-functions/api-clear-config.xml
- docs/ja/programmers/api-functions/api-config-load.xml
- docs/ja/programmers/api-functions/api-display.xml
- docs/ja/programmers/api-functions/api-fetch.xml
- docs/ja/programmers/api-functions/api-get-config-vars.xml
- docs/ja/programmers/api-functions/api-get-registered-object.xml
- docs/ja/programmers/api-functions/api-get-template-vars.xml
- docs/ja/programmers/api-functions/api-is-cached.xml
- docs/ja/programmers/api-functions/api-load-filter.xml
- docs/ja/programmers/api-functions/api-register-block.xml
- docs/ja/programmers/api-functions/api-register-compiler-function.xml
- docs/ja/programmers/api-functions/api-register-function.xml
- docs/ja/programmers/api-functions/api-register-modifier.xml
- docs/ja/programmers/api-functions/api-register-object.xml
- docs/ja/programmers/api-functions/api-register-outputfilter.xml
- docs/ja/programmers/api-functions/api-register-postfilter.xml
- docs/ja/programmers/api-functions/api-register-prefilter.xml
- docs/ja/programmers/api-functions/api-register-resource.xml
- docs/ja/programmers/api-functions/api-template-exists.xml
- docs/ja/programmers/api-functions/api-trigger-error.xml
- docs/ja/programmers/api-functions/api-unregister-block.xml
- docs/ja/programmers/api-functions/api-unregister-compiler-function.xml
- docs/ja/programmers/api-functions/api-unregister-function.xml
- docs/ja/programmers/api-functions/api-unregister-modifier.xml
- docs/ja/programmers/api-functions/api-unregister-object.xml
- docs/ja/programmers/api-functions/api-unregister-outputfilter.xml
- docs/ja/programmers/api-functions/api-unregister-postfilter.xml
- docs/ja/programmers/api-functions/api-unregister-prefilter.xml
- docs/ja/programmers/api-functions/api-unregister-resource.xml
- docs/ja/programmers/api-variables/variable-autoload-filters.xml
- docs/ja/programmers/api-variables/variable-cache-dir.xml
- docs/ja/programmers/api-variables/variable-cache-handler-func.xml
- docs/ja/programmers/api-variables/variable-cache-lifetime.xml
- docs/ja/programmers/api-variables/variable-cache-modified-check.xml
- docs/ja/programmers/api-variables/variable-caching.xml
- docs/ja/programmers/api-variables/variable-compile-check.xml
- docs/ja/programmers/api-variables/variable-compile-dir.xml
- docs/ja/programmers/api-variables/variable-compile-id.xml
- docs/ja/programmers/api-variables/variable-compiler-class.xml
- docs/ja/programmers/api-variables/variable-config-booleanize.xml
- docs/ja/programmers/api-variables/variable-config-dir.xml
- docs/ja/programmers/api-variables/variable-config-fix-newlines.xml
- docs/ja/programmers/api-variables/variable-config-overwrite.xml
- docs/ja/programmers/api-variables/variable-config-read-hidden.xml
- docs/ja/programmers/api-variables/variable-debug-tpl.xml
- docs/ja/programmers/api-variables/variable-debugging-ctrl.xml
- docs/ja/programmers/api-variables/variable-debugging.xml
- docs/ja/programmers/api-variables/variable-default-modifiers.xml
- docs/ja/programmers/api-variables/variable-default-resource-type.xml
- docs/ja/programmers/api-variables/variable-default-template-handler-func.xml
- docs/ja/programmers/api-variables/variable-error-reporting.xml
- docs/ja/programmers/api-variables/variable-force-compile.xml
- docs/ja/programmers/api-variables/variable-left-delimiter.xml
- docs/ja/programmers/api-variables/variable-php-handling.xml
- docs/ja/programmers/api-variables/variable-plugins-dir.xml
- docs/ja/programmers/api-variables/variable-request-use-auto-globals.xml
- docs/ja/programmers/api-variables/variable-request-vars-order.xml
- docs/ja/programmers/api-variables/variable-right-delimiter.xml
- docs/ja/programmers/api-variables/variable-secure-dir.xml
- docs/ja/programmers/api-variables/variable-security-settings.xml
- docs/ja/programmers/api-variables/variable-security.xml
- docs/ja/programmers/api-variables/variable-template-dir.xml
- docs/ja/programmers/api-variables/variable-trusted-dir.xml
- docs/ja/programmers/api-variables/variable-use-sub-dirs.xml
- docs/ja/programmers/caching/caching-cacheable.xml
- docs/ja/programmers/caching/caching-groups.xml
- docs/ja/programmers/caching/caching-multiple-caches.xml
- docs/ja/programmers/caching/caching-setting-up.xml
- docs/ja/programmers/plugins/plugins-block-functions.xml
- docs/ja/programmers/plugins/plugins-compiler-functions.xml
- docs/ja/programmers/plugins/plugins-functions.xml
- docs/ja/programmers/plugins/plugins-howto.xml
- docs/ja/programmers/plugins/plugins-inserts.xml
- docs/ja/programmers/plugins/plugins-modifiers.xml
- docs/ja/programmers/plugins/plugins-naming-conventions.xml
- docs/ja/programmers/plugins/plugins-outputfilters.xml
- docs/ja/programmers/plugins/plugins-prefilters-postfilters.xml
- docs/ja/programmers/plugins/plugins-resources.xml
- docs/ja/programmers/plugins/plugins-writing.xml:
- added Japanese translation files.
-
- * docs/Makefile.in
- docs/configure.in:
- added the configuration for Japanese translation.
-
-2007-04-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/en/programmers/smarty-constants.xml:
- fixed typo
-
-2007-04-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/ru/getting-started.xml:
- fixed uri for Zend Accelerator
-
-2007-04-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/de/getting-started.xml
- docs/es/getting-started.xml
- docs/it/getting-started.xml
- docs/pt_BR/getting-started.xml:
- fixed uris for php-accelerator
-
-2007-03-08 Monte Ohrt <monte@ohrt.com>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers
-
-2007-03-07 Monte Ohrt <monte@ohrt.com>
-
- * (Smarty_2_6_18)
- NEWS:
- update NEWS file with patch
-
- * (Smarty_2_6_18)
- docs/en/designers/language-builtin-functions/language-function-section.xml:
- note the fact that section loop will accept an integer
-
-2007-03-06 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- fix html_select_date separator when parts are missing (thanks to kayk for
- the patch)
-
-2007-03-06 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- bumped version number
-
- * NEWS:
- added release headline
-
- * libs/internals/core.write_compiled_include.php:
- fixed detection of non-cached block when writing compiled includes
-
-2007-03-01 Danilo Buerger <danilo@blizzz.org>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- Applied boots clean up patch and removed commented out code.
- Updated NEWS file
-
-2007-02-27 Danilo Buerger <danilo@blizzz.org>
-
- * NEWS
- docs/en/designers/language-modifiers/language-modifier-date-format.xml
- libs/internals/core.write_file.php
- libs/plugins/modifier.date_format.php:
- Updated smarty_core_write_file() and smarty_modifier_date_format() to speed
- up Windows detection.
- Emulated more parameters for Windows in smarty_modifier_date_format() and
- fixed some old ones.
- Updated the docs to tell what parameters are emulated on Windows.
- Updated NEWS file.
-
- * NEWS:
- Updated NEWS file to reflect changes commited in the last revision
-
-2007-02-27 Monte Ohrt <monte@ohrt.com>
-
- * docs/en/appendixes/troubleshooting.xml:
- fix typo
-
-2007-02-27 Danilo Buerger <danilo@blizzz.org>
-
- * libs/Smarty_Compiler.class.php:
- Modified _(push|pop)_cacheable_state() to embedd alternate syntax. See this
- bug report: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=10502
-
-2007-02-26 Peter 'Mash' Morgan <pm@daffodil.uk.com>
-
- * docs/en/designers/language-custom-functions/language-function-html-options.xml:
- Fix incorrect var name
-
-2007-02-23 Monte Ohrt <monte@ohrt.com>
-
- * libs/Smarty_Compiler.class.php:
- escape creating of language=php from interleaving
-
- * libs/Smarty_Compiler.class.php:
- add removed line back in
-
- * libs/Smarty_Compiler.class.php:
- fix up last patch, remove unnecessary lines
-
- * libs/Smarty_Compiler.class.php:
- fix situation when no compiled tags are present
-
- * libs/Smarty_Compiler.class.php:
- fix problem with php open tags generated from tag interleaving
-
-2007-02-06 boots <jayboots@yahoo.com>
-
- * docs/en/programmers/advanced-features/template-resources.xml:
- Correct default template handler function example.
-
-2007-01-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/modifier.truncate.php:
- fixed handling of $etc in the truncate modifier when $etc is longer
- than $length.
-
- thanks to Sylvinus!
-
-2007-01-10 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/plugins/modifier.date_format.php
- libs/plugins/modifier.date_format.php:
- fix handling of %I with mysql timestamps
-
- Thanks to Danilo Buerger
-
- * NEWS
- libs/internals/core.write_file.php:
- Better recognize Windows filesystems to reduce warnings
-
- * NEWS
- libs/plugins/modifier.date_format.php:
- Emulate %R in the date_format modifier on Windows
-
- Thanks to Danilo Buerger
-
-2006-12-10 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/getting-started.xml:
- fix build
-
- * docs/fr/language-snippets.ent
- docs/fr/designers/language-builtin-functions/language-function-include-php.xml
- docs/fr/designers/language-modifiers/language-modifier-truncate.xml
- docs/fr/designers/language-variables/language-variables-smarty.xml:
- sync with EN
-
-2006-12-02 Peter 'Mash' Morgan <pm@daffodil.uk.com>
-
- * docs/en/designers/language-builtin-functions/language-function-include-php.xml:
- Tidy example, speeling andd add links
-
- * docs/en/getting-started.xml:
- Add/correct entities
-
- * docs/entities/global.ent:
- Fix entities (strange)
-
-2006-12-01 Monte Ohrt <monte@ohrt.com>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update dev version numbers
-
-2006-12-01 boots <jayboots@yahoo.com>
-
- * (Smarty_2_6_16)
- NEWS:
- Fixed replacement bug introduced in trimwhitespaces output filter that
- was introduced in the last release.
-
- Thanks to Spuerhund from the forums.
-
- * (Smarty_2_6_16)
- libs/plugins/outputfilter.trimwhitespace.php:
- Fixed replacement bug introduced by last changes.
-
- Thanks to Spuerhund from the forums.
-
-2006-11-30 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- docs/en/designers/language-modifiers/language-modifier-truncate.xml
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update dev version numbers, fix manual typo
-
-2006-11-22 George Miroshnikov <support@infinity.com.ua>
-
- * docs/ru/getting-started.xml
- docs/ru/language-snippets.ent:
- sync with EN
-
- * docs/en/getting-started.xml:
- replaced hardcoded path separator with PATH_SEPARATOR constant
-
-2006-11-20 boots <jayboots@yahoo.com>
-
- * libs/plugins/modifier.debug_print_var.php:
- fix depth formatting of arrays and objects in modifier debug_print_var
-
-2006-11-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/en/designers/language-variables/language-variables-smarty.xml:
- fixed typo. thanks jonez.
-
-2006-11-08 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/internals/core.write_file.php:
- change file writing semantics in smarty_core_write_file()
-
- This avoids unlink() unless rename() fails or a Windows system is detected
-
- see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=6956
-
- Thanks to c960657 from the forums.
-
-2006-11-07 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/debug.tpl:
- update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug
- output and apply a Smarty based color scheme
-
- see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=7178
-
- thanks to cybot from the forums!
-
- * NEWS
- libs/plugins/modifier.debug_print_var.php:
- enhance reporting precision of debug_print_var modifier
-
- see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=9281
-
- thanks to cybot from the forums
-
-2006-11-01 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- make html_select_date work consistently with 0000-00-00 00:00:00 and
- 0000-00-00 inputs
-
- Thanks to cybot from forums
-
-2006-10-16 George Miroshnikov <support@infinity.com.ua>
-
- * docs/en/language-snippets.ent:
- minor typo fix - &$class doesn't make sense.
-
-2006-10-14 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/designers/language-basic-syntax.xml
- docs/fr/designers/language-builtin-functions.xml
- docs/fr/designers/language-basic-syntax/language-syntax-attributes.xml
- docs/fr/designers/language-basic-syntax/language-syntax-comments.xml
- docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml
- docs/fr/designers/language-builtin-functions/language-function-capture.xml
- docs/fr/designers/language-builtin-functions/language-function-php.xml
- docs/fr/designers/language-builtin-functions/language-function-section.xml
- docs/fr/designers/language-custom-functions/language-function-popup-init.xml
- docs/fr/designers/language-modifiers/language-modifier-escape.xml
- docs/fr/programmers/api-functions/api-display.xml
- docs/fr/programmers/plugins/plugins-inserts.xml:
- sync with EN
-
-2006-10-14 Fernando Correa da Conceição <fernando_conceicao@yahoo.com.br>
-
- * docs/pt_BR/programmers/api-variables/variable-error-reporting.xml:
- New Translation
-
- * docs/pt_BR/designers/language-basic-syntax/language-escaping.xml
- docs/pt_BR/designers/language-basic-syntax/language-syntax-variables.xml:
- New Translations
-
- * docs/pt_BR/translation.xml:
- Used in revcheck
-
- * docs/pt_BR/getting-started.xml
- docs/pt_BR/language-snippets.ent
- docs/pt_BR/make_chm_index.html
- docs/pt_BR/preface.xml
- docs/pt_BR/appendixes/resources.xml
- docs/pt_BR/appendixes/troubleshooting.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-capitalize.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-cat.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-count-characters.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-count-paragraphs.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-count-sentences.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-count-words.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-date-format.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-default.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-escape.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-indent.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-lower.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-nl2br.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-regex-replace.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-replace.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-spacify.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-string-format.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-strip-tags.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-strip.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-truncate.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-upper.xml
- docs/pt_BR/designers/language-modifiers/language-modifier-wordwrap.xml
- docs/pt_BR/designers/language-variables/language-assigned-variables.xml
- docs/pt_BR/designers/language-variables/language-config-variables.xml
- docs/pt_BR/designers/language-variables/language-variables-smarty.xml
- docs/pt_BR/programmers/advanced-features.xml
- docs/pt_BR/programmers/api-functions.xml
- docs/pt_BR/programmers/api-variables.xml
- docs/pt_BR/programmers/caching.xml
- docs/pt_BR/programmers/plugins.xml
- docs/pt_BR/programmers/smarty-constants.xml
- docs/pt_BR/programmers/advanced-features/advanced-features-objects.xml
- docs/pt_BR/programmers/advanced-features/advanced-features-outputfilters.xml
- docs/pt_BR/programmers/advanced-features/advanced-features-postfilters.xml
- docs/pt_BR/programmers/advanced-features/advanced-features-prefilters.xml
- docs/pt_BR/programmers/advanced-features/section-template-cache-handler-func.xml
- docs/pt_BR/programmers/advanced-features/template-resources.xml
- docs/pt_BR/programmers/api-functions/api-append-by-ref.xml
- docs/pt_BR/programmers/api-functions/api-append.xml
- docs/pt_BR/programmers/api-functions/api-assign-by-ref.xml
- docs/pt_BR/programmers/api-functions/api-assign.xml
- docs/pt_BR/programmers/api-functions/api-clear-all-assign.xml
- docs/pt_BR/programmers/api-functions/api-clear-all-cache.xml
- docs/pt_BR/programmers/api-functions/api-clear-assign.xml
- docs/pt_BR/programmers/api-functions/api-clear-cache.xml
- docs/pt_BR/programmers/api-functions/api-clear-compiled-tpl.xml
- docs/pt_BR/programmers/api-functions/api-clear-config.xml
- docs/pt_BR/programmers/api-functions/api-config-load.xml
- docs/pt_BR/programmers/api-functions/api-display.xml
- docs/pt_BR/programmers/api-functions/api-fetch.xml
- docs/pt_BR/programmers/api-functions/api-get-config-vars.xml
- docs/pt_BR/programmers/api-functions/api-get-registered-object.xml
- docs/pt_BR/programmers/api-functions/api-get-template-vars.xml
- docs/pt_BR/programmers/api-functions/api-is-cached.xml
- docs/pt_BR/programmers/api-functions/api-load-filter.xml
- docs/pt_BR/programmers/api-functions/api-register-block.xml
- docs/pt_BR/programmers/api-functions/api-register-compiler-function.xml
- docs/pt_BR/programmers/api-functions/api-register-function.xml
- docs/pt_BR/programmers/api-functions/api-register-modifier.xml
- docs/pt_BR/programmers/api-functions/api-register-object.xml
- docs/pt_BR/programmers/api-functions/api-register-outputfilter.xml
- docs/pt_BR/programmers/api-functions/api-register-postfilter.xml
- docs/pt_BR/programmers/api-functions/api-register-prefilter.xml
- docs/pt_BR/programmers/api-functions/api-register-resource.xml
- docs/pt_BR/programmers/api-functions/api-template-exists.xml
- docs/pt_BR/programmers/api-functions/api-trigger-error.xml
- docs/pt_BR/programmers/api-functions/api-unregister-block.xml
- docs/pt_BR/programmers/api-functions/api-unregister-compiler-function.xml
- docs/pt_BR/programmers/api-functions/api-unregister-function.xml
- docs/pt_BR/programmers/api-functions/api-unregister-modifier.xml
- docs/pt_BR/programmers/api-functions/api-unregister-object.xml
- docs/pt_BR/programmers/api-functions/api-unregister-outputfilter.xml
- docs/pt_BR/programmers/api-functions/api-unregister-postfilter.xml
- docs/pt_BR/programmers/api-functions/api-unregister-prefilter.xml
- docs/pt_BR/programmers/api-functions/api-unregister-resource.xml
- docs/pt_BR/programmers/api-variables/variable-autoload-filters.xml
- docs/pt_BR/programmers/api-variables/variable-cache-dir.xml
- docs/pt_BR/programmers/api-variables/variable-cache-handler-func.xml
- docs/pt_BR/programmers/api-variables/variable-cache-lifetime.xml
- docs/pt_BR/programmers/api-variables/variable-cache-modified-check.xml
- docs/pt_BR/programmers/api-variables/variable-caching.xml
- docs/pt_BR/programmers/api-variables/variable-compile-check.xml
- docs/pt_BR/programmers/api-variables/variable-compile-dir.xml
- docs/pt_BR/programmers/api-variables/variable-compile-id.xml
- docs/pt_BR/programmers/api-variables/variable-compiler-class.xml
- docs/pt_BR/programmers/api-variables/variable-config-booleanize.xml
- docs/pt_BR/programmers/api-variables/variable-config-dir.xml
- docs/pt_BR/programmers/api-variables/variable-config-fix-newlines.xml
- docs/pt_BR/programmers/api-variables/variable-config-overwrite.xml
- docs/pt_BR/programmers/api-variables/variable-config-read-hidden.xml
- docs/pt_BR/programmers/api-variables/variable-debug-tpl.xml
- docs/pt_BR/programmers/api-variables/variable-debugging-ctrl.xml
- docs/pt_BR/programmers/api-variables/variable-debugging.xml
- docs/pt_BR/programmers/api-variables/variable-default-modifiers.xml
- docs/pt_BR/programmers/api-variables/variable-default-resource-type.xml
- docs/pt_BR/programmers/api-variables/variable-default-template-handler-func.xml
- docs/pt_BR/programmers/api-variables/variable-force-compile.xml
- docs/pt_BR/programmers/api-variables/variable-global-assign.xml
- docs/pt_BR/programmers/api-variables/variable-left-delimiter.xml
- docs/pt_BR/programmers/api-variables/variable-php-handling.xml
- docs/pt_BR/programmers/api-variables/variable-plugins-dir.xml
- docs/pt_BR/programmers/api-variables/variable-request-use-auto-globals.xml
- docs/pt_BR/programmers/api-variables/variable-request-vars-order.xml
- docs/pt_BR/programmers/api-variables/variable-right-delimiter.xml
- docs/pt_BR/programmers/api-variables/variable-secure-dir.xml
- docs/pt_BR/programmers/api-variables/variable-security-settings.xml
- docs/pt_BR/programmers/api-variables/variable-security.xml
- docs/pt_BR/programmers/api-variables/variable-template-dir.xml
- docs/pt_BR/programmers/api-variables/variable-trusted-dir.xml
- docs/pt_BR/programmers/api-variables/variable-undefined.xml
- docs/pt_BR/programmers/api-variables/variable-use-sub-dirs.xml
- docs/pt_BR/programmers/caching/caching-cacheable.xml
- docs/pt_BR/programmers/caching/caching-groups.xml
- docs/pt_BR/programmers/caching/caching-multiple-caches.xml
- docs/pt_BR/programmers/caching/caching-setting-up.xml
- docs/pt_BR/programmers/plugins/plugins-block-functions.xml
- docs/pt_BR/programmers/plugins/plugins-compiler-functions.xml
- docs/pt_BR/programmers/plugins/plugins-functions.xml
- docs/pt_BR/programmers/plugins/plugins-howto.xml
- docs/pt_BR/programmers/plugins/plugins-inserts.xml
- docs/pt_BR/programmers/plugins/plugins-modifiers.xml
- docs/pt_BR/programmers/plugins/plugins-naming-conventions.xml
- docs/pt_BR/programmers/plugins/plugins-outputfilters.xml
- docs/pt_BR/programmers/plugins/plugins-prefilters-postfilters.xml
- docs/pt_BR/programmers/plugins/plugins-resources.xml
- docs/pt_BR/programmers/plugins/plugins-writing.xml:
- Big update. Revision tag for all files. Some updates. Now I can update it
-
-2006-10-09 Peter 'Mash' Morgan <pm@daffodil.uk.com>
-
- * docs/en/getting-started.xml
- docs/en/designers/language-basic-syntax.xml
- docs/en/designers/language-custom-functions/language-function-popup-init.xml
- docs/en/designers/language-modifiers/language-modifier-escape.xml
- docs/en/programmers/api-functions/api-display.xml
- docs/en/programmers/plugins/plugins-inserts.xml:
- Minor changes and corrections
-
- * docs/en/designers/language-basic-syntax.xml
- docs/en/designers/language-builtin-functions.xml
- docs/en/designers/language-basic-syntax/language-syntax-attributes.xml
- docs/en/designers/language-basic-syntax/language-syntax-comments.xml
- docs/en/designers/language-basic-syntax/language-syntax-quotes.xml
- docs/en/designers/language-modifiers/language-modifier-escape.xml:
- Minor formatting and error correction
-
- * docs/en/designers/language-builtin-functions/language-function-capture.xml
- docs/en/designers/language-builtin-functions/language-function-php.xml
- docs/en/designers/language-builtin-functions/language-function-section.xml:
- minor formatting and changes
-
- * docs/en/getting-started.xml:
- Tidied up formatting so more readable, tidied up the install to the paths
- are more clear (ta jj)
-
-2006-10-09 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/designers/language-builtin-functions/language-function-section.xml:
- sync with EN
-
-2006-10-08 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/designers/language-builtin-functions/language-function-php.xml
- docs/fr/designers/language-modifiers/language-modifier-escape.xml
- docs/fr/designers/language-variables/language-variables-smarty.xml
- docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml:
- fix build
-
- * docs/fr/designers/language-builtin-functions/language-function-strip.xml
- docs/fr/programmers/caching.xml
- docs/fr/programmers/smarty-constants.xml
- docs/fr/programmers/api-variables/variable-autoload-filters.xml
- docs/fr/programmers/api-variables/variable-cache-dir.xml
- docs/fr/programmers/api-variables/variable-cache-handler-func.xml
- docs/fr/programmers/api-variables/variable-cache-lifetime.xml
- docs/fr/programmers/api-variables/variable-cache-modified-check.xml
- docs/fr/programmers/api-variables/variable-caching.xml
- docs/fr/programmers/api-variables/variable-compile-check.xml
- docs/fr/programmers/api-variables/variable-compile-dir.xml
- docs/fr/programmers/api-variables/variable-compile-id.xml
- docs/fr/programmers/api-variables/variable-compiler-class.xml
- docs/fr/programmers/api-variables/variable-config-booleanize.xml
- docs/fr/programmers/api-variables/variable-config-dir.xml
- docs/fr/programmers/api-variables/variable-config-fix-newlines.xml
- docs/fr/programmers/api-variables/variable-config-overwrite.xml
- docs/fr/programmers/api-variables/variable-config-read-hidden.xml
- docs/fr/programmers/api-variables/variable-debug-tpl.xml
- docs/fr/programmers/api-variables/variable-debugging-ctrl.xml
- docs/fr/programmers/api-variables/variable-debugging.xml
- docs/fr/programmers/api-variables/variable-default-modifiers.xml
- docs/fr/programmers/api-variables/variable-default-resource-type.xml
- docs/fr/programmers/api-variables/variable-default-template-handler-func.xml
- docs/fr/programmers/api-variables/variable-error-reporting.xml
- docs/fr/programmers/api-variables/variable-force-compile.xml
- docs/fr/programmers/api-variables/variable-left-delimiter.xml
- docs/fr/programmers/api-variables/variable-php-handling.xml
- docs/fr/programmers/api-variables/variable-plugins-dir.xml
- docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml
- docs/fr/programmers/api-variables/variable-request-vars-order.xml
- docs/fr/programmers/api-variables/variable-right-delimiter.xml
- docs/fr/programmers/api-variables/variable-secure-dir.xml
- docs/fr/programmers/api-variables/variable-security-settings.xml
- docs/fr/programmers/api-variables/variable-security.xml
- docs/fr/programmers/api-variables/variable-template-dir.xml
- docs/fr/programmers/api-variables/variable-trusted-dir.xml
- docs/fr/programmers/api-variables/variable-use-sub-dirs.xml
- docs/fr/programmers/caching/caching-cacheable.xml
- docs/fr/programmers/caching/caching-groups.xml
- docs/fr/programmers/caching/caching-multiple-caches.xml
- docs/fr/programmers/caching/caching-setting-up.xml
- docs/fr/programmers/plugins/plugins-block-functions.xml
- docs/fr/programmers/plugins/plugins-compiler-functions.xml
- docs/fr/programmers/plugins/plugins-functions.xml
- docs/fr/programmers/plugins/plugins-inserts.xml
- docs/fr/programmers/plugins/plugins-modifiers.xml
- docs/fr/programmers/plugins/plugins-naming-conventions.xml
- docs/fr/programmers/plugins/plugins-outputfilters.xml
- docs/fr/programmers/plugins/plugins-prefilters-postfilters.xml
- docs/fr/programmers/plugins/plugins-resources.xml
- docs/fr/programmers/plugins/plugins-writing.xml:
- sync with EN
-
-2006-10-07 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/programmers/advanced-features/advanced-features-objects.xml
- docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml
- docs/fr/programmers/advanced-features/advanced-features-postfilters.xml
- docs/fr/programmers/advanced-features/advanced-features-prefilters.xml
- docs/fr/programmers/advanced-features/section-template-cache-handler-func.xml
- docs/fr/programmers/advanced-features/template-resources.xml
- docs/fr/programmers/api-functions/api-append-by-ref.xml
- docs/fr/programmers/api-functions/api-append.xml
- docs/fr/programmers/api-functions/api-assign-by-ref.xml
- docs/fr/programmers/api-functions/api-assign.xml
- docs/fr/programmers/api-functions/api-clear-all-assign.xml
- docs/fr/programmers/api-functions/api-clear-all-cache.xml
- docs/fr/programmers/api-functions/api-clear-assign.xml
- docs/fr/programmers/api-functions/api-clear-cache.xml
- docs/fr/programmers/api-functions/api-clear-compiled-tpl.xml
- docs/fr/programmers/api-functions/api-clear-config.xml
- docs/fr/programmers/api-functions/api-config-load.xml
- docs/fr/programmers/api-functions/api-display.xml
- docs/fr/programmers/api-functions/api-fetch.xml
- docs/fr/programmers/api-functions/api-get-config-vars.xml
- docs/fr/programmers/api-functions/api-get-registered-object.xml
- docs/fr/programmers/api-functions/api-get-template-vars.xml
- docs/fr/programmers/api-functions/api-is-cached.xml
- docs/fr/programmers/api-functions/api-load-filter.xml
- docs/fr/programmers/api-functions/api-register-block.xml
- docs/fr/programmers/api-functions/api-register-compiler-function.xml
- docs/fr/programmers/api-functions/api-register-function.xml
- docs/fr/programmers/api-functions/api-register-modifier.xml
- docs/fr/programmers/api-functions/api-register-object.xml
- docs/fr/programmers/api-functions/api-register-outputfilter.xml
- docs/fr/programmers/api-functions/api-register-postfilter.xml
- docs/fr/programmers/api-functions/api-register-prefilter.xml
- docs/fr/programmers/api-functions/api-register-resource.xml
- docs/fr/programmers/api-functions/api-template-exists.xml
- docs/fr/programmers/api-functions/api-trigger-error.xml
- docs/fr/programmers/api-functions/api-unregister-block.xml
- docs/fr/programmers/api-functions/api-unregister-compiler-function.xml
- docs/fr/programmers/api-functions/api-unregister-function.xml
- docs/fr/programmers/api-functions/api-unregister-modifier.xml
- docs/fr/programmers/api-functions/api-unregister-object.xml
- docs/fr/programmers/api-functions/api-unregister-outputfilter.xml
- docs/fr/programmers/api-functions/api-unregister-postfilter.xml
- docs/fr/programmers/api-functions/api-unregister-prefilter.xml
- docs/fr/programmers/api-functions/api-unregister-resource.xml:
- sync with EN
-
-2006-10-03 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/designers/language-custom-functions/language-function-html-select-time.xml
- docs/fr/designers/language-custom-functions/language-function-html-table.xml
- docs/fr/designers/language-custom-functions/language-function-mailto.xml
- docs/fr/designers/language-custom-functions/language-function-math.xml
- docs/fr/designers/language-custom-functions/language-function-popup-init.xml
- docs/fr/designers/language-custom-functions/language-function-popup.xml
- docs/fr/designers/language-custom-functions/language-function-textformat.xml
- docs/fr/designers/language-modifiers/language-modifier-capitalize.xml
- docs/fr/designers/language-modifiers/language-modifier-cat.xml
- docs/fr/designers/language-modifiers/language-modifier-count-characters.xml
- docs/fr/designers/language-modifiers/language-modifier-count-paragraphs.xml
- docs/fr/designers/language-modifiers/language-modifier-count-sentences.xml
- docs/fr/designers/language-modifiers/language-modifier-count-words.xml
- docs/fr/designers/language-modifiers/language-modifier-date-format.xml
- docs/fr/designers/language-modifiers/language-modifier-default.xml
- docs/fr/designers/language-modifiers/language-modifier-escape.xml
- docs/fr/designers/language-modifiers/language-modifier-indent.xml
- docs/fr/designers/language-modifiers/language-modifier-lower.xml
- docs/fr/designers/language-modifiers/language-modifier-nl2br.xml
- docs/fr/designers/language-modifiers/language-modifier-regex-replace.xml
- docs/fr/designers/language-modifiers/language-modifier-replace.xml
- docs/fr/designers/language-modifiers/language-modifier-spacify.xml
- docs/fr/designers/language-modifiers/language-modifier-string-format.xml
- docs/fr/designers/language-modifiers/language-modifier-strip-tags.xml
- docs/fr/designers/language-modifiers/language-modifier-strip.xml
- docs/fr/designers/language-modifiers/language-modifier-truncate.xml
- docs/fr/designers/language-modifiers/language-modifier-upper.xml
- docs/fr/designers/language-modifiers/language-modifier-wordwrap.xml
- docs/fr/designers/language-variables/language-assigned-variables.xml
- docs/fr/designers/language-variables/language-config-variables.xml
- docs/fr/designers/language-variables/language-variables-smarty.xml:
- sync with EN
-
-2006-10-01 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/designers/language-builtin-functions/language-function-include-php.xml
- docs/fr/designers/language-builtin-functions/language-function-include.xml
- docs/fr/designers/language-builtin-functions/language-function-insert.xml
- docs/fr/designers/language-builtin-functions/language-function-ldelim.xml
- docs/fr/designers/language-builtin-functions/language-function-literal.xml
- docs/fr/designers/language-builtin-functions/language-function-php.xml
- docs/fr/designers/language-custom-functions/language-function-assign.xml
- docs/fr/designers/language-custom-functions/language-function-counter.xml
- docs/fr/designers/language-custom-functions/language-function-cycle.xml
- docs/fr/designers/language-custom-functions/language-function-debug.xml
- docs/fr/designers/language-custom-functions/language-function-eval.xml
- docs/fr/designers/language-custom-functions/language-function-fetch.xml
- docs/fr/designers/language-custom-functions/language-function-html-checkboxes.xml
- docs/fr/designers/language-custom-functions/language-function-html-image.xml
- docs/fr/designers/language-custom-functions/language-function-html-options.xml
- docs/fr/designers/language-custom-functions/language-function-html-radios.xml
- docs/fr/designers/language-custom-functions/language-function-html-select-date.xml:
- sync with EN
-
-2006-09-30 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/getting-started.xml:
- fix build
-
- * docs/fr/designers/chapter-debugging-console.xml
- docs/fr/designers/config-files.xml
- docs/fr/designers/language-builtin-functions.xml
- docs/fr/designers/language-modifiers.xml
- docs/fr/designers/language-variables.xml
- docs/fr/designers/language-basic-syntax/language-escaping.xml
- docs/fr/designers/language-basic-syntax/language-math.xml
- docs/fr/designers/language-basic-syntax/language-syntax-comments.xml
- docs/fr/designers/language-basic-syntax/language-syntax-functions.xml
- docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml
- docs/fr/designers/language-basic-syntax/language-syntax-variables.xml
- docs/fr/designers/language-builtin-functions/language-function-capture.xml
- docs/fr/designers/language-builtin-functions/language-function-config-load.xml
- docs/fr/designers/language-builtin-functions/language-function-foreach.xml
- docs/fr/designers/language-builtin-functions/language-function-if.xml:
- sync with EN
-
- * docs/fr/getting-started.xml
- docs/fr/language-snippets.ent
- docs/fr/appendixes/resources.xml
- docs/fr/appendixes/tips.xml
- docs/fr/appendixes/troubleshooting.xml:
- sync with EN
-
-2006-09-27 Peter 'Mash' Morgan <pm@daffodil.uk.com>
-
- * docs/en/designers/language-builtin-functions/language-function-section.xml:
- Minor tweaks and corrections
-
- * docs/en/getting-started.xml
- docs/en/designers/chapter-debugging-console.xml
- docs/en/designers/language-basic-syntax/language-syntax-comments.xml
- docs/en/designers/language-custom-functions/language-function-html-image.xml
- docs/en/designers/language-custom-functions/language-function-html-options.xml
- docs/en/designers/language-custom-functions/language-function-html-radios.xml
- docs/en/designers/language-custom-functions/language-function-html-select-date.xml
- docs/en/designers/language-custom-functions/language-function-html-select-time.xml
- docs/en/designers/language-custom-functions/language-function-html-table.xml
- docs/en/designers/language-custom-functions/language-function-mailto.xml
- docs/en/designers/language-custom-functions/language-function-popup-init.xml
- docs/en/designers/language-custom-functions/language-function-textformat.xml
- docs/en/designers/language-variables/language-config-variables.xml
- docs/en/designers/language-variables/language-variables-smarty.xml:
- Add literal tags to html, general formatting
-
- * docs/en/getting-started.xml
- docs/en/appendixes/resources.xml
- docs/en/appendixes/tips.xml
- docs/en/appendixes/troubleshooting.xml
- docs/en/designers/config-files.xml
- docs/en/programmers/caching.xml
- docs/en/programmers/smarty-constants.xml
- docs/en/programmers/advanced-features/advanced-features-objects.xml
- docs/en/programmers/advanced-features/advanced-features-outputfilters.xml
- docs/en/programmers/advanced-features/advanced-features-postfilters.xml
- docs/en/programmers/advanced-features/advanced-features-prefilters.xml
- docs/en/programmers/advanced-features/section-template-cache-handler-func.xml
- docs/en/programmers/advanced-features/template-resources.xml
- docs/en/programmers/api-variables/variable-autoload-filters.xml
- docs/en/programmers/api-variables/variable-cache-dir.xml
- docs/en/programmers/api-variables/variable-cache-handler-func.xml
- docs/en/programmers/api-variables/variable-cache-lifetime.xml
- docs/en/programmers/api-variables/variable-cache-modified-check.xml
- docs/en/programmers/api-variables/variable-caching.xml
- docs/en/programmers/api-variables/variable-compile-check.xml
- docs/en/programmers/api-variables/variable-compile-dir.xml
- docs/en/programmers/api-variables/variable-compile-id.xml
- docs/en/programmers/api-variables/variable-config-booleanize.xml
- docs/en/programmers/api-variables/variable-config-dir.xml
- docs/en/programmers/api-variables/variable-config-fix-newlines.xml
- docs/en/programmers/api-variables/variable-config-overwrite.xml
- docs/en/programmers/api-variables/variable-config-read-hidden.xml
- docs/en/programmers/api-variables/variable-debug-tpl.xml
- docs/en/programmers/api-variables/variable-debugging-ctrl.xml
- docs/en/programmers/api-variables/variable-debugging.xml
- docs/en/programmers/api-variables/variable-default-modifiers.xml
- docs/en/programmers/api-variables/variable-default-resource-type.xml
- docs/en/programmers/api-variables/variable-error-reporting.xml
- docs/en/programmers/api-variables/variable-force-compile.xml
- docs/en/programmers/api-variables/variable-left-delimiter.xml
- docs/en/programmers/api-variables/variable-php-handling.xml
- docs/en/programmers/api-variables/variable-plugins-dir.xml
- docs/en/programmers/api-variables/variable-request-use-auto-globals.xml
- docs/en/programmers/api-variables/variable-request-vars-order.xml
- docs/en/programmers/api-variables/variable-right-delimiter.xml
- docs/en/programmers/api-variables/variable-secure-dir.xml
- docs/en/programmers/api-variables/variable-security-settings.xml
- docs/en/programmers/api-variables/variable-security.xml
- docs/en/programmers/api-variables/variable-template-dir.xml
- docs/en/programmers/api-variables/variable-trusted-dir.xml
- docs/en/programmers/api-variables/variable-use-sub-dirs.xml
- docs/en/programmers/caching/caching-cacheable.xml
- docs/en/programmers/caching/caching-groups.xml
- docs/en/programmers/caching/caching-multiple-caches.xml
- docs/en/programmers/caching/caching-setting-up.xml:
- Tidy up of formatting
-
- * docs/entities/global.ent:
- Adding some more resources
-
- * docs/en/programmers/plugins/plugins-block-functions.xml
- docs/en/programmers/plugins/plugins-compiler-functions.xml
- docs/en/programmers/plugins/plugins-functions.xml
- docs/en/programmers/plugins/plugins-inserts.xml
- docs/en/programmers/plugins/plugins-modifiers.xml
- docs/en/programmers/plugins/plugins-naming-conventions.xml
- docs/en/programmers/plugins/plugins-outputfilters.xml
- docs/en/programmers/plugins/plugins-prefilters-postfilters.xml
- docs/en/programmers/plugins/plugins-resources.xml
- docs/en/programmers/plugins/plugins-writing.xml:
- Tidy up some formatting
-
-2006-09-26 Peter 'Mash' Morgan <pm@daffodil.uk.com>
-
- * docs/en/programmers/api-functions/api-append-by-ref.xml
- docs/en/programmers/api-functions/api-append.xml
- docs/en/programmers/api-functions/api-assign-by-ref.xml
- docs/en/programmers/api-functions/api-assign.xml
- docs/en/programmers/api-functions/api-clear-all-assign.xml
- docs/en/programmers/api-functions/api-clear-all-cache.xml
- docs/en/programmers/api-functions/api-clear-assign.xml
- docs/en/programmers/api-functions/api-clear-cache.xml
- docs/en/programmers/api-functions/api-clear-compiled-tpl.xml
- docs/en/programmers/api-functions/api-clear-config.xml
- docs/en/programmers/api-functions/api-config-load.xml
- docs/en/programmers/api-functions/api-display.xml
- docs/en/programmers/api-functions/api-fetch.xml
- docs/en/programmers/api-functions/api-get-config-vars.xml
- docs/en/programmers/api-functions/api-get-registered-object.xml
- docs/en/programmers/api-functions/api-get-template-vars.xml
- docs/en/programmers/api-functions/api-is-cached.xml
- docs/en/programmers/api-functions/api-load-filter.xml
- docs/en/programmers/api-functions/api-register-block.xml
- docs/en/programmers/api-functions/api-register-compiler-function.xml
- docs/en/programmers/api-functions/api-register-function.xml
- docs/en/programmers/api-functions/api-register-modifier.xml
- docs/en/programmers/api-functions/api-register-object.xml
- docs/en/programmers/api-functions/api-register-outputfilter.xml
- docs/en/programmers/api-functions/api-register-postfilter.xml
- docs/en/programmers/api-functions/api-register-prefilter.xml
- docs/en/programmers/api-functions/api-register-resource.xml
- docs/en/programmers/api-functions/api-template-exists.xml
- docs/en/programmers/api-functions/api-trigger-error.xml
- docs/en/programmers/api-functions/api-unregister-block.xml
- docs/en/programmers/api-functions/api-unregister-compiler-function.xml
- docs/en/programmers/api-functions/api-unregister-function.xml
- docs/en/programmers/api-functions/api-unregister-modifier.xml
- docs/en/programmers/api-functions/api-unregister-object.xml
- docs/en/programmers/api-functions/api-unregister-outputfilter.xml
- docs/en/programmers/api-functions/api-unregister-postfilter.xml
- docs/en/programmers/api-functions/api-unregister-prefilter.xml
- docs/en/programmers/api-functions/api-unregister-resource.xml:
- Tidy up formatting and examples
-
- * docs/en/language-snippets.ent:
- Moved recurring para for register_*
-
- * docs/en/designers/language-modifiers.xml:
- Spelling on modifiers
-
- * docs/en/designers/language-builtin-functions.xml
- docs/en/designers/language-modifiers.xml
- docs/en/designers/language-custom-functions/language-function-html-options.xml
- docs/en/designers/language-modifiers/language-modifier-capitalize.xml
- docs/en/designers/language-modifiers/language-modifier-cat.xml
- docs/en/designers/language-modifiers/language-modifier-count-characters.xml
- docs/en/designers/language-modifiers/language-modifier-count-paragraphs.xml
- docs/en/designers/language-modifiers/language-modifier-count-sentences.xml
- docs/en/designers/language-modifiers/language-modifier-count-words.xml
- docs/en/designers/language-modifiers/language-modifier-date-format.xml
- docs/en/designers/language-modifiers/language-modifier-default.xml
- docs/en/designers/language-modifiers/language-modifier-escape.xml
- docs/en/designers/language-modifiers/language-modifier-indent.xml
- docs/en/designers/language-modifiers/language-modifier-lower.xml
- docs/en/designers/language-modifiers/language-modifier-nl2br.xml
- docs/en/designers/language-modifiers/language-modifier-regex-replace.xml
- docs/en/designers/language-modifiers/language-modifier-replace.xml
- docs/en/designers/language-modifiers/language-modifier-spacify.xml
- docs/en/designers/language-modifiers/language-modifier-string-format.xml
- docs/en/designers/language-modifiers/language-modifier-strip-tags.xml
- docs/en/designers/language-modifiers/language-modifier-strip.xml
- docs/en/designers/language-modifiers/language-modifier-truncate.xml
- docs/en/designers/language-modifiers/language-modifier-upper.xml
- docs/en/designers/language-modifiers/language-modifier-wordwrap.xml:
- Tidying up some markup
-
- * docs/en/designers/language-variables.xml:
- typo
-
- * docs/en/designers/language-variables.xml
- docs/en/designers/language-variables/language-assigned-variables.xml
- docs/en/designers/language-variables/language-config-variables.xml
- docs/en/designers/language-variables/language-variables-smarty.xml:
- Tidy up formatting on variables
-
- * docs/en/designers/language-basic-syntax/language-escaping.xml
- docs/en/designers/language-basic-syntax/language-math.xml
- docs/en/designers/language-basic-syntax/language-syntax-comments.xml
- docs/en/designers/language-basic-syntax/language-syntax-functions.xml
- docs/en/designers/language-basic-syntax/language-syntax-quotes.xml
- docs/en/designers/language-basic-syntax/language-syntax-variables.xml:
- Formatting of the basic-syntax dir
-
- * docs/en/designers/language-custom-functions/language-function-assign.xml
- docs/en/designers/language-custom-functions/language-function-counter.xml
- docs/en/designers/language-custom-functions/language-function-cycle.xml
- docs/en/designers/language-custom-functions/language-function-debug.xml
- docs/en/designers/language-custom-functions/language-function-eval.xml
- docs/en/designers/language-custom-functions/language-function-fetch.xml
- docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml
- docs/en/designers/language-custom-functions/language-function-html-image.xml
- docs/en/designers/language-custom-functions/language-function-html-options.xml
- docs/en/designers/language-custom-functions/language-function-html-radios.xml
- docs/en/designers/language-custom-functions/language-function-html-select-date.xml
- docs/en/designers/language-custom-functions/language-function-html-select-time.xml
- docs/en/designers/language-custom-functions/language-function-html-table.xml
- docs/en/designers/language-custom-functions/language-function-mailto.xml
- docs/en/designers/language-custom-functions/language-function-math.xml
- docs/en/designers/language-custom-functions/language-function-popup-init.xml
- docs/en/designers/language-custom-functions/language-function-popup.xml
- docs/en/designers/language-custom-functions/language-function-textformat.xml:
- More formatting and cleaning up examples
-
-2006-09-25 Peter 'Mash' Morgan <pm@daffodil.uk.com>
-
- * docs/en/designers/language-builtin-functions/language-function-foreach.xml
- docs/en/designers/language-builtin-functions/language-function-section.xml:
- Doh! removing tabs
-
- * docs/en/designers/language-builtin-functions/language-function-capture.xml
- docs/en/designers/language-builtin-functions/language-function-config-load.xml
- docs/en/designers/language-builtin-functions/language-function-foreach.xml
- docs/en/designers/language-builtin-functions/language-function-if.xml
- docs/en/designers/language-builtin-functions/language-function-include-php.xml
- docs/en/designers/language-builtin-functions/language-function-include.xml
- docs/en/designers/language-builtin-functions/language-function-insert.xml
- docs/en/designers/language-builtin-functions/language-function-ldelim.xml
- docs/en/designers/language-builtin-functions/language-function-literal.xml
- docs/en/designers/language-builtin-functions/language-function-php.xml
- docs/en/designers/language-builtin-functions/language-function-section.xml
- docs/en/designers/language-builtin-functions/language-function-strip.xml:
- A lot of formatting, tagging and tidy up. Some consistency at last
-
- * docs/en/designers/language-builtin-functions/language-function-section.xml:
- Major tidy up
-
- * docs/en/designers/language-builtin-functions/language-function-foreach.xml:
- Major tidy up, added index property and some examples
-
-2006-09-03 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/designers/language-custom-functions/language-function-popup-init.xml
- docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml
- docs/fr/programmers/advanced-features/advanced-features-postfilters.xml
- docs/fr/programmers/advanced-features/advanced-features-prefilters.xml:
- sync with EN
-
-2006-09-01 George Miroshnikov <support@infinity.com.ua>
-
- * docs/ru/programmers/api-functions/api-append-by-ref.xml
- docs/ru/programmers/api-functions/api-append.xml
- docs/ru/programmers/api-functions/api-assign-by-ref.xml
- docs/ru/programmers/api-functions/api-assign.xml
- docs/ru/programmers/api-functions/api-clear-all-assign.xml
- docs/ru/programmers/api-functions/api-clear-all-cache.xml
- docs/ru/programmers/api-functions/api-clear-assign.xml
- docs/ru/programmers/api-functions/api-clear-cache.xml
- docs/ru/programmers/api-functions/api-clear-compiled-tpl.xml
- docs/ru/programmers/api-functions/api-clear-config.xml
- docs/ru/programmers/api-functions/api-config-load.xml
- docs/ru/programmers/api-functions/api-display.xml:
- sync with EN
-
-2006-08-25 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed wrong handling of name attribute in {insert}
- thanks to Ivan Kravets for reporting this
-
- * libs/Smarty_Compiler.class.php:
- fixed typo
-
-2006-08-21 George Miroshnikov <support@infinity.com.ua>
-
- * docs/ru/designers/language-custom-functions/language-function-popup-init.xml
- docs/ru/programmers/advanced-features/advanced-features-objects.xml
- docs/ru/programmers/advanced-features/advanced-features-outputfilters.xml
- docs/ru/programmers/advanced-features/advanced-features-postfilters.xml
- docs/ru/programmers/advanced-features/advanced-features-prefilters.xml
- docs/ru/programmers/advanced-features/section-template-cache-handler-func.xml
- docs/ru/programmers/advanced-features/template-resources.xml:
- sync with EN
-
- * docs/en/programmers/advanced-features/advanced-features-prefilters.xml:
- another missing dot
-
- * docs/en/programmers/advanced-features/advanced-features-postfilters.xml:
- missing dot
-
- * docs/en/programmers/advanced-features/advanced-features-outputfilters.xml:
- missing comma
-
-2006-08-19 Peter 'Mash' Morgan <pmm@daffodil.uk.com>
-
- * docs/en/designers/language-custom-functions/language-function-popup-init.xml:
- avoid dupes and added remote paths
-
-2006-08-06 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/designers/language-custom-functions/language-function-html-table.xml
- docs/fr/designers/language-custom-functions/language-function-mailto.xml:
- sync with EN
-
-2006-08-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix false replacement of "$t" inside double quotes
- thanks to checat for reporting this
-
-2006-07-20 George Miroshnikov <support@infinity.com.ua>
-
- * docs/ru/designers/language-custom-functions/language-function-html-table.xml
- docs/ru/designers/language-custom-functions/language-function-mailto.xml:
- incrementing EN-Revision
-
- * docs/ru/designers/language-custom-functions/language-function-assign.xml
- docs/ru/designers/language-custom-functions/language-function-eval.xml
- docs/ru/designers/language-custom-functions/language-function-fetch.xml
- docs/ru/designers/language-custom-functions/language-function-html-checkboxes.xml
- docs/ru/designers/language-custom-functions/language-function-html-image.xml
- docs/ru/designers/language-custom-functions/language-function-html-options.xml
- docs/ru/designers/language-custom-functions/language-function-html-radios.xml
- docs/ru/designers/language-custom-functions/language-function-html-table.xml
- docs/ru/designers/language-custom-functions/language-function-mailto.xml
- docs/ru/designers/language-custom-functions/language-function-popup-init.xml
- docs/ru/designers/language-custom-functions/language-function-popup.xml
- docs/ru/designers/language-modifiers/language-modifier-date-format.xml
- docs/ru/designers/language-modifiers/language-modifier-default.xml
- docs/ru/designers/language-modifiers/language-modifier-escape.xml
- docs/ru/designers/language-modifiers/language-modifier-indent.xml
- docs/ru/designers/language-modifiers/language-modifier-lower.xml
- docs/ru/designers/language-modifiers/language-modifier-nl2br.xml
- docs/ru/designers/language-modifiers/language-modifier-strip.xml
- docs/ru/designers/language-modifiers/language-modifier-truncate.xml
- docs/ru/designers/language-modifiers/language-modifier-upper.xml
- docs/ru/designers/language-modifiers/language-modifier-wordwrap.xml
- docs/ru/designers/language-variables/language-variables-smarty.xml:
- sync with EN
-
- * docs/en/designers/language-custom-functions/language-function-mailto.xml:
- typo
-
-2006-07-10 boots <jayboots@yahoo.com>
-
- * libs/plugins/function.html_table.php:
- fixed email address in comments
-
- * NEWS
- libs/plugins/function.html_table.php:
- html_table: fixed th/tr output, added hdir support for column
- headings,update docs to reflect new features
-
-2006-07-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_table.php:
- fix occasional notices on undefined variables
-
-2006-07-08 boots <jayboots@yahoo.com>
-
- * libs/plugins/function.html_table.php:
- Added ability to specify column headings in {html_table}
-
- Added th_attrs attribute which works similary to td_attr and tr_attr but
- for TH elements. Changes the cols attribute to allow mixed values; a
- numeric still specifies the number of columns to render but now an array
- of values can be used to specify TH column values. The number of columns
- is determine from the size of the array. Further, a comma-separated
- string of column names can be used which is internally coverted to an
- array and used as if it was specified as a normal array.
-
- Thanks for lynlyn for the feature request.
-
-2006-06-23 boots <jayboots@yahoo.com>
-
- * libs/plugins/outputfilter.trimwhitespace.php:
- fix comments in outputfilter.trimwhitespace
-
- * NEWS
- libs/plugins/outputfilter.trimwhitespace.php:
- fixed ordering of replacements in trimwhitespace output filter
-
- Thanks to Getty from IRC for reporting this.
-
-2006-06-20 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/plugins/function.mailto.php:
- update mailto function plugin to work around a firefox/thunderbird escaping
- bug
-
- Thanks to elijahlofgren from the forums for reporting this and providing
- the necessary patch
-
- * NEWS
- libs/plugins/modifier.date_format.php:
- emulate %l in the date_format modifier on windows
-
- thanks to Gibberish from the forums for reporting this
-
-2006-06-14 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/plugins/modifier.capitalize.php:
- Fix handling of apostrophes in the capitalize modifier.
-
- Thanks to asmecher from the forums for reporting this and providing a
- partial solution.
-
-2006-05-28 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers
-
-2006-05-25 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- un-hide hidden xml open tags
-
-2006-05-09 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- separate handling of comment blocks from "special blocks"
-
- * NEWS
- libs/plugins/function.popup_init.php:
- reverted {popup_init} as proposed change to insertion behviour was not BC
-
-2006-05-04 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/plugins/function.popup_init.php:
- changed {popup_init} to only emit code once during a request
-
- Thanks to TGKnIght from forums
-
-2006-04-22 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix handling of block-methods of registered objects
- thanks to El Hombre Gris
-
-2006-04-04 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/function.html_select_date.php:
- fix typo
-
-2006-03-09 Monte Ohrt <monte@ohrt.com>
-
- * (Smarty_2_6_13)
- NEWS:
- update for release
-
-2006-03-08 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/modifier.regex_replace.php:
- remove delim quote
-
- * libs/plugins/modifier.regex_replace.php:
- fix delimiter issue
-
-2006-03-03 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/modifier.regex_replace.php:
- use preg_replace to cover any space chars
-
- * libs/plugins/modifier.regex_replace.php:
- fix problem with allowing "e" modifier
-
-2006-01-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- removed possiblity for E_NOTICE on an undefined variable in
- Smarty_Compiler::_compile_if_tag() - thanks to sbeh
-
-2006-01-18 Monte Ohrt <monte@ohrt.com>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers
-
- * (Smarty_2_6_12)
- NEWS:
- commit 2.6.12 release
-
-2006-01-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed use of references $cache_attrs and $repeat in Smarty_Compiler.
-
- php does not allow to pass an assigned by reference to a function. since
- php-5.1.2
- the reference to the lval gets lost when passing an assignment.
-
-2005-12-31 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- fixed incompatible use of fread() in Smarty::_read_file()
- it choke on php-5.1.1 and later.
- thanks to andig for pointing this out.
-
-2005-12-21 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- Fix improper tokenization of certain inline math expressions.
-
- Thanks to gerard at forums for reporting this.
-
-2005-12-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.math.php:
- fixed problem with math in certain LC_NUMERIC locales.
- thanks to wiebren for providing problem+solution.
-
-2005-12-14 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS:
- fixed iso-latin1 special chars
-
-2005-12-14 Monte Ohrt <monte@ohrt.com>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers
-
- * (Smarty_2_6_11)
- NEWS:
- commit NEWS file for 2.6.11
-
-2005-12-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/de/getting-started.xml:
- sync with en
-
-2005-11-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed code generation of non-cacheable blocks to play well with php's
- "Alternative syntax" used for example in compiled {if}..{else}..{/if}
- blocks.
-
- (see: http://php.net/manual/en/control-structures.alternative-syntax.php
- on "Alternative syntax")
-
- thanks to kihara from the forum.
-
-2005-11-26 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS:
- fixed handling of multiple identical calls to {insert}.
-
- the function was called multiple times, but all inserts where replaced
- by the results of the first call to the insert function.
-
- * libs/plugins/compiler.assign.php
- libs/plugins/function.config_load.php:
- added credits
-
- * libs/plugins/function.popup.php:
- added "closeclick" from
- http://www.bosrup.com/web/overlib/?Command_Reference
-
-2005-11-23 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/plugins/modifier.escape.php:
- replace {} string access with equivalent substr() to avoid E_STRICT
- warnings in PHP 5.1
-
-2005-11-09 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/Smarty.class.php:
- return valid reference in get_config_vars() when given var is non-existant
-
-2005-10-11 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/block.textformat.php
- libs/plugins/compiler.assign.php
- libs/plugins/function.assign_debug_info.php
- libs/plugins/function.config_load.php
- libs/plugins/function.counter.php
- libs/plugins/function.eval.php
- libs/plugins/function.fetch.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_select_date.php
- libs/plugins/function.html_select_time.php
- libs/plugins/function.math.php
- libs/plugins/function.popup.php
- libs/plugins/function.popup_init.php
- libs/plugins/modifier.capitalize.php
- libs/plugins/modifier.count_characters.php
- libs/plugins/modifier.count_paragraphs.php
- libs/plugins/modifier.count_sentences.php
- libs/plugins/modifier.count_words.php
- libs/plugins/modifier.date_format.php
- libs/plugins/modifier.debug_print_var.php
- libs/plugins/modifier.default.php
- libs/plugins/modifier.escape.php
- libs/plugins/modifier.indent.php
- libs/plugins/modifier.lower.php
- libs/plugins/modifier.regex_replace.php
- libs/plugins/modifier.replace.php
- libs/plugins/modifier.spacify.php
- libs/plugins/modifier.string_format.php
- libs/plugins/modifier.strip_tags.php
- libs/plugins/modifier.truncate.php
- libs/plugins/modifier.upper.php
- libs/plugins/modifier.wordwrap.php
- libs/plugins/shared.escape_special_chars.php
- libs/plugins/shared.make_timestamp.php:
- Added author title to plugins where they don't exist. I put my name where I
- was the original or co-author. If there needs to be more credit given
- somewhere, speak up!
-
-2005-10-10 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/plugins/function.html_image.php:
- add path_prefix to html_image, fix incorrect secure_dir error when image
- file is missing
-
-2005-10-04 Monte Ohrt <monte@ohrt.com>
-
- * demo/templates/index.tpl:
- remove popup example, update section var syntax
-
-2005-09-16 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/de/getting-started.xml:
- more fixes
-
- * docs/de/getting-started.xml:
- fix php bug #34520: broken example display (de only)
-
-2005-08-30 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/modifier.escape.php:
- change default charset from utf8 to iso-8859-1
-
- * NEWS
- libs/plugins/modifier.escape.php:
- add char_set param
-
-2005-08-17 Monte Ohrt <monte@ohrt.com>
-
- * NEWS:
- fix notice in debug security check
-
- * libs/Smarty.class.php:
- fix typo
-
- * NEWS
- libs/Smarty.class.php:
- return valid reference in get_template_vars() when given var is
- non-existant
-
-2005-08-12 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/plugins/modifier.escape.php:
- add "urlpathinfo" escape type to escape modifier. (apache does not like %2F
- in the PATH_INFO)
-
-2005-08-05 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers
-
-2005-08-04 Monte Ohrt <monte@ohrt.com>
-
- * NEWS:
- update secure_dir notes
-
- * NEWS:
- allow debug.tpl to work from arbitrary dir
-
-2005-08-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed proper escaping for literal strings passed to
- Smarty_Compiler::_expand_quoted_text() by
- Smarty_Compiler::_parse_var_props()
-
-2005-07-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/shared.make_timestamp.php:
- removed ambiguity for numeric values passed to smarty_make_timestamp().
- numeric values are *always* treated as timestamps now.
-
-2005-07-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php:
- removed E_NOTICE from Config_File::get()
-
- * libs/Smarty.class.php:
- removed E_NOTICE
-
-2005-07-10 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/getting-started.xml:
- sync with EN
-
-2005-07-08 Monte Ohrt <monte@ohrt.com>
-
- * NEWS:
- correct username in NEWS file
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- added passthru attribute feature to html_select_date
-
-2005-07-03 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/language-snippets.ent
- docs/fr/preface.xml:
- sync with EN
-
-2005-06-16 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/de/preface.xml
- docs/de/preface.xml:
- sync with en
-
-2005-06-13 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/plugins/modifier.truncate.php:
- add "middle" parameter to truncate modifier
-
-2005-06-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/de/livedocs.ent:
- added german livedocs.ent
-
- * docs/de/language-snippets.ent
- docs/de/preface.xml:
- sync with en
-
-2005-06-09 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/de/bookinfo.xml
- docs/de/getting-started.xml
- docs/de/getting-started.xml:
- sync with en
-
-2005-05-24 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/getting-started.xml
- docs/fr/language-snippets.ent:
- sync with EN
-
-2005-05-20 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/function.html_radios.php:
- fix allowable label id characters
-
-2005-05-06 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/plugins/function.html_radios.php:
- make form input label ids optional (monte)
-
-2005-05-02 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- add error message for empty if/elseif statements
-
-2005-04-15 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/plugins/function.html_radios.php:
- cast selected value to string for comparison in html_radios
-
-2005-04-07 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- added xhtml compliance to html_select_date's year_as_text-feature
- thanks to Mark West
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- fixed handling of selected month html_select_date
- thanks to Yuri Weseman for providing problem+solution
-
-2005-04-07 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/configure.in:
- sync configure and file-entities scripts with phpdoc, for better
- windows/cygwin support
-
-2005-03-31 Monte Ohrt <monte@ohrt.com>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers
-
- * (Smarty_2_6_9)
- NEWS:
- update NEWS file
-
-2005-03-30 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.math.php:
- re-enabled hex-constant. i hope in a sane way this time.
-
-2005-03-30 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/function.math.php:
- fix function testing logic
-
- * libs/Smarty_Compiler.class.php:
- disable variable func calls completely
-
- * libs/Smarty_Compiler.class.php:
- disallow variable func calls when security is enabled
-
-2005-03-22 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- bumped version-number to 2.6.9-dev
- added headline of 2.6.6 release to NEWS file
-
-2005-03-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * (Smarty_2_6_8)
- NEWS:
- maybe even better this way. thanks monte :)
-
- * NEWS:
- little more clear news-entry
-
-2005-03-21 Monte Ohrt <monte@ohrt.com>
-
- * NEWS:
- update NEWS with e-modifier removal
-
- * (Smarty_2_6_8)
- libs/plugins/modifier.regex_replace.php:
- remove e-modifier
-
-2005-03-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- objects don't get casted to arrays anymore in {foreach}
-
-2005-02-26 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- add "null" as a valid token for {if} when security is enabled
-
-2005-02-25 Monte Ohrt <monte@ohrt.com>
-
- * NEWS
- libs/plugins/function.mailto.php:
- add javascript_charcode option to mailto
-
-2005-02-24 Monte Ohrt <monte@ohrt.com>
-
- * NEWS:
- update NEWS file
-
- * QUICK_START
- libs/plugins/function.html_radios.php:
- add label ids to html_radios
-
-2005-02-10 Monte Ohrt <monte@ohrt.com>
-
- * QUICK_START:
- update with directory structure
-
-2005-02-10 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/Makefile.in:
- fix chm generation
-
-2005-02-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed too agressive {strip} around delimiters inside strip-blocks
-
-2005-02-10 Monte Ohrt <monte@ohrt.com>
-
- * QUICK_START:
- fix a couple errors
-
-2005-02-10 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/Makefile.in
- docs/README:
- commiting the new tools to make the CHM manual.
-
-2005-02-09 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed handling of strip-tags with non-default delimiters
-
-2005-02-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_radios.php:
- fixed syntax error. shame on me.
-
-2005-02-03 Monte Ohrt <monte@ohrt.com>
-
- * QUICK_START:
- fix example
-
- * QUICK_START:
- initial commit
-
- * RELEASE_NOTES
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers in cvs
-
- * (Smarty_2_6_7)
- NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- commit version numbers for new release
-
-2005-02-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * (Smarty_2_6_7)
- libs/plugins/function.html_image.php:
- fixed comment (thanks to CirTap)
-
-2005-02-01 Monte Ohrt <monte@ohrt.com>
-
- * libs/plugins/function.html_image.php:
- remove border tag
-
-2005-02-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- fixed serialization of values containing newlines (like _cache_attrs)
- in core_write_cache_file()
-
- bumped version to 2.6.6-dev-3 to indicate that the fileformat of cache
- has changed
-
-2005-01-30 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed handling of hashed opening php-tags inside strip-blocks
- (reported by titi_rafa)
-
-2005-01-30 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/fr/language-snippets.ent:
- fix build
-
-2005-01-28 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/modifier.escape.php:
- escape:url now uses the (RFC 1738 compliant) rawurlencode()
-
-2005-01-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- replaced ? true : false and removed intermediate $_cookie_var in the
- handling of the SMARTY_DEBUG-cookie
-
-2005-01-22 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/bookinfo.xml:
- update EN-Revision tag
-
-2005-01-21 Monte Ohrt <monte@ohrt.com>
-
- * README
- RELEASE_NOTES
- docs/de/bookinfo.xml
- docs/fr/bookinfo.xml
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/plugins/function.cycle.php
- libs/plugins/function.debug.php
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_image.php
- libs/plugins/function.html_radios.php
- libs/plugins/function.html_table.php
- libs/plugins/function.mailto.php
- libs/plugins/modifier.cat.php
- libs/plugins/modifier.nl2br.php
- libs/plugins/modifier.strip.php
- libs/plugins/outputfilter.trimwhitespace.php:
- de-spammify e-mails
-
- * README
- RELEASE_NOTES
- docs/de/bookinfo.xml
- docs/fr/bookinfo.xml
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/plugins/function.cycle.php
- libs/plugins/function.debug.php
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_image.php
- libs/plugins/function.html_radios.php
- libs/plugins/function.html_table.php
- libs/plugins/function.mailto.php
- libs/plugins/modifier.cat.php
- libs/plugins/modifier.nl2br.php
- libs/plugins/modifier.strip.php
- libs/plugins/outputfilter.trimwhitespace.php:
- update copyright notices, e-mail addresses
-
-2005-01-06 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- reduced the code that is generated on a {foreach}-block that has a
- name.
-
- instead of pre-computing all foreach-properties (like first, last,
- show) on each iteration, they are computed on demand as soon as
- {$smarty.foreach.*}-variables are used.
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- slight optimization in the compilation of $smarty.const.FOO .
-
- more complex consts like $smarty.const.$name still compile to
- constant($this->_tpl_vars['name'])
-
-2005-01-05 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- make block functions and registered objects' block methods use a
- local variable for block_content instead of $this->_block_content
-
- it's not necessary to have $smarty->_block_content accessible.
-
-2005-01-04 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/bookinfo.xml:
- sync with EN
-
-2005-01-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- Happy new year from germany.
-
-2004-12-28 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php:
- fix _read_file comments
-
-2004-12-26 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/getting-started.xml
- docs/fr/preface.xml:
- typo
-
- * docs/fr/language-defs.ent
- docs/fr/language-snippets.ent
- docs/fr/livedocs.ent:
- sync with EN & typo
-
-2004-12-21 Yannick Torres <yannick.torres@keliglia.com>
-
- * docs/fr/bookinfo.xml
- docs/fr/getting-started.xml
- docs/fr/translation.xml:
- sync with EN
-
-2004-12-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed escaping of template-filenames in the generated code that loads
- needed plugins
-
-2004-12-15 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/function.popup.php:
- fix invalid HTML issue with popup
-
-2004-12-06 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/plugins/function.popup.php:
- - fixed {popup} to properly handle inarray and function parameters and
- added support for mouseoff and followmouse options
-
-2004-11-21 Mehdi Achour <didou@keliglia.com>
-
- * docs/fr/livedocs.ent:
- add livedocs specific entities files
-
-2004-11-16 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_radios.php:
- cleaned up typecasting
-
-2004-11-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_options.php:
- fixed semantically misleading check for $options (use isset() instead
- of is_array() because it is always an array).
-
- thanks to albert almeida.
-
-2004-11-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- removed unused code
-
-2004-10-25 Mehdi Achour <didou@keliglia.com>
-
- * docs/fr/bookinfo.xml
- docs/fr/getting-started.xml:
- sync with en
-
-2004-10-13 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- update header
-
-2004-10-02 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS:
- fixed nocache-handling with nested includes. there was a logical error
- in the replacement of internal nocache-tags to dynamic content that
- lead to false results with deeply nested includes or with
- nocache-blocks inside nocache-blocks.
-
- many thanks to Lars Jankowfsky for providing big help on reproducing
- and tracking down this bug!
-
-2004-10-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- - better header for compiled includes (more in line with compiled
- templates)
-
- - reuse cache_serials if a file is compiled more than once in one
- process (force_compile)
-
- - don't print nocache-delimiters wenn already inside
- process_cached_inserts()
-
-2004-09-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- switched from @count() to !empty() . this was pointed out a few times
- by a few people with buggy error-handlers
-
- * libs/Smarty_Compiler.class.php:
- added some property declarations
-
-2004-09-28 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- bumped up version number to reflect incompatibility in tempfiles of
- 'core' vs. 'internals'
-
-2004-09-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_select_date.php:
- fixed $start_year when no value for the year in $time is given.
-
-2004-09-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_table.php:
- fixed handling of "inner"-attribute
-
- * libs/Smarty_Compiler.class.php:
- fixed handling of object derefence inside backticks
-
-2004-09-20 Monte Ohrt <monte@ispi.net>
-
- * libs/debug.tpl:
- add <head></head> tags
-
-2004-09-18 boots <jayboots@yahoo.com>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/plugins/function.config_load.php
- libs/plugins/function.debug.php
- libs/plugins/function.fetch.php
- libs/plugins/function.html_image.php:
- Fixed \\r\\n line endings mistakenly introduced in last commit. d'oh.
-
-2004-09-16 boots <jayboots@yahoo.com>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.assemble_plugin_filepath.php
- libs/core/core.assign_smarty_interface.php
- libs/core/core.create_dir_structure.php
- libs/core/core.display_debug_console.php
- libs/core/core.get_include_path.php
- libs/core/core.get_microtime.php
- libs/core/core.get_php_resource.php
- libs/core/core.is_secure.php
- libs/core/core.is_trusted.php
- libs/core/core.load_plugins.php
- libs/core/core.load_resource_plugin.php
- libs/core/core.process_cached_inserts.php
- libs/core/core.process_compiled_include.php
- libs/core/core.read_cache_file.php
- libs/core/core.rm_auto.php
- libs/core/core.rmdir.php
- libs/core/core.run_insert_handler.php
- libs/core/core.smarty_include_php.php
- libs/core/core.write_cache_file.php
- libs/core/core.write_compiled_include.php
- libs/core/core.write_compiled_resource.php
- libs/core/core.write_file.php
- libs/plugins/function.config_load.php
- libs/plugins/function.debug.php
- libs/plugins/function.fetch.php
- libs/plugins/function.html_image.php:
- Moved /libs/core to /libs/internals and created new constant,
- SMARTY_CORE_DIR which defaults to SMARTY_DIR/internals. This should help
- CVS and rsynch users butupgrades will require changes and this may affect
- 3rd party plugins that use the /core dir.
-
-2004-09-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- moved $this->_num_const_regexp out of $this->_var_regexp and added it
- to the places that affect $this->_var_regexp
-
- this should fix some problems parsing plugin-names endings with digits
-
-2004-09-14 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update files to 2.6.6-dev
-
-2004-09-13 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS:
- fixed typo
-
-2004-09-13 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_6_5)
- NEWS:
- update NEWS file with parsing correction note
-
-2004-09-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.debug.php:
- removed notice from {debug}
- thanks to Peter Billen for pointing this one out!
-
-2004-09-11 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- fix more object calling syntax issues
-
-2004-09-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- added $smarty->security_settings['ALLOW_CONSTANTS']
- including test-cases for them
-
-2004-09-09 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- break down regex to digestable chunks, fix multiple param problem with
- method calls,
- add object method testing to unit_test cases
-
- * libs/Smarty_Compiler.class.php:
- update code comment with more examples
-
- * libs/Smarty_Compiler.class.php:
- allow objects in arbitrary param positions
-
- * libs/Smarty_Compiler.class.php:
- fix object parameter regex, allow one level of object indirection
-
- * libs/Smarty_Compiler.class.php:
- fix compile problem with numeric constants and math operator matching
-
-2004-09-07 Monte Ohrt <monte@ispi.net>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update files to 2.6.5-dev
-
- * (Smarty_2_6_4)
- NEWS:
- update NEWS file with 2.6.4 header
-
-2004-08-31 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- fix preg_quote
-
- * libs/Smarty_Compiler.class.php:
- fix math in object params, clean up some regex on the way, change
- preg_ delimiters to ~ to avoid character clashes with ! and %
-
-2004-08-30 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- add $smarty.ldelim and $smarty.rdelim to smarty special var
-
-2004-08-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/core/core.write_file.php:
- tempnam() seems to be borken on many installation.
-
- now we try tempnam first and if that fails we generate our own
- temp-filename with uniqid()
-
-2004-08-23 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/modifier.capitalize.php:
- dont use constant, use static var instead
-
- * libs/plugins/modifier.capitalize.php:
- implement optional param to capitalize for digit behavior
-
- * libs/plugins/modifier.capitalize.php:
- another commit to capitalize, taking special chars into account
-
-2004-08-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- cleaned up attribute-handling in Smarty_Compiler::_compile_foreach_start()
-
-2004-08-23 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/function.html_select_date.php
- libs/plugins/modifier.capitalize.php:
- fix capitalize modifier to not rely on buggy ucwords() func
-
-2004-08-20 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/function.html_select_date.php:
- update version
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- make time param work with negative timestamps, force year range to include
- given date unless explicitly set
-
-2004-08-19 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/function.fetch.php:
- fix bug with fetch, passing user/pass in url did not work
-
-2004-08-13 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed handling of {foreachelse} and {sectionelse} that got borked with
- the latest commit (v 1.330)
-
-2004-08-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed occasional wrong error messages on mismatched tags when
- {else}, {elseif}, {foreachelse} or {sectionelse} is involved
-
- thanks to Ooypunk for pointing me on this
-
-2004-08-12 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/.cvsignore
- docs/Makefile.in
- docs/configure.in:
- enable russian PDF builds
-
-2004-07-30 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/configure.in:
- typo
-
- * docs/Makefile.in
- docs/README
- docs/configure.in:
- add make test_xml
- this is usefull to detect XML problems
-
-2004-07-29 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/configure.in:
- avoid warnings in head
-
- * docs/.cvsignore
- docs/Makefile.in
- docs/README
- docs/configure.in:
- build pdf files
- just type make pdf
-
-2004-07-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed handling of methods arguments.
-
- thanks to Manfred Wischin for finding this one and providing the
- conceptual fix.
-
-2004-07-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_radios.php:
- there was little flaw in smarty_function_html_radios() and
- smarty_function_html_checkboxes():
-
- the newly introduced assign-attribute was still added to the
- tag-output as an extra-attribute.
-
- fixed.
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.load_plugins.php
- libs/core/core.load_resource_plugin.php
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_image.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_radios.php
- libs/plugins/function.html_select_date.php
- libs/plugins/function.html_select_time.php
- libs/plugins/modifier.date_format.php:
- backed out renaming of _get_plugin_filepath() to get_plugin_filepath()
-
- we'll stick to _get_plugin_filepath() and look for a more viable
- solution to be exposed to plugin-writers.
-
-2004-07-20 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php
- libs/core/core.is_trusted.php
- libs/plugins/compiler.assign.php:
- Some fixes on PhpDocumentor comments. Thanks go to Ruben Vermeersch.
-
-2004-07-16 andreas halter <phpcvs@andreashalter.ch>
-
- * docs/de/bookinfo.xml
- docs/de/getting-started.xml
- docs/de/language-defs.ent
- docs/de/language-snippets.ent
- docs/de/preface.xml:
- - updated for 2.6.3
- - updates for new build system
- - added missing files
- - corrections from users
- - revcheck comments for all files
- - big up to didou and nuno, brilliant work
- - make test: ok
- - make: ok
-
-2004-07-16 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/de/getting-started.xml:
- fix the revision tracking tag
- the revision number might not be right. just check it, please
-
-2004-07-16 andreas halter <phpcvs@andreashalter.ch>
-
- * docs/de/getting-started.xml:
- - updated version (incl revcheck comment) for revcheck testing
-
-2004-07-14 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php:
- replace " with ' where literal strings are quoted (ever so slight speedup)
-
-2004-07-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/modifier.date_format.php:
- changed call from $smarty->_get_plugin_filepath() to
- $smarty->get_plugin_filepath()
-
- * libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_image.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_radios.php
- libs/plugins/function.html_select_date.php
- libs/plugins/function.html_select_time.php:
- renamed calls to $smarty->_get_plugin_filepath() to
- $smarty->get_plugin_filepath()
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.load_plugins.php
- libs/core/core.load_resource_plugin.php:
- renamed Smarty::_get_plugin_filepath() to Smarty::get_plugin_filepath()
-
- * NEWS
- libs/Smarty.class.php
- libs/core/core.write_compiled_include.php
- libs/core/core.write_compiled_resource.php
- libs/core/core.write_file.php:
- removed touch() call. changing the timestamp of the compiled-template
- to the source template's may be irritating for certain
- source-code-caches. now a newly compiled template gets the current
- time as timestamp.
-
-2004-07-02 gerald croes <gerald@phpside.org>
-
- * docs/fr/getting-started.xml
- docs/fr/preface.xml:
- Fixed missing tags to be able to make doc again
-
- * docs/fr/preface.xml:
- added the "is a good thing [TM]" as in en docs
-
- * docs/fr/getting-started.xml:
- added ctags, updated screen => programm listing.
- added the technical note founded on the en doc
-
-2004-07-02 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_radios.php
- libs/plugins/function.mailto.php:
- add assign attribute to html_checkboxes and html_radios
-
-2004-07-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- removed use of get_include_filepath() inside
- get_auto_filename(). thanks go to c960657
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- enhanced error-reporting for {foreach}
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed handling of digits inside tagnames. this problem slipped into
- the regexps by adding support for numeric contants next to string
- constants as variables.
-
-2004-06-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed escaping of backslashes in Smarty_Compiler::_quote_replace()
-
-2004-06-23 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/modifier.date_format.php:
- display date_format %e, %T and %D as expected for windows
-
-2004-06-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- changed version-number to 2.6.4-dev
-
-2004-06-16 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_6_3)
- NEWS:
- update NEWS file with version number
-
-2004-06-09 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/modifier.escape.php:
- added escapement of '</' to javascript escaping
-
-2004-06-08 gerald croes <gerald@phpside.org>
-
- * docs/fr/translation.xml:
- Add other translators.
-
-2004-06-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- made the correct value of "use_sub_dirs" available to the compiler.
- (not worth a NEWS-entry, i think)
-
-2004-06-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.fetch.php:
- fix: proper initialistaion of $content.
- thanks to Dmitry Koteroff for pointing this out.
-
-2004-05-29 Mehdi Achour <didou@keliglia.com>
-
- * docs/fr/translation.xml:
- oups :)
-
- * docs/fr/translation.xml:
- added translation file
-
-2004-05-28 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/Makefile.in:
- clean also file-entities.php
-
-2004-05-28 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.mailto.php:
- added obfuscation of protocol-string in {mailto} when using
- hex-encoding (thanks to bharat)
-
-2004-05-26 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- enhanced auto-generated filenames for templates_c and cache
-
- incremented Smarty::_version because the tempfiles' structure changed
- a little
-
-2004-05-23 Mehdi Achour <didou@keliglia.com>
-
- * docs/fr/bookinfo.xml
- docs/fr/getting-started.xml
- docs/fr/preface.xml:
- WS and added revcheck
-
-2004-05-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed typo in error-messages
-
- * docs/de/language-snippets.ent
- docs/fr/language-snippets.ent:
- added empty language-snippets.ent to fix "make web"
-
-2004-05-12 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/modifier.escape.php:
- add 'nonstd' escape modifier
-
-2004-05-07 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/block.textformat.php:
- update textformat to not output wrap chars after last para
-
-2004-05-06 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/core/core.write_file.php:
- use tempnam() instead of unqid() to create better temporary files in
- smarty_core_write_file().
-
- (thanks to xces for finding this race-condition and his work on
- fixing it)
-
-2004-05-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- added check if for file_exists() to Smarty::_read_file()
-
-2004-04-30 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/modifier.escape.php:
- add 'mail' attribute to escape modifier
-
-2004-04-20 Mehdi Achour <didou@keliglia.com>
-
- * docs/manual.xml.in:
- added the language-snippets.ent file and started using entities for notes
- under en/programmers/api-functions
-
-2004-04-18 Mehdi Achour <didou@keliglia.com>
-
- * docs/de/getting-started.xml
- docs/fr/getting-started.xml:
- new global entity for zend and php-accelerator
-
- * docs/fr/bookinfo.xml
- docs/fr/getting-started.xml
- docs/fr/preface.xml:
- added myself as translator and added vim comments and xml tags
-
-2004-04-16 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS:
- added entry for numeric constants
-
- * libs/Smarty_Compiler.class.php:
- removed unused 2nd param in call to _parse_var()
-
- * libs/Smarty_Compiler.class.php:
- added explanation for $this->_num_const_regexp
-
- * NEWS
- libs/plugins/modifier.escape.php:
- added escape type "decentity" to smarty_modifier_escape()
-
- * libs/Smarty_Compiler.class.php:
- enabled numerical constants be parsed as statements.
- (like {10} or {10|@range:12} )
-
- * libs/Smarty_Compiler.class.php:
- removed unused $smarty_compiler->_dvar_num_var_regexp
-
- * libs/Smarty.class.php:
- reverted Stuff
-
- * libs/debug.tpl
- libs/core/core.assemble_plugin_filepath.php
- libs/core/core.read_cache_file.php
- libs/core/core.write_file.php
- libs/plugins/function.eval.php
- libs/plugins/function.popup.php
- libs/plugins/modifier.escape.php
- libs/plugins/shared.make_timestamp.php:
- reverted stuff
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/debug.tpl
- libs/core/core.assemble_plugin_filepath.php
- libs/core/core.read_cache_file.php
- libs/core/core.write_file.php
- libs/plugins/function.eval.php
- libs/plugins/function.popup.php
- libs/plugins/modifier.escape.php
- libs/plugins/shared.make_timestamp.php:
- Smarty_Compiler.class.php
-
-2004-04-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/core/core.write_compiled_include.php:
- made smarty_core_write_compiled_include() php5-aware
-
- if someone knows a better way than patching the source with the
- tokenizer, please stand up!
-
-2004-04-14 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/Makefile.in:
- remove file-entities.ent also
-
- * docs/.cvsignore
- docs/Makefile.in
- docs/README:
- allow make revcheck
-
-2004-04-13 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/configure.in:
- do not need inipath
-
-2004-04-13 Mehdi Achour <didou@keliglia.com>
-
- * docs/TODO:
- done
-
- * docs/configure.in
- docs/manual.xml.in:
- now the files entites are generated dynamically
-
-2004-04-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php:
- removed unused functionality to load a subset of lines from a file in
- Smarty::_read_file()
-
- additionally removed a warning that is emitted since php-4.3.5 when
- fread() is called on an empty file (with filesize()==0). thanks to
- Andreas Streichardt who pointed this out.
-
- * NEWS
- libs/core/core.is_secure.php:
- smarty_core_is_secure() only checks the file for readability now, not
- the directory where is in.
-
- * libs/Smarty.class.php:
- removed unused security_setting 'ALLOW_CONSTANTS'
-
-2004-04-07 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.assign_debug_info.php
- libs/plugins/function.cycle.php
- libs/plugins/function.mailto.php:
- removed trailing spaces
-
- * libs/Smarty.class.php:
- removed unused $smarty->_error_msg
-
-2004-04-04 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/configure.in:
- fixing my crap
- put build_date back on-line
-
-2004-04-03 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/Makefile.in
- docs/configure.in
- docs/manual.xml.in:
- trying to fix ru problems
-
-2004-03-30 Monte Ohrt <monte@ispi.net>
-
- * libs/core/core.display_debug_console.php:
- fix problem with debug_tpl path and security
-
- * NEWS
- libs/core/core.display_debug_console.php:
- fix problem displaying debug console when $default_resource_type is not
- "file:"
-
-2004-03-29 Mehdi Achour <didou@keliglia.com>
-
- * docs/TODO:
- and finally, add a TODO here
-
- * docs/de/bookinfo.xml
- docs/de/manual.sgml
- docs/fr/bookinfo.xml
- docs/fr/manual.xml:
- translate bookinfo.xml and put back the translators
-
-2004-03-28 Mehdi Achour <didou@keliglia.com>
-
- * docs/manual.xml.in:
- add global.ent and define some general entities
-
- * docs/de/bookinfo.xml
- docs/de/getting-started.xml
- docs/de/language-defs.ent
- docs/de/preface.xml:
- add new de files
-
- * docs/de/appendixes.sgml
- docs/de/designers.sgml
- docs/de/getting-started.sgml
- docs/de/html-common.dsl
- docs/de/preface.sgml
- docs/de/programmers.sgml:
- drop old de files
-
- * docs/fr/bookinfo.xml
- docs/fr/getting-started.xml
- docs/fr/manual.xml
- docs/fr/preface.xml:
- add ommited files
-
- * docs/fr/language-defs.ent:
- split the french dir
-
- * docs/fr/appendixes.sgml
- docs/fr/designers.sgml
- docs/fr/getting-started.sgml
- docs/fr/html-common.dsl
- docs/fr/manual.sgml
- docs/fr/preface.sgml
- docs/fr/programmers.sgml:
- drop old french files
-
- * docs/manual.xml.in:
- let's put the new build system
-
-2004-03-26 Mehdi Achour <didou@keliglia.com>
-
- * docs/de/common.dsl
- docs/de/html.dsl
- docs/fr/common.dsl
- docs/fr/html.dsl
- docs/fr/php.dsl:
- not needed anymore
-
-2004-03-24 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/Makefile.in:
- updated stylesheets
- highlight PHP automatically
-
- * docs/Makefile.in
- docs/html.dsl:
- remove unneeded file
-
-2004-03-23 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/version.ent.in:
- remove this also
-
- * docs/getting-started.sgml:
- remove this one too
-
- * docs/appendixes.sgml
- docs/common.dsl
- docs/designers.sgml
- docs/html-common.dsl
- docs/manual.sgml
- docs/php.dsl
- docs/preface.sgml
- docs/programmers.sgml:
- removing uneeded files
-
- * docs/.cvsignore:
- commiting missing files for docbook
-
- * docs/.cvsignore
- docs/Makefile.in
- docs/configure.in
- docs/manual.xml.in:
- bundling docbook 4
- now make and make web works
-
-2004-03-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.config_load.php:
- unrolled call to the is_compiled()-check to be able to supply the
- correct resource_base_path for config_load. this avoids errors when
- config-files are accessed where security is enabled.
-
- thanks to shuther for pointing out this bug.
-
-2004-03-20 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/manual.xml.in:
- fix build date
-
-2004-03-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.is_secure.php:
- removed merging of $smarty->template_dir into $smarty->secure_dir
-
- the resource_base_path is considerd secure instead. this change should
- have absolutely no impact on smarty's security's behaviour
-
-2004-03-18 Nuno Lopes <nunoplopes@sapo.pt>
-
- * docs/configure.in:
- correcting non-existent var
-
- * docs/.cvsignore
- docs/Makefile.in
- docs/configure.in
- docs/manual.xml.in
- docs/version.ent.in:
- generate build date
-
- * docs/.cvsignore
- docs/Makefile.in
- docs/README
- docs/configure.in
- docs/manual.xml.in:
- new build/test system
-
-2004-03-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- moved setting of a default resource_base_path from
- Smarty::_parse_resource_name() to Smarty::_fetch_resource_info()
-
- this shouldn't affect anything, since all calls to
- _parse_resource_name() that are not done from within
- _fetch_resource_info() all pass their own resource_base_path
-
-2004-03-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- removed '.' from the list of default resource_base_paths in
- _parse_resource_name()
-
- this should only affect _parse_resource_name() for templates, not for
- php-resources and not for config_files. the latter pass two their own
- resource_base_path.
-
-2004-03-16 Mehdi Achour <didou@keliglia.com>
-
- * docs/appendixes.sgml
- docs/getting-started.sgml
- docs/preface.sgml:
- adding editor comments
-
- * docs/appendixes.sgml
- docs/getting-started.sgml:
- cleaning words spacing, killing tabulations, using roles for
- programlisting..
-
-2004-03-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- simplified Smarty::clear_all_cache();
-
-2004-03-12 boots <jayboots@yahoo.com>
-
- * docs/programmers.sgml:
- Updated is_cached prototype to indicate proper return type. (thanks to
- Geoffrey Hoffman)
-
-2004-03-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.assemble_plugin_filepath.php:
- fixed little bug that prevented plugins filepaths that are found in
- php's include_path (and not in one of the plugins_dirs) from being
- cached in the internal plugins-filepath-cache
-
-2004-03-01 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- update include_php docs:wq
- :q
-
- * docs/appendixes.sgml:
- update componentized template example to something useful
-
-2004-02-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- _parse_resource_name() returned true on non-existant absolute
- paths. This caused a warning on _fetch_resource_info() when used in
- conjunction with template_exists(). It should be fixed now without
- negative effects.
-
-2004-02-24 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- one more typo
-
- * docs/designers.sgml:
- fix typo
-
-2004-02-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/core/core.is_secure.php:
- smarty_resource_*_secure got &$smarty passed errornously as 3rd
- parameter and not as 2nd. this is fixed.
-
-2004-02-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS:
- fix handling of integer values like width and delay im
- smarty_function_popup()
-
- * libs/plugins/function.popup.php:
- fixed handling of integer-attributes
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- updated version to 2.6.3-dev
-
-2004-02-22 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_select_date.php:
- removed notice on html_select_date with the month_empty-attribute
-
- * libs/plugins/function.mailto.php:
- removed 2 notices of undefined vars (thanks Cit)
-
-2004-02-17 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- add header
-
- * (Smarty_2_6_2)
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- change some info in headers, remove fluff
-
-2004-02-13 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- correctly handle partially empty dates (like "2004--" or "-12-").
-
- * docs/programmers.sgml:
- learned something about <note> and sgml and applied this to the
- use.sub.dirs-section :)
-
- * docs/designers.sgml:
- changed attribute-name "checked" to "selected" in the docs for
- html_radios and html_checkboxes. "checked" is deprecated for ages
- AFAIK and selected is recommended for consistency with {html_options}
-
- * docs/programmers.sgml:
- added note about use_sub_dirs and Smarty-2.6.2 .
- fixed markup for section about clear_compiled_tpl() .
-
-2004-02-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Config_File.class.php:
- YES and NO should not be booleanized inside triple-quotes in a
- config-file. this behaviour changed by accident in 2.6.1 and is now
- reverted to pre-2.6.1 behaviour
-
-2004-02-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Config_File.class.php:
- fixed slurping of a the next line following a triple-quoted value in a
- config-file
-
-2004-02-07 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php:
- avoid @-operator for handling empty lines in Config_File.class.php
-
- * libs/Smarty_Compiler.class.php:
- removed two notices from Smarty_Compiler::_parse_is_expr()
- (thanks shuther!)
-
- * NEWS
- libs/Smarty.class.php:
- changed default for use_sub_dirs to false
-
- * libs/plugins/function.mailto.php:
- removed notice of undefined variable. (thanks shuther!)
-
-2004-01-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- added file and line-number-information to error-messages regarding
- assigned objects an an error messages regarding modifiers with
- security.
-
-2004-01-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- removed use of temporary var $_params in compiled code of block-plugins
-
- * NEWS
- libs/plugins/function.popup.php:
- fixed quoting of values in smarty_function_popup()
-
-2004-01-25 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/programmers.sgml:
- documented parameters of Smarty::clear_compiled_tpl()
-
- * libs/Smarty_Compiler.class.php:
- Smarty_Compiler::_syntax_error() uses Smarty::_trigger_fatal_error() now
- instead of the trigger_error()-function
-
- * libs/Smarty.class.php:
- Smarty::_trigger_fatal_error() uses Smarty::trigger_error() now,
- instead of the native trigger_error()-function
-
- * libs/Smarty_Compiler.class.php:
- unrecognized custom-functions trigger an error at compile now, not at
- display-time.
-
-2004-01-23 Monte Ohrt <monte@ispi.net>
-
- * docs/getting-started.sgml:
- reword a paragraph
-
-2004-01-22 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.config_load.php:
- removed emission of unnecessary notices for unavailable config-files
- in config_load()
-
- * NEWS
- libs/Config_File.class.php:
- fixed handling of hidden sections in Config_File
-
-2004-01-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.config_load.php:
- added handling of resources for {config_load}
-
-2004-01-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_table.php:
- fixed bug when using arrays with tr_attr and td_attr in {html_table}
-
-2004-01-16 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- add unit testing
-
- * NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers, add initial unit test directory
-
- * (Smarty_2_6_1)
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers for 2.6.1 release
-
-2004-01-16 Messju Mohr <messju@lammfellpuschen.de>
-
- * (Smarty_2_6_1)
- NEWS
- docs/programmers.sgml
- libs/Smarty.class.php:
- renamed $smarty->tpl_rror_reporting to $smarty->error_reporting
- "tpl_" is a bit redundant here (it's a TemPLate-engine overall :)
-
-2004-01-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_image.php:
- forgot to remove duplicate is_secure()-check
-
- * NEWS
- libs/plugins/function.html_image.php:
- fix: $smarty->security is now correctly handled
-
- minor optimizations:
- core/core.is_secure.php is only included when needed
- $dpi_default is only determined when needed
-
-2004-01-14 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/appendixes.sgml
- docs/programmers.sgml:
- removed suggestions to use extract() from the manual
-
- * docs/designers.sgml:
- fixed typo
-
-2004-01-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- mention SCRIPT_NAME below {$smarty} reserved variable because it got
- lost in the docs for $smarty->global_assign
-
- * docs/designers.sgml:
- added docs for {$smarty.version} special variable
-
- * docs/programmers.sgml:
- removed docs for $global_assign
-
- * docs/programmers.sgml:
- added docs for tpl_error_reporting
-
- * docs/designers.sgml:
- added docs for year_empty-, month_empty- and day_emtpy-attributes of
- html_select_date. maybe an example is needed to better explain empty
- values in YYY-MM-DD.
-
-2004-01-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed handling of {php}-tags
-
-2004-01-10 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- fix html_checkboxes examples
-
-2004-01-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/core/core.assemble_plugin_filepath.php:
- added caching of requested paths to smarty_core_assemble_plugin_filepath()
-
- * NEWS:
- fix handling of comments inside {php}- and {literal}-blocks
-
- * libs/Smarty_Compiler.class.php:
- fixed handling of comments inside {php} and {literal}
-
-2004-01-06 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Config_File.class.php:
- fixed bug handling triple-quotes in config-files
-
- * libs/Config_File.class.php:
- fixed bugs with triple-quotes in config-files
- thanks BRDude for finding them testing!
-
-2004-01-02 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- removed unnecessary param in call to _fetch_resource_info()
-
-2003-12-30 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- oops! removed tabs.
-
-2003-12-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- made $SCRIPT_NAME available again
- changes default for request_use_auto_global to prefer autoglobals
-
- * libs/Smarty.class.php:
- removed tabs and trailing spaces
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- readded default_modifiers. who removed that?
-
-2003-12-23 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- add portuguese docs
-
-2003-12-22 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- fix counter example
-
-2003-12-19 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php:
- add debug console persistance feature
-
-2003-12-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/block.textformat.php
- libs/plugins/function.html_table.php
- libs/plugins/function.popup.php:
- removed extract(). enhanced parameter parsing.
-
- * libs/plugins/function.counter.php
- libs/plugins/function.fetch.php
- libs/plugins/function.popup_init.php
- libs/plugins/modifier.capitalize.php
- libs/plugins/modifier.cat.php
- libs/plugins/modifier.date_format.php
- libs/plugins/modifier.debug_print_var.php
- libs/plugins/modifier.escape.php
- libs/plugins/modifier.indent.php
- libs/plugins/modifier.lower.php
- libs/plugins/modifier.nl2br.php
- libs/plugins/modifier.strip.php
- libs/plugins/modifier.upper.php
- libs/plugins/modifier.wordwrap.php
- libs/plugins/outputfilter.trimwhitespace.php
- libs/plugins/shared.escape_special_chars.php:
- removed tabs. fixed indentiation.
-
- * libs/plugins/modifier.truncate.php:
- removed tabs
-
- * libs/plugins/function.counter.php
- libs/plugins/function.cycle.php:
- removed extract() from parameter-parsing
-
-2003-12-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_select_date.php:
- fix plugin-name in error message
-
- * libs/plugins/function.html_select_time.php:
- remove extract-call from {html_select_time}
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- allow single-digit days and months without smarty_make_timestamp()
- this makes dates like "1968-11-6" work correctly since no strtotime()
- is involved
-
- add warning when unknown parameter is passed
-
-2003-12-16 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- fix headers sent erroneously with cache_modified_check and fetch()
-
-2003-12-12 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/function.config_load.php:
- move set_path() call below the conditional bracket
-
- * NEWS
- libs/plugins/function.config_load.php:
- fix config_load filepath bug
-
-2003-12-12 boots <jayboots@yahoo.com>
-
- * docs/designers.sgml:
- Updated language.function.if with additional annotation and to fix error
- that broke docs build process
-
-2003-12-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- little optimization for "is odd" and "is even"
-
-2003-12-11 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix 'is even by' and 'is odd by' logic
-
-2003-12-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- update example-output of {mailto}
-
- * libs/plugins/function.mailto.php:
- removed extract-call -> cleaner parameter-handling
-
- * libs/plugins/function.mailto.php:
- fixed indentiation
-
- * TODO:
- removed two done topics
-
-2003-12-11 boots <jayboots@yahoo.com>
-
- * docs/designers.sgml:
- Updated language.function.if to describe qualifiers (thanks andre)
-
-2003-12-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_select_date.php:
- added day_empty, month_empty, year_empty and all_empty attributes
- to pass an undefined date use {html_select_date time="--" ...}
-
- * libs/plugins/function.html_select_date.php:
- removed extract()-call
-
- * libs/plugins/function.html_select_date.php:
- fixed indetiation
-
-2003-12-10 boots <jayboots@yahoo.com>
-
- * NEWS
- docs/designers.sgml:
- Added table to language.function.if to describe qualifiers
-
-2003-12-09 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_options.php:
- strict comparason didn't work in all cases. use type-casting now.
-
- * NEWS
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_options.php:
- fix bug when comparing array-keys to "selected" in html_options and
- html_checkboxes
-
- in_array() uses "strict" comparason now.
-
- * libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_radios.php:
- removed tabs, fixed indentiation
-
-2003-12-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- add better checks for correctly nested tags when compiling
-
-2003-12-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/plugins/function.html_image.php:
- fix: check $smarty->request_use_auto_globals at the last occurences of
- HTTP_*_VARS
-
-2003-12-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- remove $global_assign property from Smarty and $global_assign-handling
- from the constructor. the only visible change is, that $SCRIPT_NAME is
- not available in the tempates anymore. $smarty.server.SCRIPT_NAME has
- to be used from now.
-
-2003-12-03 boots <jayboots@yahoo.com>
-
- * docs/designers.sgml:
- Fixed example for count_characters
-
-2003-12-01 boots <jayboots@yahoo.com>
-
- * docs/designers.sgml:
- Added section "Escaping Smarty Parsing" under Basic Syntax.
-
-2003-12-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.create_dir_structure.php:
- thought again about my latest commit and backed it out.
-
- * libs/core/core.create_dir_structure.php:
- fix root-dir-handling on windows filepath
-
-2003-11-29 boots <jayboots@yahoo.com>
-
- * libs/plugins/function.config_load.php:
- really make the fixes the last patch was supposed to do
-
- * libs/plugins/function.config_load.php:
- removed tabs and killed trailing white-space
-
- * libs/plugins/function.config_load.php:
- changed $smarty->_syntax_error to $smarty->trigger_error
-
-2003-11-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/modifier.debug_print_var.php:
- remove warning in debug_print_var on php-resources
-
- * README:
- fix version number
-
-2003-11-26 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- raise max_level for $smarty.config... to 3 to allow arrays of config-vars
-
-2003-11-25 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- changed version-tag to indicate incompatibility to older compiled
- templates
-
-2003-11-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/compiler.assign.php
- libs/plugins/function.assign.php:
- move function.assign.php to compiler.assign.php
-
- * libs/core/core.get_include_path.php:
- silence occasional warnings of open_basedir- and
- safe_mode-restrictions in core.get_include_path.php
-
-2003-11-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.write_compiled_resource.php
- libs/core/core.write_file.php:
- avoid touch()-ing of recently unlinked files by touch()-ing the
- tempfile before rename instead of touch()-ing the resulting file after
- rename.
-
- * NEWS
- libs/Smarty.class.php:
- add property $tpl_error_reporting
-
-2003-11-22 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.assign.php:
- remove use of extract() in smarty_function_assign()
-
- * NEWS
- libs/Smarty.class.php:
- remove property $undefined. "null" is used literally instead
-
-2003-11-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- remove two E_NOTICES
-
-2003-11-20 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- change version to 2.6.1-dev
-
-2003-11-19 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_6_0)
- NEWS:
- update NEWS file
-
- * (Smarty_2_6_0)
- docs/designers.sgml
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- change version numbers to 2.6.0
-
-2003-11-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml
- docs/de/designers.sgml
- docs/fr/designers.sgml:
- fix examples of escape-modifier (in docs, docs/de and docs/fr !)
-
-2003-11-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- move Smarty::quote_replace() to Smarty_Compiler::_quote_replace()
-
- * libs/Smarty.class.php:
- removed extract-calls from _include()- and _eval()-wrappers
- variables passed with {include_php} have to accessed as members of $params
- now
-
-2003-11-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- fixed typo
-
-2003-11-13 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php:
- fix occasional notice
-
-2003-11-13 andreas halter <phpcvs@andreashalter.ch>
-
- * docs/de/designers.sgml:
- - added cat modifier, thanks messju :-)
-
-2003-11-13 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_6_0-RC3)
- NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- commit RC3 tags
-
-2003-11-13 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix handling of $var.key inside []
-
- * libs/Smarty.class.php:
- fix unnecessary loading of core.load_resource_plugin.php
-
- * (Smarty_2_6_0-RC3)
- docs/fr/designers.sgml:
- fixed example of html_table
-
-2003-11-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/core/core.process_cached_inserts.php:
- fix handling of assign inside {insert}-tags
-
-2003-11-06 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.read_cache_file.php:
- added $exp_time-parameter
-
- * docs/programmers.sgml:
- added $exp_time to cache_handler_func-example
-
- * libs/Smarty.class.php
- libs/core/core.write_cache_file.php:
- added $exp_time-parameter of clear_cache() and clear_all_cache() to
- cache_handler_func.
-
-2003-11-05 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Config_File.class.php:
- fix handling if [...] inside triple-quotes in config-files
-
-2003-11-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- fixed little bug in _parse_resource_name() (jlgunter, messju)
-
-2003-11-03 andreas halter <phpcvs@andreashalter.ch>
-
- * docs/designers.sgml
- docs/de/designers.sgml
- docs/fr/designers.sgml:
- - changed Smarty.php.class occurences to Smarty.class.php
-
-2003-10-29 boots <jayboots@yahoo.com>
-
- * docs/appendixes.sgml
- docs/designers.sgml
- docs/manual.sgml
- docs/programmers.sgml
- docs/de/appendixes.sgml
- docs/de/designers.sgml
- docs/de/programmers.sgml
- docs/fr/appendixes.sgml
- docs/fr/designers.sgml
- docs/fr/getting-started.sgml
- docs/fr/manual.sgml
- docs/fr/preface.sgml
- docs/fr/programmers.sgml:
- Fixes to documentation syntax so that all content can be processed used
- xsltproc docbook-xsl tools. In particular, fixes unescaped entities,
- broken tags, unquoted attributes.
-
-2003-10-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix handling of simple-math-operators inside modifiers
-
-2003-10-25 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- removed unused property _output_type
- removed unused param $tag_attrs of _parse_var_props()
- cleaned up alignment of class-properties
-
-2003-10-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- removed notice in php-tag handling in Smarty_Compiler::_compile_file()
-
- * libs/Smarty_Compiler.class.php:
- removed two occasional E_NOTICES from
- Smarty_Compiler::_compile_include_php_tag()
-
- * NEWS
- libs/core/core.create_dir_structure.php:
- fix handling of trailing-slashes in open_basedir in
- smarty_core_create_dir_structure()
-
-2003-10-20 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- elements inside `` are bracketed now inside the compiled-tpl. this
- fixes some issues with simple-math inside backticks.
-
-2003-10-16 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- update overlib docs, no working examples
-
-2003-10-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/core/core.is_secure.php:
- move check for template_dir in secure_dir-array into core.is_secure.php
-
- this makes template_exists() work correctly with security=true even if
- template_dir is not inside the secure_dir-array
-
-2003-10-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/shared.make_timestamp.php:
- tightened check for YYYYMMDDHHMMSS-format. thanks konstantin for
- pointing this out.
-
- removed a few tabs.
-
- * libs/Smarty_Compiler.class.php:
- fix precedence of simple-math-operators before modifiers.
- thanks dominik!
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.assemble_plugin_filepath.php
- libs/core/core.assign_smarty_interface.php
- libs/core/core.create_dir_structure.php
- libs/core/core.display_debug_console.php
- libs/core/core.get_include_path.php
- libs/core/core.get_microtime.php
- libs/core/core.get_php_resource.php
- libs/core/core.is_secure.php
- libs/core/core.is_trusted.php
- libs/core/core.load_plugins.php
- libs/core/core.load_resource_plugin.php
- libs/core/core.process_cached_inserts.php
- libs/core/core.process_compiled_include.php
- libs/core/core.read_cache_file.php
- libs/core/core.rm_auto.php
- libs/core/core.rmdir.php
- libs/core/core.run_insert_handler.php
- libs/core/core.smarty_include_php.php
- libs/core/core.write_compiled_include.php
- libs/core/core.write_compiled_resource.php
- libs/core/core.write_file.php:
- removed tabs from the main and the core/*.php files
-
-2003-10-08 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_6_0-RC2)
- NEWS
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- update version numbers to RC2
-
-2003-09-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml
- docs/de/designers.sgml:
- fixed description of cycle's advance-attribute
-
-2003-09-16 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- apply modifiers only once to section-loop and foreach-from attributes
-
-2003-09-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.write_cache_paths_file.php:
- backed out _smarty_cached_paths-file-handling
-
- * libs/Smarty.class.php
- libs/core/core.rm_auto.php:
- fixed clear_compiled_tpl with explicit $tpl_file given
- fixed return value of smarty_core_rm_auto() + Smarty::_unlink()
-
- * libs/Smarty.class.php:
- little fix in _get_auto_filename()
-
-2003-09-14 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/core/core.assemble_auto_filename.php:
- removed auto-filenames from path-cache. merged assemble_auto_filename
- back into Smarty::_get_auto_filename()
-
-2003-09-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed quoting of modifier parameters
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.get_php_resource.php
- libs/core/core.load_plugins.php
- libs/core/core.load_resource_plugin.php:
- remove Smarty::_plugin_implementation_exists() - use php's native
- is_callable()
-
-2003-09-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- silenced two notices acces HTTP_SERVER_VARS
-
-2003-09-10 andreas halter <phpcvs@andreashalter.ch>
-
- * docs/de/designers.sgml
- docs/de/getting-started.sgml
- docs/de/programmers.sgml:
- - minor fixes (2 rep), slight wording changes
- - jade transform problem fixed
-
-2003-09-08 andreas halter <phpcvs@andreashalter.ch>
-
- * docs/de/designers.sgml
- docs/de/getting-started.sgml
- docs/de/manual.sgml
- docs/de/preface.sgml
- docs/de/programmers.sgml:
- all updated for 2.6.0 release, translated everything from 2_5_0 branch to
- 20030908
-
-2003-09-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- proper checking for files in _fetch_resource_info()
-
-2003-09-02 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- ignore {strip}/{/strip) inside {strip}-blocks
-
- * libs/plugins/function.mailto.php:
- fixed 2 notices in smarty_function_mailto()
-
-2003-09-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- re-include cache_paths on multiple calls to fetch() to avoid
- inconsistencies
- at multiple calls to fetch() in one script
-
- * libs/Smarty_Compiler.class.php:
- fixed handling of \r in {strip}
- renamed $_trailing_lf to $_additional_newline
-
- * libs/Smarty_Compiler.class.php:
- the weekly fix for {strip} :)
-
- * docs/designers.sgml:
- fixed example for simple math.
-
-2003-08-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.assign_smarty_interface.php
- libs/core/core.display_debug_console.php
- libs/plugins/function.assign.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_table.php:
- fixed PHPDocumentor-comments (thanks Konstantin)
-
- * libs/core/core.rmdir.php:
- made rmdir a bit more optimistic. especially it now removes
- directories correctly that where created accidently by "safe_mode=On
- && $use_sub_dirs=true"
-
-2003-08-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed removal of leading/trailing newlines in {strip}-blocks
-
-2003-08-25 Messju Mohr <messju@lammfellpuschen.de>
-
- * INSTALL:
- added note emphasizing the introduction of "libs/" with 2.5.0
-
- * NEWS
- libs/plugins/modifier.escape.php:
- fixed proper escaping of " and ' with escape:javascript
-
-2003-08-22 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/core/core.assemble_plugin_filepath.php:
- fixed bug in traversal of $smarty->plugins_dir-array in
- smarty_core_assemble_plugin_filepath(). the first matching plugin in
- the path should be used, not the last one.
-
- * libs/core/core.read_cache_file.php:
- discard $_cache_info when the cache should be regenerated
-
-2003-08-20 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php
- libs/plugins/block.strip.php:
- reverted {strip} from a block-plugin back into the compiler
-
- * docs/programmers.sgml:
- fixed examples for register_function() and register_block()
-
- * libs/Smarty.class.php:
- made template_exists() quiet when the template does not exist (thanks
- to konstatin for pointing this out)
-
-2003-08-18 Monte Ohrt <monte@ispi.net>
-
- * docs/getting-started.sgml:
- fix example title
-
- * docs/README
- docs/getting-started.sgml:
- change installation wording confusion
-
-2003-08-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/core/core.read_cache_file.php:
- fixed unnecessary load of source in template_exists() and the
- compile-check of smarty_core_read_cache_file()
-
- * libs/Smarty_Compiler.class.php:
- allow section-, array- and object-dereference in $smarty-references
-
-2003-08-15 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- added parameter-descriptions for count_characters (thanks Konstantin
- A. Pelepelin)
-
- fixed docs for {html_checkboxes}
-
-2003-08-14 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/core/core.read_cache_file.php:
- fixed timestamp-check of config-files in smarty_core_read_cache_file()
-
- * libs/Smarty.class.php:
- fixed typecasting for arrays in _parse_resource_name()
-
- * NEWS
- libs/plugins/function.config_load.php:
- fixes in config_load:
- - handling of section-attribute
- - reusing the same config-file multiple times
- - serialization of config-data for php<4.2.0 (no var_export)
-
- many thanks to atu for pointing this out and for testing
-
-2003-08-13 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/core/core.smarty_include_php.php:
- fixed problem with vars as attributes in {include_php}
-
-2003-08-13 Monte Ohrt <monte@ispi.net>
-
- * docs/README:
- commit README file for documentation compiling
-
-2003-08-13 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/debug.tpl
- libs/plugins/modifier.debug_print_var.php:
- removed '\r' from debug_print_vars' output
- properly escape vars in javascript-version of debug.tpl
-
-2003-08-11 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_6_0_RC1)
- NEWS
- docs/designers.sgml
- docs/html.dsl
- docs/php.dsl
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- get ready for 2.6.0-RC1 release
-
-2003-08-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- fixed status-header for cache_modified_check under cgi-sapi
-
-2003-08-09 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.is_secure.php
- libs/core/core.is_trusted.php:
- synced secure_dir-checking with trusted_dir-checking
-
- * libs/core/core.is_secure.php:
- tightenend path checking in smarty_core_is_secure()
-
-2003-08-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- fix: proper nesting of $smarty->_cache_including flag in cascaded
- cached/not-cached/fetched/inserted/foo-templates
-
- * libs/debug.tpl:
- better escaping for $_debug_tpls[templates].filenames
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- removed redundant $smarty from Smarty::_smarty_include()
-
- * libs/debug.tpl:
- proper escaping of filenames in debug-console (thanks to prossel).
-
-2003-08-07 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/programmers.sgml:
- added docs for block-methods of registered objects
-
- * docs/programmers.sgml:
- fixed typo in example for registered objects
-
- * docs/designers.sgml:
- fixed exampls of html_image and html_checkboxes
-
- * libs/plugins/function.debug.php:
- fixed {debug} and removed tabs in function.debug.php
-
- * docs/programmers.sgml:
- fixed example for register_object
-
- * docs/designers.sgml
- docs/programmers.sgml:
- updated docs for capture, html_table, html_image and register_object
-
-2003-08-07 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- docs/programmers.sgml:
- add math and default_resource_type to docs
-
- * docs/getting-started.sgml:
- add core to example, add tech note
-
-2003-08-07 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/manual.sgml
- docs/fr/manual.sgml:
- upd copyright in the docs
-
-2003-08-07 Monte Ohrt <monte@ispi.net>
-
- * docs/getting-started.sgml:
- added core directory to install instructions
-
-2003-08-07 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml
- docs/programmers.sgml:
- added docs for php-functions as modifiers
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- better caching of attributes for $cacheable=false-plugins
-
- * docs/programmers.sgml:
- added section "caching.cacheable" to the docs, explaining the usage of
- the $cacheable-flag of the register_(block|compiler|function)-functions
-
- * libs/Smarty_Compiler.class.php:
- fixed output of custom-functions with cached attributes
-
- * docs/programmers.sgml:
- docs update on callbacks to the register_*-functions
-
-2003-08-06 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.process_compiled_include.php:
- added optional parameter $cache_attrs to register_function() and
- register_block(). $cache_attrs is an array containing attribute- names
- that should be cached on calls to functions that have $cacheable set
- to false.
-
- * libs/Smarty.class.php:
- fixed bug in _run_mod_handler
-
- * libs/Smarty_Compiler.class.php:
- fixed bug with autoload-handling of modifiers. thanks ándre.
-
-2003-08-05 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- updated copyright notice
-
- * libs/Smarty.class.php
- libs/core/core.load_plugins.php:
- fixed bug that occurred when using the same not-cacheable plugin in
- multiple includes
-
- * docs/programmers.sgml:
- docs-update for plugins.writing
-
-2003-08-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml
- docs/programmers.sgml:
- updated docs for register_block_function(), block-functions,
- $request_use_auto_globals and html_checkboxes
-
-2003-07-31 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- enabled registration of class-methods as callbacks for the
- register_*-functions
-
- use: array('classname', 'method_name')) as callback
-
-2003-07-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- modifiers are resolved at compile-time now. _run_mod_handler() is
- still used for modifiers with map_array=true (== no preceeding '@')
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.smarty_include.php:
- moved _smarty_include() back into Smarty.class.php
-
- * libs/Smarty.class.php
- libs/core/core.load_plugins.php:
- prevent unnecessary calls to _read_file() in _is_compiled()
- converted method-call to internal function-call in
- smarty_core_load_plugins()
-
-2003-07-28 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- quote smarty-header properly to prevent resource-names from escaping from
- the comment
-
-2003-07-25 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.create_dir_structure.php:
- weakend race-condition and removed bogus error-message caused by that
- in smarty_core_create_dir_structure().
-
-2003-07-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/core/core.display_debug_console.php
- libs/core/core.fetch_resource_info.php
- libs/core/core.get_php_resource.php
- libs/core/core.parse_resource_name.php
- libs/core/core.process_cached_inserts.php
- libs/core/core.read_cache_file.php
- libs/core/core.run_insert_handler.php
- libs/core/core.smarty_include.php
- libs/core/core.smarty_include_php.php
- libs/plugins/function.eval.php:
- moved _fetch_resource_info and _parse_resource_name back into
- Smarty.class.php
- renamed smarty_include and smarty_eval wrappers to _include and _eval
-
-2003-07-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.process_compiled_include.php
- libs/core/core.read_cache_file.php:
- improved checking of compiled_include against cached-template with
- non-cached-chunks
-
- * libs/core/core.write_compiled_include.php:
- fixed too short open-tag
-
- * libs/plugins/function.eval.php:
- fixed assign parameter for eval (must have gotton lost on its way to 2.5.0)
- cleaned up indentiation
-
-2003-07-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- resurrected $foo->$bar syntax
-
- * libs/Smarty_Compiler.class.php:
- i'm so stupid. kick me.
-
- * libs/Smarty_Compiler.class.php:
- fixed initialisation of $this->_plugins in compile_block_tag()
-
-2003-07-03 Monte Ohrt <monte@ispi.net>
-
- * libs/Config_File.class.php:
- add preg_quote delimiter
-
-2003-07-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- applied fix for {$var1->p1|modifier:$var2->p2}-syntax - thanks Dominik
-
-2003-07-02 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed duplicate generation of arg-list in _compile_block_tag()
-
- * libs/Smarty_Compiler.class.php:
- fixed off-by-one-error in nocache-tag-handling
-
-2003-06-30 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- backed out errornously committed support for $foo->$bar
-
- * libs/core/core.write_file.php:
- fixed indentiation, silenced occasional warning
-
- * libs/plugins/function.html_image.php:
- match first character of file-attribute against "/" instead of
- DIRECTORY_SEPARATOR since it is a url-path and not a file-path.
-
- * libs/Smarty_Compiler.class.php
- libs/core/core.write_file.php
- libs/plugins/function.html_image.php:
- libs/plugins/function.html_image.php
-
- * libs/Smarty_Compiler.class.php:
- re-fixed cacheable_state-handling
-
- * libs/core/core.display_debug_console.php
- libs/core/core.process_cached_inserts.php
- libs/core/core.process_compiled_include.php
- libs/core/core.run_insert_handler.php:
- extincting $this out of smarty_core_*-functions
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- fixed handling of nocache-state
-
-2003-06-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/core/core.smarty_include.php
- libs/core/core.smarty_include_php.php
- libs/plugins/function.eval.php:
- removed $this from smarty_include and smarty_include_php
- added cleaner handling of $this to {eval}
-
- * libs/core/core.load_resource_plugin.php:
- fixed inlude_once-call
-
- * docs/de/designers.sgml
- docs/fr/designers.sgml:
- fixed examples of html_radios and html_checkboxes in german and french docs
-
-2003-06-25 Monte Ohrt <monte@ispi.net>
-
- * libs/core/core.assemble_auto_filename.php
- libs/core/core.write_cache_paths_file.php:
- fix typo, fix write_cache_paths logic
-
- * libs/Smarty.class.php
- libs/core/core.assemble_auto_filename.php:
- fix SMARTY_COMPILE_DIR_SEP problem, make local var
-
-2003-06-24 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php
- libs/core/core.assemble_auto_filename.php
- libs/core/core.write_cache_paths_file.php:
- fixed cache_paths bug, simplified filename assembly logic
-
-2003-06-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.html_image.php:
- added parsing of forgotton param "basedir"
-
- * libs/Smarty_Compiler.class.php:
- fixed $smarty.get-reference
-
- * libs/plugins/block.textformat.php:
- removed warning
-
- * libs/Smarty_Compiler.class.php:
- fixed value of _cacheable_state on compiler-startup
-
-2003-06-23 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.write_cache_paths_file.php:
- make cache_path per resource, fix a couple directory path issues
-
-2003-06-23 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- removed warning when compiling empty template
-
- * libs/core/core.write_compiled_include.php:
- fixed bug in write_compiled_include
-
- * libs/core/core.assemble_plugin_filepath.php:
- fixed warning
-
-2003-06-22 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.eval.php:
- fixed propagation of $this into evald code in smarty_function_eval()
-
- * libs/core/core.write_cache_paths_file.php
- libs/core/core.write_compiled_include.php:
- fix in compiled-include-handling
-
- * libs/core/core.assemble_auto_filename.php
- libs/core/core.assemble_plugin_filepath.php
- libs/core/core.assign_smarty_interface.php
- libs/core/core.create_dir_structure.php
- libs/core/core.fetch_resource_info.php
- libs/core/core.get_include_path.php
- libs/core/core.get_microtime.php
- libs/core/core.get_php_resource.php
- libs/core/core.is_secure.php
- libs/core/core.is_trusted.php
- libs/core/core.load_plugins.php
- libs/core/core.load_resource_plugin.php
- libs/core/core.parse_resource_name.php
- libs/core/core.read_cache_file.php
- libs/core/core.rm_auto.php
- libs/core/core.rmdir.php
- libs/core/core.write_cache_file.php
- libs/core/core.write_cache_paths_file.php
- libs/core/core.write_compiled_include.php
- libs/core/core.write_compiled_resource.php
- libs/core/core.write_file.php
- libs/plugins/modifier.date_format.php:
- started moving from $this to $smarty in core.*.php
-
-2003-06-21 Monte Ohrt <monte@ispi.net>
-
- * libs/core/core.create_dir_structure.php
- libs/core/core.write_file.php
- libs/plugins/function.config_load.php:
- fix more dir paths
-
- * NEWS
- libs/Smarty.class.php
- libs/core/core.assemble_auto_filename.php
- libs/core/core.assemble_plugin_filepath.php
- libs/core/core.fetch_resource_info.php
- libs/core/core.get_php_resource.php
- libs/core/core.parse_resource_name.php
- libs/core/core.process_cached_inserts.php
- libs/core/core.read_cache_file.php
- libs/core/core.rm_auto.php
- libs/core/core.rmdir.php
- libs/core/core.run_insert_handler.php
- libs/core/core.smarty_include.php
- libs/core/core.smarty_include_php.php
- libs/core/core.write_cache_file.php
- libs/core/core.write_cache_paths_file.php
- libs/core/core.write_compiled_include.php
- libs/core/core.write_compiled_resource.php
- libs/core/core.write_file.php
- libs/plugins/function.config_load.php
- libs/plugins/function.fetch.php
- libs/plugins/function.html_image.php:
- fix filepaths to core files to use DIRECTORY_SEPARATOR
-
-2003-06-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed {plugin|modifier} syntax
-
- * libs/Smarty.class.php
- libs/core/core.write_compiled_include.php:
- fixed compiled include handling
-
-2003-06-21 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.assemble_auto_filename.php
- libs/core/core.assemble_plugin_filepath.php
- libs/core/core.write_cache_paths_file.php:
- added filepath caching
-
-2003-06-20 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- update more varnames
-
- * libs/Smarty.class.php
- libs/core/core.display_debug_console.php
- libs/core/core.fetch_file_info.php
- libs/core/core.fetch_resource_info.php
- libs/core/core.get_php_resource.php
- libs/core/core.parse_file_path.php
- libs/core/core.parse_resource_name.php
- libs/core/core.process_cached_inserts.php
- libs/core/core.read_cache_file.php
- libs/core/core.run_insert_handler.php
- libs/core/core.smarty_include.php
- libs/core/core.smarty_include_php.php
- libs/core/core.write_compiled_resource.php
- libs/core/core.write_compiled_template.php
- libs/plugins/function.config_load.php:
- refactored var naming to better reflect "resource" instead of "file" where
- appropriate
-
-2003-06-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- updated version-number to 2.5.0-cvs
-
- * libs/core/core.write_cache_file.php:
- omit is-cache_dir-writable-check if a cache_handler_function is in use
-
- * libs/core/core.smarty_include_php.php:
- fixed comments in smarty_include_php
-
-2003-06-19 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.display_debug_console.php
- libs/core/core.smarty_include.php
- libs/plugins/function.eval.php:
- split up _compile_template to _compile_file and _compile_source, fix eval
- function
- VS: ----------------------------------------------------------------------
-
- * libs/plugins/function.config_load.php:
- fix logic for _is_compiled()
-
-2003-06-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- added optional assign-attribute to {capture}-tag
-
- * NEWS
- libs/Smarty.class.php:
- added $cacheable-parameter to register_compiler_function()
-
-2003-06-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.load_plugins.php
- libs/core/core.process_compiled_include.php
- libs/core/core.read_cache_file.php
- libs/core/core.write_cache_file.php
- libs/core/core.write_compiled_include.php:
- added $cacheable-parameter to register_function() and register_block()
-
- * libs/Smarty.class.php:
- append '.php' to all compiled templates regardless of the settings of
- $use_sub_dirs
-
- * libs/Smarty.class.php
- libs/core/core.read_cache_file.php:
- fixed $file_path-parameters passed to smarty_core_fetch_file_info()
-
-2003-06-17 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- fix name
-
- * libs/Smarty_Compiler.class.php:
- change varnames to follow coding methods
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- add math patch to core
-
-2003-06-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/core/core.smarty_include.php:
- switched _process_template() to _is_compiled()-logic
-
-2003-06-17 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php:
- fix _is_compiled logic
-
- * NEWS:
- update news file
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- fix _run_mod_handler routine
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.display_debug_console.php
- libs/core/core.fetch_file_info.php
- libs/core/core.parse_file_path.php
- libs/core/core.write_compiled_template.php
- libs/plugins/function.config_load.php:
- fix path problems, rename some varibles from "template" to "file"
-
-2003-06-16 Monte Ohrt <monte@ispi.net>
-
- * libs/core/core.fetch_file_info.php
- libs/core/core.fetch_template_info.php:
- rename file, commit
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.parse_file_path.php
- libs/core/core.read_cache_file.php
- libs/plugins/block.strip.php
- libs/plugins/block.textformat.php
- libs/plugins/compiler.config_load.php
- libs/plugins/function.config_load.php
- libs/plugins/function.eval.php
- libs/plugins/function.fetch.php
- libs/plugins/function.html_image.php:
- fix config_load, compile fetched arrays to compile_dir, switch display
- back to runtime. clean up var names and function names, split up compile
- testing and compiling to separate funcs, rename some template_* functions
- to
- file_* functions and update logic so they can be used for file resources
- other than templates.
-
-2003-06-16 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed little bug in _compile_custom_tag()
-
-2003-06-16 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/core/core.assign_smarty_interface.php
- libs/core/core.create_dir_structure.php
- libs/core/core.display_debug_console.php
- libs/core/core.fetch_template_info.php
- libs/core/core.get_include_path.php
- libs/core/core.get_microtime.php
- libs/core/core.get_php_resource.php
- libs/core/core.is_secure.php
- libs/core/core.is_trusted.php
- libs/core/core.load_plugins.php
- libs/core/core.load_resource_plugin.php
- libs/core/core.parse_file_path.php
- libs/core/core.process_cached_inserts.php
- libs/core/core.read_cache_file.php
- libs/core/core.rm_auto.php
- libs/core/core.rmdir.php
- libs/core/core.run_insert_handler.php
- libs/core/core.smarty_include.php
- libs/core/core.smarty_include_php.php
- libs/core/core.write_cache_file.php
- libs/core/core.write_compiled_template.php
- libs/core/core.write_file.php
- libs/plugins/core.assign_smarty_interface.php
- libs/plugins/core.create_dir_structure.php
- libs/plugins/core.display_debug_console.php
- libs/plugins/core.fetch_template_info.php
- libs/plugins/core.get_include_path.php
- libs/plugins/core.get_microtime.php
- libs/plugins/core.get_php_resource.php
- libs/plugins/core.is_secure.php
- libs/plugins/core.is_trusted.php
- libs/plugins/core.load_plugins.php
- libs/plugins/core.load_resource_plugin.php
- libs/plugins/core.parse_file_path.php
- libs/plugins/core.process_cached_inserts.php
- libs/plugins/core.read_cache_file.php
- libs/plugins/core.rm_auto.php
- libs/plugins/core.rmdir.php
- libs/plugins/core.run_insert_handler.php
- libs/plugins/core.smarty_include.php
- libs/plugins/core.smarty_include_php.php
- libs/plugins/core.write_cache_file.php
- libs/plugins/core.write_compiled_template.php
- libs/plugins/core.write_file.php:
- move core files into their own directory under SMARTY_DIR,
- remove abstraction function _execute_core_function
-
- * libs/Smarty_Compiler.class.php:
- fix newline handling for template for all template tags
-
-2003-06-11 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/compiler.config_load.php:
- add compiler function to cvs repository
-
-2003-06-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- added config-option "request_use_auto_globals" to make auto-globals be
- used as request vars instead of HTTP_*_VARS
-
-2003-06-11 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/plugins/function.config_load.php:
- make config vars compile statically
-
-2003-06-11 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- backed out newlines patch
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- removed newlines in compiled templates after closing tags
-
-2003-06-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/de/designers.sgml:
- fixed german note on html_image and disk-access
-
-2003-06-10 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/core.parse_file_path.php:
- fix bug with resource_type resolving
-
-2003-06-09 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- replace example with more practical one
-
-2003-06-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- added block-methods for registered objects
-
-2003-06-07 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/programmers.sgml:
- fixed bug in documentation for $smarty->default_modifiers
-
-2003-06-06 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/core.parse_file_path.php:
- fix problem with new default_resource_type changes
-
- * NEWS:
- update NEWS file info
-
- * NEWS
- libs/Smarty.class.php
- libs/plugins/core.parse_file_path.php:
- add default_resource_type, ignore 1 char resource names
-
- * NEWS
- libs/Config_File.class.php:
- fix bug where config file starts with hidden section
-
-2003-06-04 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty.class.php:
- -** empty log message ***
-
-2003-06-03 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/function.html_image.php:
- fix example in code comments
-
-2003-06-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.counter.php:
- fixed behaviour of start=... for {counter}
-
-2003-06-02 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.counter.php:
- fixed assign for {counter}
-
-2003-05-30 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/core.write_cache_file.php
- libs/plugins/core.write_compiled_template.php:
- add discrete error checking pertaining to $cache_dir
- and $compile_dir, their existance and writability
-
-2003-05-28 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_table.php:
- added params vdir, hdir and inner to html_table to allow looping over
- the data in various directions
-
-2003-05-28 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/core.compile_template.php
- libs/plugins/core.display_debug_console.php:
- fix problem with security and debug.tpl file
-
-2003-05-23 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- upd NEWS file
-
- * libs/Smarty_Compiler.class.php:
- allow spaces in literal tags
-
-2003-05-22 Monte Ohrt <monte@ispi.net>
-
- * docs/fr/programmers.sgml:
- fix special chars
-
-2003-05-19 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- speed up compiled templates, hardcode plugin filepaths instead of
- recalculate at runtime
-
-2003-05-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- fixed example of {html_image}
-
- * docs/designers.sgml:
- fixed typo
-
-2003-05-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/plugins/core.read_cache_file.php
- libs/plugins/core.smarty_include.php
- libs/plugins/function.config_load.php:
- fixed multiple redundant occurrences for 'config' and 'template' in
- $smarty->_cache_info
-
-2003-05-10 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/core.create_dir_structure.php:
- refurbished create_dir_structure to use '/' internally
-
- * libs/plugins/core.create_dir_structure.php:
- fixed windows absolute-paths in smarty_core_create_dir_structure()
-
- * libs/plugins/core.create_dir_structure.php:
- fixed error-message
-
-2003-05-09 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- fixed warning due to missing param to _execute_core_function()
-
- * libs/Smarty_Compiler.class.php:
- fixed quoting in _compile_include_php
-
- * libs/Smarty_Compiler.class.php:
- fixed quoting of "file"-parameter in _compile_include_tag()
-
-2003-05-08 Monte Ohrt <monte@ispi.net>
-
- * docs/programmers.sgml:
- fix typo
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/plugins/core.compile_template.php
- libs/plugins/core.create_dir_structure.php
- libs/plugins/core.fetch_template_info.php
- libs/plugins/core.get_include_path.php
- libs/plugins/core.get_microtime.php
- libs/plugins/core.get_php_resource.php
- libs/plugins/core.is_secure.php
- libs/plugins/core.is_trusted.php
- libs/plugins/core.load_plugins.php
- libs/plugins/core.load_resource_plugin.php
- libs/plugins/core.parse_file_path.php
- libs/plugins/core.process_cached_inserts.php
- libs/plugins/core.read_cache_file.php
- libs/plugins/core.rm_auto.php
- libs/plugins/core.rmdir.php
- libs/plugins/core.run_insert_handler.php
- libs/plugins/core.smarty_include.php
- libs/plugins/core.smarty_include_php.php
- libs/plugins/core.write_cache_file.php
- libs/plugins/core.write_compiled_template.php
- libs/plugins/core.write_file.php
- libs/plugins/function.config_load.php
- libs/plugins/function.fetch.php
- libs/plugins/function.html_image.php:
- abstract more private functions to plugin directory
-
- * libs/Config_File.class.php:
- only add DIRECTORY_SEPARATOR if it isn't already present
-
- * libs/Config_File.class.php:
- fix directory separator code, use DIRECTORY_SEPARATOR
-
-2003-05-08 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- fixed example of html_checkboxes
-
- * NEWS
- libs/Smarty.class.php:
- fixed bug in _create_dir_structure() when used with
- open_basedir-restriction and relative paths
-
- * docs/designers.sgml:
- fixed example for html_radios
-
-2003-05-07 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php
- libs/plugins/core.assign_smarty_interface.php
- libs/plugins/core.display_debug_console.php
- libs/plugins/function.display_debug_console.php:
- abstracted display_debug_console and assign_smarty_interface to plugin dir
- as a test
-
- * libs/Smarty.class.php
- libs/plugins/function.display_debug_console.php:
- correct misc varnames, abstract debug console display to plugin function
-
- * libs/plugins/modifier.escape.php:
- fix typo
-
-2003-05-05 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- add % to math
-
- * libs/Smarty.class.php:
- clean up comments, formatting
-
- * NEWS
- libs/Smarty.class.php:
- keep DIR_SEP for 3rd party compatability
-
- * NEWS
- libs/Smarty.class.php:
- remove DIR_SEP, use DIRECTORY_SEPARATOR exclusively
-
- * libs/Smarty_Compiler.class.php:
- remove ++ and -- math operators on template vars
-
-2003-05-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty_Compiler.class.php:
- removed unused parameter $quote from Smarty_Compiler::_parse_attrs()
-
- * libs/plugins/function.html_image.php:
- fixed DIR_SEP in html_image-plugin
-
-2003-05-04 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty.class.php:
- rename DIR_SEP to SMARTY_DIR_SEP to avoid varname collisions
-
-2003-05-04 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_image.php:
- changed "link" to "href" in html_image. "link" is still working but
- deprecated
- html_image always renders an alt-tag now (default alt="")
- cleaned up indentiation of function.html_image.php
-
-2003-05-03 Monte Ohrt <monte@ispi.net>
-
- * libs/debug.tpl:
- fix typo
-
-2003-05-02 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.counter.php:
- fixed assign attribute for multiple counters
-
-2003-05-02 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- allow math on negative number
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- added simple math operators to variables
-
-2003-05-02 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- fixed typos
-
-2003-04-30 Monte Ohrt <monte@ispi.net>
-
- * docs/fr/appendixes.sgml
- docs/fr/common.dsl
- docs/fr/designers.sgml
- docs/fr/getting-started.sgml
- docs/fr/html-common.dsl
- docs/fr/html.dsl
- docs/fr/manual.sgml
- docs/fr/php.dsl
- docs/fr/preface.sgml
- docs/fr/programmers.sgml:
- add frech docs to cvs repository
-
-2003-04-29 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- reverted patch for case-insensitive tag-names
-
-2003-04-28 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/programmers.sgml:
- reverted back to humerous redundancy in the docs :). although we all
- know we are here to generate template-based output, and not to have
- fun ;-)
-
- * docs/getting-started.sgml:
- fixed default user and group for max os x installation
-
- * libs/Smarty.class.php:
- made $function[2] and $function[3] options for register_resource
-
- * libs/Smarty.class.php:
- fixed issue with object-callback when fetching a php-resource
-
- * NEWS
- libs/Smarty.class.php:
- enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted') as
- callback for register_resource()
-
- enabled array(&$obj, 'method') as callback for
- $default_template_handler_func
-
-2003-04-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml
- docs/programmers.sgml:
- fixed some typos, thank to mehdi
-
- * libs/plugins/function.counter.php:
- prevent assign from overruling print-attribute in function.counter.php
-
- * libs/plugins/function.counter.php:
- fixed problem with counter and assign
-
- * libs/Smarty.class.php:
- fixed notice in _load_plugins()
-
- * NEWS
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- made plugin-names case-insensitive. this affects
- compiler/block/custom-functions and modifers.
-
-2003-04-26 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- remove unnecessary close/open tags from compiled templates
-
-2003-04-26 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- added documentation for foreach.property.*
-
-2003-04-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * docs/designers.sgml:
- fixed example table_attr and tr_attr in html_table-example
-
-2003-04-21 Greg Beaver <greg@chiaraquartet.net>
-
- * libs/Smarty.class.php:
- fixed small bug in doc comments
-
-2003-04-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_image.php:
- fixed errornous creation of '//' in image_path in html_image
-
-2003-04-21 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/modifier.debug_print_var.php:
- fix htmlspecialchars() conflict
-
- * NEWS
- libs/plugins/modifier.debug_print_var.php:
- fix escapement of special chars in key values of debug console
-
- * NEWS
- libs/plugins/function.config_load.php:
- fixed debug timing logic for config_load
-
- * docs/designers.sgml:
- fix example text
-
-
-2003-04-20 Greg Beaver <cellog@users.sourceforge.net>
- * plugins/*
- Smarty.class.php
- Smarty_Compiler.class.php
- Config_File.class.php:
- updated all doc comments to phpDocumentor format (whew!)
-
-2003-04-06 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/plugins/function.math.php:
- allowed "_" in the name of variable-parameters to {math}-function
-
-2003-04-04 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- docs/designers.sgml
- libs/Smarty_Compiler.class.php:
- change backtic syntax from $`foo` to `$foo`
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- recognize $foo[][] syntax in embedded quotes without backticks
-
-2003-04-03 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- name=123 is passed as an integer (not a string) to plugins now
-
-2003-04-01 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- added CVS $Id: ChangeLog 2746 2007-09-28 01:32:05Z changelog $
-
-2003-03-31 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- added missing compile_id inside Smarty_Compiler
-
- * libs/Smarty_Compiler.class.php:
- fixed flaw when generating an error for missing postfilter
-
-2003-03-31 Monte Ohrt <monte@ispi.net>
-
- * docs/getting-started.sgml
- docs/programmers.sgml:
- fix typos
-
-2003-03-27 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/modifier.debug_print_var.php:
- $length is now propagated to sub-values in debug_print_var
-
-2003-03-26 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- update header
-
- * RELEASE_NOTES:
- commit changes to release notes
-
- * (Smarty_2_5_0_RC2)
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- committing RC2
-
-2003-03-24 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- made clear_cache() ignore compile_id when clearing cache_groups
-
- * libs/plugins/function.popup.php:
- made onmouseout XHTML-compatible in function.popup.php
-
-2003-03-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- applied new var-names to fetch()
-
- * NEWS
- libs/Smarty.class.php:
- renamed $localvars to $_localvars in cache-file-handling-functions,
- added _get_auto_id()-function
-
-2003-03-21 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/function.mailto.php
- libs/plugins/function.popup.php:
- update functions for XHTML compatability
-
-2003-03-21 Messju Mohr <messju@lammfellpuschen.de>
-
- * libs/Smarty.class.php:
- fixed wrong $auto_id in _read_cache_file()
-
- * NEWS
- libs/Smarty.class.php:
- swapped compile_id and cache_id in read_cache_file and write_cache_file
-
- * libs/Smarty.class.php:
- reverted patch for ignoring compile-id back to -r1.364, due to problems
-
- * NEWS
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_radios.php:
- html_radios and html_checkboxes accept "selected" instead of "checked"
- optionally now
-
- * NEWS
- libs/Smarty.class.php:
- swapped compile_id and cache_id for cache-file-handling again
-
-2003-03-20 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- fix notice when no parameter is passed to default
-
-2003-03-20 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- removed notice of undefined var in _rm_auto()
-
-2003-03-19 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_radios.php
- libs/plugins/function.html_table.php:
- fix a few error messages, follow consistancy format plugin_name: errormsg
-
- * libs/plugins/function.html_radios.php:
- update error messages
-
- * NEWS
- libs/plugins/function.html_radios.php:
- add a warning when an array is passed as the 'checked' value of html_radios
-
-2003-03-19 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fixed errormessage in _compile_smarty_ref()
-
- * NEWS
- docs/designers.sgml:
- updated docs for html_image
-
-2003-03-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/Smarty.class.php:
- cleaned up calls to readdir()
-
- * libs/plugins/function.html_options.php:
- fixed label for optgroup in html_options
-
-2003-03-18 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix (newly introduced) bug with passing multiple modifiers to a parameter
-
-2003-03-18 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- docs/designers.sgml:
- updated docs for html_checkboxes, html_options and html_radios
-
- * libs/plugins/function.html_options.php:
- fixed wrong default-"name" in function.html_options.php
-
- * NEWS
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_radios.php:
- renamed "checkbox" and "radios" to "options" in {html_checkboxes} and
- {html_radios}
-
- * libs/plugins/outputfilter.trimwhitespace.php:
- tried to optimize re-replacement in outputfilter.trimwhitespace.php a
- little
-
- * libs/plugins/outputfilter.trimwhitespace.php:
- fixed greedy str_replace in outputfilter.trimwhitespace.php
-
- * NEWS
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_radios.php:
- html_options, html_checkboxes and html_radios now pass-thru all unknown
- paramters
-
-2003-03-17 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/function.html_options.php:
- html_options passthru all unknown paramters now
-
-2003-03-17 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/function.html_image.php:
- Fix link bug in html_image function, also make output XHTML compatible
-
- * libs/Smarty_Compiler.class.php:
- fix issue of embedded var and escaped double quotes
-
-2003-03-15 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- back out "@" logic, apply only to default modifier special case
-
- * libs/Smarty_Compiler.class.php:
- fix @ logic, only use upon an echo
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- append "@" to template var echoes to supress possible notices
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- append "@" to _run_mod_handler to supress warnings
-
-2003-03-14 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix problem with escaped double quotes
-
- * NEWS
- libs/plugins/function.html_radios.php:
- fixed html_options to not return an array
-
-2003-03-12 Messju Mohr <messju@lammfellpuschen.de>
-
- * NEWS
- libs/plugins/modifier.truncate.php:
- fixed length in modifier.truncate.php
-
- * NEWS
- libs/plugins/outputfilter.trimwhitespace.php:
- fixed handling of '$'-signs in trimwhitespace outputfilter (messju)
-
-2003-03-12 Monte Ohrt <monte@ispi.net>
-
- * docs/programmers.sgml:
- update technical explanation of assign_by_ref and append_by_ref
-
-2003-03-11 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/Smarty.class.php:
- fix config file recompiling code
-
-2003-03-07 Monte Ohrt <monte@ispi.net>
-
- * libs/plugins/function.html_image.php:
- change E_USER_ERROR to E_USER_NOTICE
-
- * libs/plugins/function.html_image.php:
- suppress warning in html_image
-
- * NEWS
- libs/plugins/function.html_image.php:
- update changes to html_image
-
-2003-03-06 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- docs/de/appendixes.sgml
- docs/de/common.dsl
- docs/de/designers.sgml
- docs/de/getting-started.sgml
- docs/de/html-common.dsl
- docs/de/html.dsl
- docs/de/manual.sgml
- docs/de/preface.sgml
- docs/de/programmers.sgml:
- add german docs to dist
-
- * NEWS:
- update news file
-
- * libs/plugins/function.html_image.php:
- fix width/height parameter index
-
- * NEWS
- libs/Smarty.class.php:
- get rid of unsetting name and script attributes to insert tags
-
-2003-03-05 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- RELEASE_NOTES:
- update NEWS file
-
- * libs/plugins/modifier.string_format.php:
- fix argument order, erroneously swapped a while back
-
- * (Smarty_2_5_0_RC1)
- NEWS
- README
- RELEASE_NOTES
- libs/Config_File.class.php
- libs/Smarty.class.php
- libs/Smarty_Compiler.class.php:
- commit final changes for 2.5.0-RC1
-
-2003-03-04 Monte Ohrt <monte@ispi.net>
-
- * docs/programmers.sgml:
- remove $show_info_header and $show_info_include property vars from docs
-
-2003-03-03 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/function.popup.php:
- fixed PHP notice
-
-2003-02-28 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty_Compiler.class.php:
- simplify smarty.const.foo and smarty.const.$foo logic
-
- * libs/Smarty_Compiler.class.php:
- only allow $foo syntax in embedded quotes, unless escaped with backticks
- then allow any dollar var
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- fix "once" var compiling to work with new attr compiling methods for
- include_php
-
- * FAQ
- NEWS
- README
- docs/designers.sgml
- docs/getting-started.sgml
- libs/Smarty_Compiler.class.php
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_image.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_radios.php
- libs/plugins/function.html_select_date.php
- libs/plugins/function.html_select_time.php
- libs/plugins/function.html_table.php:
- fix $smarty.const.foo compiling, clean up double quoted strings,
- allow full dollar var syntax in quotes again
-
-2003-02-27 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- docs/programmers.sgml
- libs/Smarty_Compiler.class.php:
- update docs, fix smarty var compiling, allow any $smarty.*.$foo syntax,
- add $`foobar` for embedded variables
-
- * libs/plugins/function.html_image.php:
- update functionality
-
-2003-02-26 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- libs/plugins/modifier.nl2br.php:
- add nl2br modifier
-
- * libs/plugins/function.html_image.php:
- add link parameter
-
-2003-02-24 Monte Ohrt <monte@ispi.net>
-
- * libs/Smarty.class.php
- libs/plugins/function.html_image.php:
- fix rename problem in windows, unlink first
-
- * libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_image.php
- libs/plugins/function.html_options.php
- libs/plugins/function.html_radios.php
- libs/plugins/shared.escape_special_chars.php:
- update functions with separate escape_special_chars routine
-
- * NEWS
- libs/plugins/function.html_checkboxes.php
- libs/plugins/function.html_radios.php:
- commit checkboxes, update radios
-
- * NEWS
- libs/Smarty.class.php
- libs/plugins/function.html_image.php:
- fix bug with get_registered_object
-
- * NEWS
- libs/plugins/modifier.cat.php:
- added cat modifier to distribution
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- added << >> <> support to IF statements
-
- * libs/plugins/function.html_radios.php:
- apply patch to initial html_radios function
-
- * NEWS
- libs/Smarty.class.php:
- fix _assign_smarty_interface to not overwrite keys other than 'request'
-
- * NEWS
- libs/plugins/function.html_radios.php:
- added html_radios to distribution
-
- * NEWS
- libs/plugins/modifier.string_format.php:
- fixed arg order of string_format
-
- * NEWS
- libs/Smarty.class.php:
- use tmp file for file writes, avoid race condition
-
- * NEWS
- libs/Smarty_Compiler.class.php:
- add $smarty.config.foo var, handle embedded smarty var correctly
-
- * NEWS
- libs/plugins/function.fetch.php:
- silence warnings in fetch plugin
-
-2003-02-21 Monte Ohrt <monte@ispi.net>
-
- * INSTALL:
- update wording
-
- * INSTALL:
- update install instructions
-
- * AUTHORS
- BUGS
- CREDITS
- QUICKSTART
- README
- RESOURCES
- TESTIMONIALS:
- remove some files already in docs or elsewhere
-
- * demo/index.php:
- add templates_c to repository
-
- * index.php:
- move demo files to demo directory
-
- * Config_File.class.php
- Smarty.class.php
- Smarty_Compiler.class.php
- debug.tpl:
- moved lib files under libs directory
-
-2003-02-20 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php:
- add get_config_vars() method, update get_template_vars() functionality
-
- * NEWS
- Smarty.class.php:
- fix minor logic in _fetch_template_info()
-
- * NEWS
- Smarty.class.php:
- support merging appended vars
-
- * NEWS
- Smarty.class.php:
- fix cache groups behavior with compile_id set
-
-2003-02-19 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- back out third parameter, extend functionality of append
-
- * NEWS
- Smarty_Compiler.class.php:
- update imbedded vars, allow special $smarty vars
-
- * plugins/function.html_table.php:
- add plugin html_table
-
- * NEWS
- Smarty.class.php:
- support appending key=>val pairs
-
- * NEWS
- Smarty_Compiler.class.php:
- change embedded variable logic to only recognize $foo and $foo[0][bar]
- syntax
-
- * NEWS
- Smarty_Compiler.class.php:
- allow null as function attribute value
-
-2003-02-18 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- support foo->bar[index] syntax
-
- * Smarty_Compiler.class.php:
- allow $foo->bar[0] syntax
-
-2003-02-17 Monte Ohrt <monte@ispi.net>
-
- * plugins/modifier.escape.php:
- fix syntax error from previous commit
-
- * NEWS
- Smarty.class.php:
- add error msgs to get_registered_object
-
- * Smarty.class.php:
- add function for getting reference to registered object
-
- * Smarty_Compiler.class.php:
- back out patches for object and objref calls on $smarty var
-
- * NEWS
- Smarty_Compiler.class.php:
- treat unrecognized param attribute syntax as a string
-
- * NEWS
- Smarty_Compiler.class.php:
- support $smarty.const.$foo syntax
-
- * NEWS
- debug.tpl
- plugins/modifier.count_words.php
- plugins/modifier.escape.php:
- fix E_NOTICE messages
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- add @ and === to if tokens, few param cleanups
-
-2003-02-16 Greg Beaver <greg@chiaraquartet.net>
-
- * ChangeLog
- Smarty.class.php
- Smarty_Compiler.class.php:
- many more phpdoc comment upgrades
-
-2003-02-15 Greg Beaver <cellog@sourceforge.net>
- * Smarty.class.php
- Smarty_Compiler.class.php
- continue cleaning of phpdoc comments. All that is needed is the
- addition of @return tags and perhaps a bit more verbose comments
- and they are finished.
-
-2003-02-14 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php:
- enable config_load error messages
-
- * NEWS
- plugins/function.html_options.php:
- fix html_options to not escape already escaped entities
-
- * NEWS
- Smarty.class.php:
- send Last-Modified header on cache creation, misc tab/spacing cleanup
-
-2003-02-13 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- docs/designers.sgml:
- allow dash in plain text
-
- * NEWS
- Smarty_Compiler.class.php:
- check strict syntax of function attributes
-
-2003-02-12 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty_Compiler.class.php:
- dropped support for modifiers on object parameters,
- added support for objects as modifier parameters
-
- * NEWS
- Smarty_Compiler.class.php
- docs/designers.sgml:
- fix bug with decimal numbers in if statements, misc doc updates
-
-2003-02-11 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_4_2)
- Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php:
- update version numbers
-
-2003-02-10 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty_Compiler.class.php:
- add support for $foo->$bar syntax
-
- * NEWS:
- update NEWS file
-
- * NEWS
- Smarty_Compiler.class.php:
- support full var syntax in quoted text, fix problem with const var access,
- clean up some more regex code, fix object problem with no properties
-
-2003-02-06 Monte Ohrt <monte@ispi.net>
-
- * (Smarty_2_4_1)
- Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php:
- committed 2.4.1 changes
-
- * NEWS
- Smarty_Compiler.class.php:
- ignore case in IF statements
-
-2003-02-05 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty_Compiler.class.php:
- treat undefined constants as null
-
- * NEWS
- Smarty.class.php:
- fix problem with inserts and nested fetches
-
- * Smarty_Compiler.class.php:
- fix "if" regex for math tokens
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- docs/getting-started.sgml:
- added support for extracting params to include_php
-
-2003-02-04 Monte Ohrt <monte@ispi.net>
-
- * RELEASE_NOTES:
- reformat text
-
-2003-02-03 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- update news file
-
-2003-02-03 Greg Beaver <greg@chiaraquartet.net>
-
- * ChangeLog
- Smarty.class.php:
- begin fixing phpdoc comments in Smarty.class.php
-
- * ChangeLog
- Config_File.class.php:
- fixed phpdoc comments
-
-2003-02-03 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- allow $foo->bar[$x].foo syntax
-
- * Smarty_Compiler.class.php
- index.php
- configs/test.conf
- templates/index.tpl:
- fix accidental commit
-
- * index.php
- configs/test.conf
- templates/index.tpl:
- allow $foo->bar[$j].blah type of syntax
-
-2003-02-02 Greg Beaver <cellog@php.net>
-
- * Smarty.class.php
- begin fixing of phpdoc comments
-
- * Config_File.class.php
- fix phpdoc comments, add phpDocumentor docblock templates
-
-2003-02-02 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- docs/html.dsl
- docs/php.dsl:
- fix version number
-
- * (Smarty_2_4_0)
- Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php
- docs/appendixes.sgml
- docs/designers.sgml
- docs/programmers.sgml:
- update Smarty version numbers
-
-2003-01-30 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty_Compiler.class.php
- TODO:
- fix order of php tag comparisons
-
- * NEWS
- Smarty_Compiler.class.php:
- fix known php tag handling problems
-
-2003-01-29 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php:
- change comments to phpdoc style
-
-2003-01-28 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- docs/programmers.sgml:
- make separate var for compiler file
-
- * plugins/function.fetch.php:
- fix error call
-
-2003-01-25 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php:
- add support for restriction to registered methods
-
- * plugins/outputfilter.trimwhitespace.php:
- update with textarea support
-
-2003-01-24 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- fix compiling problem with {foreach} tags
-
- * Smarty.class.php
- Smarty_Compiler.class.php:
- put objects in own array, add object param format support, change
- object syntax from foo.bar to foo->bar
-
-2003-01-23 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- add support for object registration
-
-2003-01-22 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- add file & line number of calling error to error message
-
-2003-01-21 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- put php style object syntax back in
-
-2003-01-20 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- move security settings to fetch function for template_dir
-
- * NEWS
- Smarty.class.php:
- fix debug template and security, add template_dir to secure_dir at runtime
-
-2003-01-17 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- added new object support without new template syntax
-
-2003-01-15 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- fix if statement syntax for negative integers, fix issue with directories
- named '0'
-
-2003-01-08 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- plugins/function.counter.php
- plugins/function.cycle.php
- plugins/function.debug.php
- plugins/function.eval.php
- plugins/function.fetch.php
- plugins/function.html_options.php
- plugins/function.html_select_date.php
- plugins/function.html_select_time.php
- plugins/function.mailto.php
- plugins/function.math.php
- plugins/function.popup.php
- plugins/function.popup_init.php:
- update plugins to return values instead of echo, fix config file cache
- to include global config variables in cache file
-
- * Smarty_Compiler.class.php:
- fix bug with >= tests in if statements, comment out full object support
-
-2003-01-06 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- docs/html.dsl
- plugins/modifier.escape.php:
- add javascript escape parameter to escape modifier
-
-2003-01-02 Monte Ohrt <monte@ispi.net>
-
- * templates/header.tpl:
- move the title into head where it should be
-
-2002-12-24 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- added correct line numbers to smarty syntax error messages
-
- * docs/programmers.sgml:
- update append documentation, make more clear on its function
-
- * Smarty_Compiler.class.php:
- fix modifier matching regexp
-
-2002-12-23 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- support nested function calls in IF statements
-
-2002-12-20 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- few more fixes, spaces around function parameters
-
- * Smarty_Compiler.class.php:
- fix misc syntax issues with {if} tags
-
-2002-12-20 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- fix misc syntax issues with {if} tags
-
-2002-12-19 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- commit updates, passes all smoke tests
-
- * NEWS:
- update NEWS file
-
- * Smarty_Compiler.class.php:
- fixed literal string not in quotes as parameters
-
- * NEWS
- Smarty_Compiler.class.php:
- fix misc syntax issues, add ability to pass modifiers to functions
-
-2002-12-18 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- update NEWS
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- update compiler code, clean up regex, add new syntax features
-
-2002-12-16 Monte Ohrt <monte@ispi.net>
-
- * NEWS:
- update NEWS file
-
- * Smarty_Compiler.class.php:
- commit updates for objects
-
-2002-12-14 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php:
- fix bug with compiling config files with caching on
-
-2002-12-13 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- fix problem with matching single quoted strings
-
- * Smarty_Compiler.class.php:
- update embedded variable logic, get rid of ."" at end of output
-
- * NEWS
- docs/designers.sgml
- plugins/function.html_select_date.php:
- add day_value_format to html_select_date
-
-2002-12-12 Monte Ohrt <monte@ispi.net>
-
- * plugins/modifier.debug_print_var.php:
- fix bug, double escaped values in display
-
- * Smarty.class.php:
- move debug test back into fetch()
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- plugins/outputfilter.trimwhitespace.php:
- assigned vars are no longer in global name space, few debug cleanups
-
-2002-12-11 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.popup.php:
- fix error in newline code
-
- * plugins/function.popup.php:
- fix popup to allow newlines in text data
-
-2002-12-10 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- fix plugin error logic
-
- * docs/designers.sgml
- docs/programmers.sgml:
- edit examples, make more verbose
-
- * NEWS
- plugins/function.html_options.php:
- escape html entities in the option values and output
-
- * NEWS
- plugins/function.html_options.php:
- fixed bug with label of html_options
-
-2002-12-09 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- add support for var_export()
-
- * Config_File.class.php
- Smarty.class.php:
- clean up code, respect force_compile and compile_check flags
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- docs/designers.sgml
- plugins/function.mailto.php:
- add caching feature to config loading, document update, add mailto plugin
-
-2002-12-08 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.fetch.php:
- fix query part of URL
-
-2002-12-05 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- fix typos
-
-2002-11-22 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php:
- patch for warning message
-
-2002-11-21 Monte Ohrt <monte@ispi.net>
-
- * RELEASE_NOTES
- Smarty.class.php:
- get rid of testing for a set value with assign function, just set to
- whatever is passed into the template
-
- * docs/programmers.sgml:
- fix typo
-
-2002-11-19 Monte Ohrt <monte@ispi.net>
-
- * Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php:
- commit changes, ready for 2.3.1 release
-
-2002-11-01 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.html_options.php:
- added label attribute to all option outputs, cover w3c spec.
-
- * NEWS: update NEWS file
-
- * docs/designers.sgml: update docs for optgroup output
-
- * plugins/function.html_options.php:
- make html_options work with optgroup, make func modular and recursive.
-
-2002-10-29 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php: set mtime on compile files so they match source files
-
-2002-10-18 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php: added proper support for open_basedir setting
-
- * docs/designers.sgml: clear up docs on index, iteration and rownum
-
-2002-10-16 Monte Ohrt <monte@ispi.net>
-
- * plugins/modifier.default.php: fix warning message in default modifier
-
-2002-09-25 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- plugins/modifier.strip.php
- NEWS: added strip variable modifier
-
-2002-09-24 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty_Compiler.class.php:
- Fix to be able to use $smarty.x variables as arrays.
-
-2002-09-23 Monte Ohrt <monte@ispi.net>
-
- * Config_File.class.php:
- add support for mac/dos formatted config files (fix newlines)
-
- * docs/programmers.sgml: add optional tags to clear_cache parameters
-
- * docs/designers.sgml:
- fix error with include_php description, add $this to description
-
-2002-09-20 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- docs/getting-started.sgml: fixed errors with example setup docs
-
-2002-09-16 Monte Ohrt <monte@ispi.net>
-
- * plugins/block.textformat.php
- docs/designers.sgml
- NEWS: add textformat block function
-
-2002-09-10 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- add assign attribute to cycle function documentation
-
- * docs/designers.sgml
- docs/programmers.sgml: fix typos
-
-2002-09-09 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.debug.php
- templates/header.tpl:
- fix header in debug template, fix typo in header.tpl example
-
-2002-08-15 mohrt <mohrt@pb1.pair.com>
-
- * docs/programmers.sgml: fix typos
-
-2002-08-08 mohrt <mohrt@pb1.pair.com>
-
- * RELEASE_NOTES
- Smarty.class.php:
- supress warnings from unlink() and is_dir(), let error handler deal with it
-
-2002-08-07 mohrt <mohrt@pb1.pair.com>
-
- * docs/appendixes.sgml
- docs/designers.sgml
- docs/programmers.sgml
- Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php: update files with new version numbers
-
-2002-08-02 mohrt <mohrt@pb1.pair.com>
-
- * NEWS: update NEWS file with credits
-
- * NEWS
- Smarty.class.php: added assign_by_ref() and append_by_ref() functions
-
-2002-08-01 mohrt <mohrt@pb1.pair.com>
-
- * TODO
- NEWS
- Smarty.class.php:
- changed default warning type for plugin errors from E_USER_WARNING to E_USER_ERROR
-
-2002-07-29 mohrt <mohrt@pb1.pair.com>
-
- * plugins/function.html_select_time.php
- docs/designers.sgml
- NEWS: added paramters to html_select_time plugin
-
-2002-07-25 Andrei Zmievski <andrei@pb1.pair.com>
-
- * TODO: *** empty log message ***
-
-2002-07-24 mohrt <mohrt@pb1.pair.com>
-
- * QUICKSTART: update QUICKSTART guide
-
- * NEWS
- debug.tpl
- plugins/modifier.debug_print_var.php:
- update debug console to show objects, fix warning in debug.tpl
-
-2002-07-23 mohrt <mohrt@pb1.pair.com>
-
- * docs/programmers.sgml: fix load_filter examples
-
- * Config_File.class.php
- NEWS: fix error when there are no sections in config file
-
-2002-07-19 mohrt <mohrt@pb1.pair.com>
-
- * docs/getting-started.sgml: fix error in install guide
-
-2002-07-18 mohrt <mohrt@pb1.pair.com>
-
- * Smarty_Compiler.class.php:
- correct the expression match for smarty:nodefaults
-
-2002-07-17 mohrt <mohrt@pb1.pair.com>
-
- * Smarty_Compiler.class.php: fix default modifier to work with config vars
-
- * Smarty_Compiler.class.php: got args to strstr backwards...
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- change default modifiers to array instead of string
-
- * Smarty_Compiler.class.php
- docs/designers.sgml
- Smarty.class.php: add default modifier logic, minor doc updates
-
- * NEWS
- Smarty.class.php
- plugins/function.popup_init.php:
- make popup_init xhtml compliant, minor variable name changes for consistancy
-
-2002-07-16 mohrt <mohrt@pb1.pair.com>
-
- * NEWS: update NEWS file
-
- * plugins/function.debug.php
- Smarty.class.php
- debug.tpl
- NEWS:
- fix problem with filenames on windows, add ability to supply expire time in seconds when clearing cache or compiled files
-
-2002-07-15 mohrt <mohrt@pb1.pair.com>
-
- * Smarty.class.php:
- fixed problem with insert tags when loading function from script attribute
- and caching enabled (Monte)
-
-2002-07-14 mohrt <mohrt@pb1.pair.com>
-
- * NEWS
- Smarty.class.php: fix bug with debug_tpl file path for Windows
-
-2002-07-12 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: fix append function with array/string issue
-
-2002-07-11 Monte Ohrt <monte@ispi.net>
-
- * RELEASE_NOTES: update release notes
-
- * NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php
- Config_File.class.php: update files to 2.2.0 tags, get ready for release
-
-2002-07-09 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php: make debug.tpl work with any delimiter
-
- * NEWS
- Smarty.class.php:
- change tests in append and assign to != '' instead of empty(), which is more accurate
-
-2002-07-08 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml: minor doc update
-
- * Smarty.class.php:
- cast var as an array, simplify and get rid of PHP warning messages
-
-2002-07-03 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: one more N
-
- * Smarty.class.php:
- prepend "N" to filenames to avoid possible OS issues with dir names starting with "-"
-
- * Smarty.class.php: only set $debug_tpl in constructor if empty
-
- * Smarty.class.php
- docs/designers.sgml
- docs/getting-started.sgml
- docs/programmers.sgml:
- make use_sub_dirs go back to crc32 for subdir separation
-
-2002-06-29 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.eval.php: do nothing if $val is empty
-
- * TODO
- plugins/function.eval.php
- plugins/function.popup_init.php:
- add zindex to popup init, fix error message for eval.
-
-2002-06-27 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- only loop through relative paths for PHP include_path, remove $_relative variable
-
- * Smarty_Compiler.class.php: added {$smarty.version} variable
-
-2002-06-26 Monte Ohrt <monte@ispi.net>
-
- * docs/appendixes.sgml
- docs/designers.sgml
- docs/getting-started.sgml
- docs/programmers.sgml
- Smarty.class.php:
- update plugin loading logic, look in SMARTY_DIR, then cwd. If all fail, then retry all with include_path
-
- * templates/header.tpl
- Smarty.class.php: update get_include_path, get _path_array only once
-
- * Smarty.class.php: fix get_include_path function for windows
-
- * Smarty.class.php: update plugin search logic
-
- * Smarty.class.php: only search include_path if relative path
-
- * plugins/function.html_select_date.php
- plugins/function.html_select_time.php
- plugins/modifier.date_format.php
- Smarty_Compiler.class.php
- NEWS
- Smarty.class.php: allow plugins_dir to be an array of directories
-
-2002-06-25 Monte Ohrt <monte@ispi.net>
-
- * docs/programmers.sgml
- docs/getting-started.sgml: update installation docs
-
- * debug.tpl
- docs/getting-started.sgml
- templates/debug.tpl
- NEWS
- Smarty.class.php: move debug.tpl to SMARTY_DIR, add to constructor
-
-2002-06-24 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.assign_debug_info.php
- NEWS: fixed warning message in function.assign_debug_info
-
- * Smarty.class.php: update include_path fixes
-
- * NEWS:
- fixed $template_dir, $compile_dir, $cache_dir, $config_dir to respect include_path
-
-2002-06-23 Monte Ohrt <monte@ispi.net>
-
- * plugins/shared.make_timestamp.php:
- update timestamp plugin to work when passed a timestamp
-
-2002-06-19 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update NEWS file
-
- * plugins/modifier.date_format.php
- docs/designers.sgml:
- update date_format, allow optional 2nd paramater as default date if passed date is empty. update docs.
-
- * plugins/modifier.date_format.php:
- fix date_format modifier, return nothing if given empty string
-
-2002-06-18 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- plugins/function.cycle.php:
- gave $reset a default value in cycle function
-
- * plugins/function.html_select_date.php
- plugins/shared.make_timestamp.php
- NEWS:
- corrected warnings in html_select_time function, made make timestamp always return a timestamp
-
-2002-06-17 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: swapped around cache_id and compile_id order
-
-2002-06-14 Monte Ohrt <monte@ispi.net>
-
- * docs/programmers.sgml
- plugins/function.popup_init.php
- Smarty.class.php:
- change directory delimiter to "^" for cache and compile files
-
-2002-06-13 Andrei Zmievski <andrei@php.net>
-
- * TODO: done.
-
- * Smarty_Compiler.class.php:
- Optimize the calculation of section 'total' property.
-
-2002-06-11 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php:
- added support for subdir exclusion, deletion by full or partial cache_id and compile_id, change file format to urlencoded values instead of crc32
-
-2002-06-07 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: fix bug with last_modified_check code
-
- * NEWS
- Smarty.class.php:
- updated $GLOBALS refererence for HTTP_IF_MODIFIED_SINCE
-
-2002-06-06 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- overlib.js:
- remove overlib.js file from distribution, update plugin and docs
-
-2002-06-05 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- NEWS
- Smarty.class.php: fix 304 Not Modified, don't send content
-
-2002-06-03 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.cycle.php: update version number
-
- * plugins/function.cycle.php
- NEWS:
- fixed cycle function to respect delimiter setting after initial setting
-
- * Smarty.class.php
- NEWS:
- update $GLOBALS references to work properly with track_globals settings
-
- * plugins/function.math.php: fixed bug with call $assign
-
- * docs/appendixes.sgml
- docs/designers.sgml
- plugins/function.html_options.php
- plugins/function.html_select_time.php
- NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- optimized for loops with count() function calls
-
-2002-06-01 Andrei Zmievski <andrei@php.net>
-
- * TODO: *** empty log message ***
-
-2002-05-21 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update NEWS file
-
- * plugins/function.html_select_date.php
- RESOURCES
- docs/designers.sgml
- Config_File.class.php:
- update html_select_date with month_value_format attribute for controlling the format of the month values.
-
-2002-05-17 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty_Compiler.class.php:
- Made it possible to use simple variables inside [] for indexing.
-
-2002-05-16 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- docs/getting-started.sgml
- NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- TESTIMONIALS: add "once" attribute to php_include, update docs
-
-2002-05-09 Andrei Zmievski <andrei@ispi.net>
-
- * NEWS
- TODO: *** empty log message ***
-
-2002-05-07 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.cycle.php: remove \n from cycle function
-
- * docs/designers.sgml
- plugins/function.cycle.php
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php
- NEWS:
- update cycle function to handle array as input, update files to 2.1.1
-
-2002-05-06 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.fetch.php:
- update fetch function with more error checking
-
-2002-05-03 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- plugins/function.counter.php:
- update counter to use name instead of id (id still works though)
-
- * plugins/function.cycle.php
- docs/designers.sgml: rename id to name for cycle function
-
- * plugins/function.cycle.php:
- update cycle function to allow blank values parameter after initialized
-
- * plugins/function.cycle.php: fix syntax error
-
-2002-05-02 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.cycle.php: ugh, another typo
-
- * plugins/function.cycle.php: update comments
-
- * docs/designers.sgml
- plugins/function.cycle.php
- NEWS: added function cycle
-
- * FAQ
- Smarty.class.php: fix register_outputfilter function
-
-2002-05-01 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml
- NEWS
- Smarty.class.php: fixed bug with resource testing and include_path
-
-2002-04-30 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php: update files for 2.1.0 release
-
-2002-04-30 Andrei Zmievski <andrei@ispi.net>
-
- * plugins/function.fetch.php
- docs/programmers.sgml
- Smarty.class.php: Fix.
-
-2002-04-29 Andrei Zmievski <andrei@ispi.net>
-
- * docs/programmers.sgml
- docs/designers.sgml: A whole bunch of docs.
-
-2002-04-26 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- QUICKSTART
- docs/programmers.sgml: update FAQ, QUICKSTART, small doc syntax fix
-
-2002-04-24 Monte Ohrt <monte@ispi.net>
-
- * docs/programmers.sgml
- templates/debug.tpl
- Smarty.class.php: changed doc structure a bit
-
-2002-04-16 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Add register/unregister API for output filters.
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- TODO:
- Changed the way filters are loaded, which now has to be done explicitly,
- either through load_filter() API or by filling in $autoload_filters variable.
- Also renamed internal variable to avoid namespace pollution.
-
-2002-04-15 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php:
- Fixed _get_php_resource() to take include_path into account.
-
-2002-04-15 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml:
- update docs, get modifiers and functions into index for easy access
-
- * docs/programmers.sgml
- NEWS
- Smarty.class.php: update caching documentation
-
-2002-04-15 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty.class.php: Only turn down error notices if $debugging is false.
-
-2002-04-15 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update NEWS file
-
- * plugins/function.html_select_date.php:
- fixed logic so this works right when field_separator = "/"
-
- * plugins/function.html_select_date.php:
- fix regular expression for matching date
-
-2002-04-13 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml: updated html_select_date docs to reflect changes
-
- * NEWS
- plugins/function.html_select_date.php:
- added YYYY-MM-DD support to html_select_date
-
-2002-04-12 Andrei Zmievski <andrei@php.net>
-
- * TESTIMONIALS: New entry.
-
-2002-04-12 Monte Ohrt <monte@ispi.net>
-
- * plugins/modifier.strip_tags.php: back out changes to strip_tags
-
- * docs/programmers.sgml: update docs regarding cache_lifetime
-
- * plugins/modifier.strip_tags.php
- Smarty.class.php:
- update cache_lifetime logic: -1 = never expire, 0 = always expire
-
-2002-04-11 Andrei Zmievski <andrei@php.net>
-
- * BUGS
- FAQ
- INSTALL
- NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- docs/getting-started.sgml:
- Fixed directory separtor issue. Requiring PHP 4.0.6 now.
-
- * NEWS
- Smarty_Compiler.class.php:
- Added ability to use simple variables for array indices or object properties.
-
- * TESTIMONIALS: Another one.
-
- * TESTIMONIALS: Adding one from Mark P.
-
-2002-04-05 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php
- NEWS
- Smarty.class.php: Make it possible to unregister pre/postfilter plugins.
-
-2002-04-05 Monte Ohrt <monte@ispi.net>
-
- * INSTALL: Remove addons file from INSTALL instructions
-
-2002-04-04 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml: update doc error
-
- * docs/designers.sgml
- plugins/modifier.escape.php
- NEWS
- Smarty.class.php: added htmlall attribute to escape modifier
-
-2002-04-03 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Fixed undefined offset warning in {if} tag.
-
- * Smarty.class.php
- NEWS: Added template_exists() API.
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- NEWS:
- - Added $smarty.template variable.
- - Fixed {include_php} tag when dynamic values were used for 'file' attribute.
-
- * Config_File.class.php: Separator setting fix.
-
-2002-03-28 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- README: add digest address
-
- * FAQ
- README
- Smarty.class.php: update mailing list addresses
-
-2002-03-28 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * plugins/function.html_select_date.php
- plugins/function.html_select_time.php
- plugins/modifier.date_format.php:
- Fix for when plugins directory is not the default one.
-
-2002-03-28 Andrei Zmievski <andrei@ispi.net>
-
- * NEWS: *** empty log message ***
-
- * plugins/function.html_select_date.php
- plugins/function.html_select_time.php
- plugins/modifier.date_format.php:
- Fix for when plugins directory is not the default one.
-
-2002-03-27 Monte Ohrt <monte@ispi.net>
-
- * FAQ: update FAQ page
-
-2002-03-26 Andrei Zmievski <andrei@ispi.net>
-
- * CREDITS
- NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- TODO: Block functions changes.
-
- * Config_File.class.php: *** empty log message ***
-
-2002-03-25 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php: Initial implementation of block functions.
-
-2002-03-22 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml: fix documentation error in capture
-
-2002-03-22 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: *** empty log message ***
-
- * Smarty.class.php: Turn off notices.
-
-2002-03-21 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Make _current_file available to prefilters.
-
- * NEWS
- Smarty.class.php:
- Made is possible to assign variables in pre/postfilters.
-
-2002-03-20 Andrei Zmievski <andrei@php.net>
-
- * plugins/function.html_select_date.php: Fixed +/- functionality.
-
- * NEWS: *** empty log message ***
-
-2002-03-20 Monte Ohrt <monte@ispi.net>
-
- * Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.class.php
- Smarty_Compiler.class.php: update version numbers
-
- * plugins/function.html_select_date.php
- plugins/function.html_select_time.php
- plugins/modifier.date_format.php:
- move .make_timestamp.php to shared.make_timestamp.php
-
- * NEWS
- Smarty.class.php
- docs/designers.sgml
- plugins/function.fetch.php
- plugins/function.html_select_date.php:
- update file generation, replace crc32() '-' with 'N'
-
-2002-03-20 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: *** empty log message ***
-
-2002-03-19 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty.class.php
- Smarty_Compiler.class.php:
- Fix plugin behavior for inserts with script attribute.
-
- * NEWS: *** empty log message ***
-
- * Smarty_Compiler.class.php: Fix bug with $smarty.cookies.
-
- * TESTIMONIALS: *** empty log message ***
-
-2002-03-15 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- docs/designers.sgml: update Changelog
-
- * plugins/modifier.indent.php
- plugins/modifier.wordwrap.php: add wordwrap and indent to repository
-
-2002-03-14 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- remove show_info_include and show_info_header functions
-
-2002-03-13 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.fetch.php: update fetch function
-
- * plugins/function.fetch.php: update fetch function with new parameters
-
-2002-03-12 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml: update doc tables
-
- * docs/designers.sgml: update docs columns
-
- * docs/getting-started.sgml
- docs/appendixes.sgml: update docs
-
- * TESTIMONIALS
- docs/appendixes.sgml: update syntax error in docs, add to testimonials
-
-2002-03-04 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- README: update FAQ, README with digest mode info
-
-2002-03-02 Monte Ohrt <monte@ispi.net>
-
- * QUICKSTART: update quickstart
-
- * Smarty.class.php:
- change behavior so cache_lifetime = 0 never expires (instead of always regenerate)
-
-2002-03-01 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml: update doc example
-
-2002-03-01 Andrei Zmievski <andrei@php.net>
-
- * CREDITS
- RELEASE_NOTES
- TODO
- NEWS: *** empty log message ***
-
-2002-03-01 Monte Ohrt <monte@ispi.net>
-
- * docs/appendixes.sgml
- docs/designers.sgml
- docs/getting-started.sgml
- docs/programmers.sgml: update document id tags
-
- * docs.sgml: remove docs.sgml
-
- * RESOURCES
- Smarty.class.php: update resources
-
-2002-02-28 Andrei Zmievski <andrei@php.net>
-
- * TESTIMONIALS
- docs/appendixes.sgml
- docs/designers.sgml
- docs/programmers.sgml: *** empty log message ***
-
-2002-02-27 Andrei Zmievski <andrei@php.net>
-
- * plugins/function.eval.php
- docs/designers.sgml: *** empty log message ***
-
-2002-02-27 Monte Ohrt <monte@ispi.net>
-
- * plugins/function.eval.php: added eval function to plugin dir
-
-2002-02-27 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
-2002-02-27 Monte Ohrt <monte@ispi.net>
-
- * docs/designers.sgml: fix syntax error
-
- * docs/appendixes.sgml
- docs/designers.sgml
- docs/getting-started.sgml
- docs/programmers.sgml: convert technical notes to docbook format
-
- * NEWS
- docs/designers.sgml: added "eval" plugin docs
-
-2002-02-26 Andrei Zmievski <andrei@php.net>
-
- * docs/programmers.sgml
- docs/designers.sgml
- docs/appendixes.sgml
- docs/getting-started.sgml
- docs/html-common.dsl
- docs/.cvsignore: *** empty log message ***
-
- * docs/appendixes.sgml
- docs/common.dsl
- docs/designers.sgml
- docs/getting-started.sgml
- docs/html-common.dsl
- docs/html.dsl
- docs/manual.sgml
- docs/preface.sgml
- docs/programmers.sgml: Split up docs.
-
-2002-02-25 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml: *** empty log message ***
-
-2002-02-22 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: update docs
-
-2002-02-22 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml
- AUTHORS
- NEWS: *** empty log message ***
-
-2002-02-21 Monte Ohrt <monte@ispi.net>
-
- * Config_File.class.php
- NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml: update misc changes
-
-2002-02-21 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml: *** empty log message ***
-
-2002-02-20 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: misc updates
-
-2002-02-20 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml: *** empty log message ***
-
- * Smarty.class.php
- plugins/function.assign.php
- plugins/function.assign_debug_info.php
- plugins/function.counter.php
- plugins/function.fetch.php
- plugins/function.math.php
- plugins/function.popup.php
- plugins/function.popup_init.php
- plugins/modifier.escape.php: Fixup some naming.
-
-2002-02-20 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: update docs
-
-2002-02-20 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml: *** empty log message ***
-
-2002-02-20 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- docs.sgml
- plugins/modifier.escape.php:
- removed global vars from fetch function, added attrs to escape modifier
-
- * docs.sgml: add plugin chapter outline
-
-2002-02-19 Monte Ohrt <monte@ispi.net>
-
- * README
- RELEASE_NOTES
- RESOURCES
- Smarty.class.php
- docs.sgml
- BUGS
- FAQ
- INSTALL
- QUICKSTART: update docs
-
-2002-02-19 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml: Updated resources docs.
-
- * README: *** empty log message ***
-
- * docs.sgml: Updated description of {$smarty} variable.
-
- * BUGS
- FAQ
- INSTALL
- QUICKSTART
- RELEASE_NOTES
- docs.sgml: Remove PEAR notes.
-
-2002-02-18 Andrei Zmievski <andrei@php.net>
-
- * Config_File.class.php
- NEWS: Removed dependency on PEAR.
-
-2002-02-18 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- docs.sgml
- plugins/function.popup_init.php: add src attribute to popup_init
-
-2002-02-15 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php
- plugins/modifier.debug_print_var.php
- NEWS
- Smarty.class.php: Performance enhancements.
-
-2002-02-06 Andrei Zmievski <andrei@php.net>
-
- * plugins/function.html_options.php:
- Fix html_options output to be XHTML compatible.
-
-2002-02-05 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php: Fix up plugin inclusion.
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- TODO
- plugins/function.html_select_date.php
- plugins/function.html_select_time.php
- plugins/modifier.date_format.php: Fix plugin directory access.
-
-2002-02-04 Andrei Zmievski <andrei@php.net>
-
- * .cvsignore
- Smarty_Compiler.class.php: *** empty log message ***
-
-2002-01-31 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php
- TODO
- plugins/function.assign.php
- plugins/function.assign_debug_info.php
- plugins/function.counter.php
- plugins/function.fetch.php
- plugins/function.html_options.php
- plugins/function.html_select_date.php
- plugins/function.html_select_time.php
- plugins/function.math.php
- plugins/function.popup.php
- plugins/function.popup_init.php
- plugins/modifier.capitalize.php
- plugins/modifier.count_characters.php
- plugins/modifier.count_paragraphs.php
- plugins/modifier.count_sentences.php
- plugins/modifier.count_words.php
- plugins/modifier.date_format.php
- plugins/modifier.debug_print_var.php
- plugins/modifier.default.php
- plugins/modifier.escape.php
- plugins/modifier.lower.php
- plugins/modifier.regex_replace.php
- plugins/modifier.replace.php
- plugins/modifier.spacify.php
- plugins/modifier.string_format.php
- plugins/modifier.strip_tags.php
- plugins/modifier.truncate.php
- plugins/modifier.upper.php
- plugins/shared.make_timestamp.php
- templates/index.tpl
- AUTHORS
- CREDITS
- Config_File.class.php
- README: Implemented plugin architecture.
-
- * NEWS: *** empty log message ***
-
-2002-01-30 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- docs.sgml: added modifiers wordwrap and indent
-
-2002-01-28 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- docs.sgml:
- add support for is-modified-since headers, adjust a doc example
-
-2002-01-24 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: cleanup formatting
-
- * NEWS
- Smarty.class.php
- docs.sgml: update ChangeLog, remove insert_tag_check parameter
-
-2002-01-24 Andrei Zmievski <andrei@php.net>
-
- * plugins/standard.plugin.php: *** empty log message ***
-
-2002-01-24 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: fix syntax error
-
- * Smarty.class.php: removed unneccesary test from fetch()
-
-2002-01-23 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php: update overlib fixes
-
- * NEWS: update changelog
-
- * FAQ
- NEWS
- RESOURCES
- Smarty.addons.php: updated overlib fixes
-
-2001-12-31 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: Fixed compile_id problem.
-
-2001-12-28 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- fixed problem with using assigned var with include_php filepath
-
-2001-12-21 Monte Ohrt <monte@ispi.net>
-
- * RESOURCES: update RESOURCES
-
-2001-12-20 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- README: update FAQ
-
-2001-12-18 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- docs.sgml
- Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php: update version numbers
-
-2001-12-18 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: Fixed clear_cache().
-
-2001-12-14 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.addons.php:
- fixed bug in smarty_make_timestamp introduced in PHP 4.1.0
-
-2001-12-13 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php
- docs.sgml: update default function args, fix cached insert debug timing
-
-2001-12-12 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: fix syntax error in documentation
-
- * Smarty.class.php: update default template handling functionality
-
-2001-12-11 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php: update file fetching logic
-
-2001-12-11 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: Added 'script' attribute to {insert..}.
-
-2001-12-10 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php: added default template function handler
-
- * Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php: update version numbers in files to 1.5.1
-
-2001-12-10 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: Removed error message from the _read_file() method.
-
- * Smarty.class.php: Fix check for compile and cache IDs.
-
-2001-12-06 Monte Ohrt <monte@ispi.net>
-
- * QUICKSTART: fix spelling error in QUICKSTART
-
- * docs.sgml: fixed spelling errors in documenation
-
- * Smarty_Compiler.class.php
- docs.sgml
- Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php: commit 1.5.0 release
-
- * RESOURCES
- docs.sgml: added RESOURCES file
-
-2001-12-05 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Refactor.
-
-2001-12-05 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty_Compiler.class.php
- docs.sgml: added assign to include and php_include
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml: *** empty log message ***
-
-2001-12-04 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty_Compiler.class.php: Formatting.
-
-2001-12-04 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- NEWS
- Smarty.class.php: update ChangeLog
-
-2001-12-04 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: Formatting.
-
-2001-12-04 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: removed SMARTY_DIR setting in constructor
-
- * Smarty.class.php: fix Smarty.class.php indention error
-
- * Smarty.class.php: update trusted logic
-
-2001-12-03 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php:
- fix up is_secure, is_trusted, make _parse_tpl_path function
-
- * Smarty.class.php: fix problem with testing SMARTY_DIR as empty
-
- * NEWS
- docs.sgml: update documentation, change log
-
- * Smarty.class.php:
- update constructor to check for SMARTY_DIR before assigning
-
-2001-12-03 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: *** empty log message ***
-
-2001-12-03 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- INSTALL
- RELEASE_NOTES: update a few files
-
- * NEWS
- QUICKSTART
- Smarty.class.php
- docs.sgml: added trusted_dir functionality, cleaned up secure_dir logic
-
-2001-12-03 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * NEWS
- Smarty.class.php: - Introduced $compile_id class variable.
- - Fixed a situation where if $cache_id and $compile_id were both null
- they were passed to auto functions as empty string instead of null.
-
-2001-11-30 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php:
- change variable names in fetch() fuction to smarty_* to avoid namespace conflicts
-
- * NEWS
- Smarty.class.php: fixed bug in _rm_auto with catenated null values
-
-2001-11-29 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty_Compiler.class.php: Added $smarty.section.* syntax.
-
- * Smarty_Compiler.class.php: Made 'name' attribute optional for {foreach}.
-
-2001-11-29 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- index.php: remove assign "now" in index.tpl
-
-2001-11-29 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php: Fix formatting.
-
-2001-11-28 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.class.php
- docs.sgml:
- removed return statements from _read_cache_file (how did they get in there?)
-
-2001-11-27 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml
- NEWS
- Smarty.addons.php
- Smarty.class.php:
- fixed bugs and added assign attribute to several functions
-
-2001-11-27 Andrei Zmievski <andrei@php.net>
-
- * NEWS: Some rewording.
-
- * Smarty_Compiler.class.php: Fix $smarty.capture access.
-
- * TODO: *** empty log message ***
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- Made {config_load ..} merge globals from each config file only once per scope.
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php: - Added {foreach ...}.
- - Made certain $smarty.* references handled at compilation time.
-
-2001-11-26 Monte Ohrt <monte@ispi.net>
-
- * Config_File.class.php
- NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml: commit cache handler functionality
-
-2001-11-20 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.addons.php
- Smarty_Compiler.class.php: Various fixes and additions.
-
- * NEWS
- index.php: *** empty log message ***
-
-2001-11-05 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: changed _read_file parameter from $end to $lines
-
- * NEWS
- Smarty.class.php: fixed is_cache, make cache reading more efficient
-
-2001-11-02 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- NEWS: update FAQ with mailing list Reply-To header FAQ
-
- * NEWS
- Smarty.class.php
- index.php: supress fopen errors, return false if cache file won't load
-
-2001-11-01 Monte Ohrt <monte@ispi.net>
-
- * QUICKSTART
- docs.sgml
- index.php: update QUICKSTART guide with index key example
-
- * Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml: commit all updates for 1.4.6
-
-2001-11-01 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
-2001-10-30 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php: fix assign function problem with empty value passed
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php
- templates/debug.tpl:
- fixed bug in assign function when passing an empty value
-
-2001-10-26 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php
- Smarty.class.php
- index.php: fix minor typo in debug code
-
-2001-10-26 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Typo.
-
-2001-10-26 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php:
- update debug console output, handle html encoding correctly
-
-2001-10-26 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- templates/debug.tpl: Debug formatting.
-
- * Smarty.class.php: Disable rmdir warning.
-
-2001-10-26 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php
- Smarty.class.php
- templates/debug.tpl: update debugging to expand array variables
-
- * Smarty.class.php
- docs.sgml:
- update docs for fetching only timestamp with custom template source functions
-
- * Smarty.addons.php: fix debug console error
-
-2001-10-26 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml: Typos.
-
- * Smarty.addons.php: Cleanup whitespace.
-
- * Smarty_Compiler.class.php: Clean up whitespace.
-
- * Smarty.class.php: Cleaning up code, formatting mostly.
-
- * NEWS: *** empty log message ***
-
-2001-10-25 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- docs.sgml: update documentation to current version
-
- * NEWS
- Smarty.addons.php:
- updated fetch to give proper warning when fetching unreadable or nonexistant files
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- fixed problem with newline at the end of compiled templates
-
- * NEWS
- Smarty.class.php: recompile cache if config file gets modified too.
-
- * NEWS
- Smarty.class.php:
- added feature to regenerate cache if compile_check is enabled and an
- involved template is modified
-
-2001-10-23 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: fix indent for insert tags in debug console
-
- * templates/debug.tpl: update debug.tpl file format
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- templates/debug.tpl:
- update execution time debugging, move into include list
-
-2001-10-10 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php:
- fixed up execution time output in debug console
-
-2001-10-09 Andrei Zmievski <andrei@php.net>
-
- * Config_File.class.php
- NEWS
- Smarty.class.php
- TODO: Added support for hidden config vars.
-
-2001-10-04 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- templates/debug.tpl: added execution times to debug console
-
-2001-10-02 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Add space.
-
-2001-10-01 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Fix reference to compile_id.
-
-2001-09-28 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php: Added postfilter functions.
-
-2001-09-26 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- docs.sgml: Rename to clear_compiled_tpl().
-
-2001-09-25 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty_Compiler.class.php:
- Fixed line number reporting when removing comments.
-
-2001-09-20 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- RELEASE_NOTES
- Smarty.addons.php: made html_options output xhtml compatible
-
-2001-09-19 Monte Ohrt <monte@ispi.net>
-
- * Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php
- templates/debug.tpl: updated version numbers
-
-2001-09-16 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- NEWS
- docs.sgml: fix doc error with insert function
-
-2001-09-06 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
-2001-08-31 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update ChangeLog
-
- * overlib.js
- Smarty.addons.php
- Smarty.class.php
- docs.sgml:
- update overlib to 3.50, adjust addon code so that the overlib.js file isn't modified
-
-2001-08-31 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: - compile_id changes
-
- * NEWS
- Smarty.addons.php: - compile_id support
- - new options for html_select_date
-
-2001-08-23 Andrei Zmievski <andrei@php.net>
-
- * TODO: *** empty log message ***
-
-2001-08-10 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php:
- Modified to pass Smarty object as second parameter to insert functions.
- Also moved _smarty_mod_handler() and _smarty_insert_handler() into the class.
-
- * NEWS
- Smarty_Compiler.class.php:
- Passing Smarty as second parameter to prefilter functions.
-
-2001-08-09 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
-2001-08-09 Monte Ohrt <monte@ispi.net>
-
- * templates/index.tpl
- Smarty.class.php: add smarty.now variable to template
-
-2001-08-06 Monte Ohrt <monte@ispi.net>
-
- * templates/index.tpl: change config_load section back to setup
-
-2001-08-06 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php: Optimize a bit.
-
-2001-08-04 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: update capture documentation
-
-2001-08-03 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- NEWS
- Smarty.class.php:
- fix bug with URL controlled debugging, works now (Monte)
-
-2001-08-01 Andrei Zmievski <andrei@php.net>
-
- * Config_File.class.php: *** empty log message ***
-
- * Smarty_Compiler.class.php
- Smarty.class.php: - Fixed some E_NOTICE stuff in compiler.
- - Generalized assign_smarty_interface() a bit.
-
-2001-07-24 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty_Compiler.class.php
- TODO: See ChangeLog for details.
-
-2001-07-20 Andrei Zmievski <andrei@php.net>
-
- * Config_File.class.php: Booleanize case-insensitively.
-
-2001-07-17 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update ChangeLog
-
- * Smarty.class.php
- docs.sgml: put SMARTY_DIR on Config_File require
-
-2001-07-11 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml
- FAQ
- NEWS
- Smarty.class.php:
- updated security to not include insecure docs, only warning
-
-2001-07-10 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Adding 'sizeof' as an allowed {if} function.
-
-2001-07-06 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
-2001-07-06 Monte Ohrt <monte@ispi.net>
-
- * Config_File.class.php
- NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php: update version number to 1.4.4
-
- * NEWS
- Smarty.addons.php
- Smarty_Compiler.class.php
- docs.sgml
- templates/header.tpl
- templates/index.tpl: update documenatation, template examples
-
-2001-07-03 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: Implemented access to request vars via $smarty var.
-
- * NEWS
- Smarty_Compiler.class.php:
- Fixed a bug with parsing function arguments in {if} tags.
-
-2001-06-30 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update ChangeLog
-
-2001-06-29 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php
- Smarty.class.php
- docs.sgml
- overlib.js:
- moved overlib to separate file, added SMARTY_DIR, documented. added much documentation
-
-2001-06-29 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- RELEASE_NOTES
- TODO: *** empty log message ***
-
-2001-06-29 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- docs.sgml
- index.php
- templates/debug.tpl
- templates/header.tpl
- templates/index.tpl: update release notes
-
-2001-06-27 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: *** empty log message ***
-
- * NEWS
- Smarty_Compiler.class.php: Implemented 'step' section attribute.
-
- * Smarty_Compiler.class.php: Negative values of 'max' will mean no max.
-
- * AUTHORS
- NEWS: *** empty log message ***
-
-2001-06-26 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- index.php: Added 'max' and 'start' section attributes.
- Added 'total' and 'iteration' section properties.
-
-2001-06-25 Andrei Zmievski <andrei@php.net>
-
- * Config_File.class.php
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php: Update version numbers.
-
-2001-06-23 Andrei Zmievski <andrei@php.net>
-
- * TODO: *** empty log message ***
-
-2001-06-21 Andrei Zmievski <andrei@php.net>
-
- * Config_File.class.php
- NEWS: Fixed booleanization bug.
-
-2001-06-20 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml:
- update documents to reflect changes to cached content & debugging
-
-2001-06-20 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- Smarty.class.php: Remove debug output for cached and fetched cases.
-
-2001-06-20 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: update include_info to false
-
- * Smarty.class.php
- docs.sgml
- index.php
- templates/footer.tpl:
- moved debug logic into Smarty completely, created flags for it
-
-2001-06-19 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- Smarty.class.php
- templates/debug.tpl: *** empty log message ***
-
- * NEWS
- Smarty.class.php: Remove unneeded debug functions.
-
-2001-06-19 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- docs.sgml
- templates/debug.tpl
- templates/footer.tpl: commit updates, add debug template
-
-2001-06-19 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- TODO:
- Moved config loading code inside main class, the compiled template now
- simply calls that method.
-
-2001-06-15 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- templates/index.tpl: * moved config array into class itself
- * added 'scope' attribute for config_load
-
- * Smarty_Compiler.class.php
- Smarty.addons.php
- Smarty.class.php: Finishing up secure mode.
-
-2001-06-15 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update ChangeLog
-
- * Smarty_Compiler.class.php: cleaned up logic of if statement security
-
- * Smarty_Compiler.class.php: update if logic to cover more situations
-
- * Smarty_Compiler.class.php
- docs.sgml: update if statement security feature
-
-2001-06-14 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- Smarty.class.php: *** empty log message ***
-
- * NEWS
- Smarty_Compiler.class.php:
- Fixed a bug with quoted strings inside if statements.
-
-2001-06-13 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php
- Smarty.class.php: added secure_dir array for multiple secure directories
-
- * Smarty.addons.php: update fetch funtion to respect security setting
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- docs.sgml: update documentation, changelog
-
- * Smarty.addons.php
- Smarty.class.php: moved _extract setting to assign functions
-
- * Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php:
- added assign/unassign custom functions, ability to re-extract tpl_vars
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml
- index.php: commit security features
-
-2001-06-11 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Version variable typo.
-
-2001-06-05 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php:
- Create config object in fetch() or just set the config path if it already
- exists.
-
-2001-06-04 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: *** empty log message ***
-
- * NEWS
- Smarty_Compiler.class.php:
- Fixed a problem with $<number> inside strip tags.
-
-2001-05-31 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Config_File.class.php: Allow empty config_path.
-
-2001-05-29 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- docs.sgml
- NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php: update version numbers
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml: moved version variable to internal variable
-
-2001-05-22 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php:
- Moved $_smarty_sections and $_smarty_conf_obj into Smarty class.
-
-2001-05-18 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update ChangeLog
-
- * FAQ
- QUICKSTART: update FAQ, QUICKSTART for windows include_path setup
-
- * configs/test.conf: added configs directory to cvs
-
-2001-05-18 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Use compiler_class for including the file.
-
-2001-05-18 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: fix typo
-
-2001-05-16 Monte Ohrt <monte@ispi.net>
-
- * README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php: update files to version 1.4.1
-
- * NEWS: update ChangeLog
-
-2001-05-15 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * index.php: forget that!
-
- * NEWS
- Smarty_Compiler.class.php
- index.php: Fixed a few E_NOTICE warnings.
-
-2001-05-09 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- docs.sgml: update dates versions
-
-2001-05-09 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty.class.php:
- Use absolute paths when requiring/including Smart components.
-
- * NEWS: *** empty log message ***
-
- * Smarty.class.php: Use write mode instead of append.
-
-2001-05-02 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty_Compiler.class.php: Fix indexing by section properties.
-
-2001-05-02 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update changelog
-
- * Smarty.class.php: remove period from syntax error
-
-2001-05-02 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Double-quote the attribute values by default.
-
-2001-04-30 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- NEWS: added simple {capture} logic
-
-2001-04-30 Andrei Zmievski <andrei@php.net>
-
- * TODO: *** empty log message ***
-
- * Smarty_Compiler.class.php
- Smarty.class.php: Fix passing config vars to included files.
-
- * Smarty.class.php
- Smarty_Compiler.class.php: Fix inclusion again.
-
-2001-04-30 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- RELEASE_NOTES
- Smarty.class.php
- misc/fix_vars.php
- NEWS: update paths for windows (c:)
-
-2001-04-28 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php: Fix passing variables to included files.
-
- * templates/index.tpl: *** empty log message ***
-
-2001-04-27 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Fix includes.
-
-2001-04-26 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php
- docs.sgml
- Smarty.class.php: Formatting mostly.
-
- * Smarty_Compiler.class.php
- Config_File.class.php: *** empty log message ***
-
-2001-04-26 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- docs.sgml
- FAQ
- NEWS
- QUICKSTART
- RELEASE_NOTES
- Smarty.class.php: update docs with new changes
-
-2001-04-26 Andrei Zmievski <andrei@php.net>
-
- * RELEASE_NOTES: *** empty log message ***
-
- * docs.sgml
- templates/index.tpl
- NEWS
- Smarty_Compiler.class.php: Added ability to reference object properties.
-
-2001-04-25 Andrei Zmievski <andrei@php.net>
-
- * README
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml
- AUTHORS
- Config_File.class.php
- CREDITS
- RELEASE_NOTES
- NEWS: *** empty log message ***
-
- * docs.sgml: Docs on new parameter to custom functions.
-
- * NEWS: *** empty log message ***
-
- * Smarty_Compiler.class.php:
- Changing the way tpl vars are referenced and passing smarty object
- to custom functions.
-
- * RELEASE_NOTES
- docs.sgml: Fixing docs a bit.
-
-2001-04-24 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml: Docs for $compiler_class and compiler functions.
-
- * templates/index.tpl: *** empty log message ***
-
- * Smarty_Compiler.class.php: Remove debugging.
-
-2001-04-24 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: update compiler function docs
-
-2001-04-24 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- templates/index.tpl: Added compiler function support.
-
-2001-04-24 Monte Ohrt <monte@ispi.net>
-
- * RELEASE_NOTES
- Smarty.class.php:
- update notes, change show_info_header to false by default
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml
- CREDITS
- FAQ
- NEWS
- README
- RELEASE_NOTES: update documenation, bug fixes
-
-2001-04-24 Andrei Zmievski <andrei@php.net>
-
- * misc/fix_vars.php: Hopefully fix for sure.
-
-2001-04-23 Monte Ohrt <monte@ispi.net>
-
- * misc/fix_vars.php: uncomment copy/unlink
-
-2001-04-23 Andrei Zmievski <andrei@php.net>
-
- * misc/fix_vars.php: Do it more thoroughly.
-
- * misc/fix_vars.php: check for }
-
-2001-04-22 Andrei Zmievski <andrei@php.net>
-
- * misc/fix_vars.php: Fix variable parsing.
-
-2001-04-20 Monte Ohrt <monte@ispi.net>
-
- * misc/fix_vars.php: fix problem with 4.0.5-dev and preg_replace_callback
-
-2001-04-19 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- docs.sgml
- misc/fix_vars.php
- NEWS
- RELEASE_NOTES
- Smarty.class.php: update notes/documentation
-
- * NEWS
- README
- RELEASE_NOTES
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml: update files for 1.4.0 release
-
-2001-04-16 Andrei Zmievski <andrei@php.net>
-
- * misc/fix_vars.php: Added fix_vars.php script.
-
-2001-04-16 Monte Ohrt <monte@ispi.net>
-
- * QUICKSTART
- RELEASE_NOTES
- docs.sgml
- templates/index.tpl:
- update RELEASE_NOTES & scripts with new section var syntax
-
-2001-04-13 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: * Implement new variable format parser.
- * Optimizing config load a bit.
-
-2001-04-13 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- NEWS
- RELEASE_NOTES
- Smarty.class.php:
- added $check_cached_insert_tags to speed up cached pages if
- {insert ...} is not used (Monte)
-
-2001-04-12 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- RELEASE_NOTES: *** empty log message ***
-
- * Smarty_Compiler.class.php: Remove redundant functions.
-
- * Smarty.class.php: Formatting.
-
-2001-04-12 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: update file: parsing
-
- * Smarty.class.php
- docs.sgml: update documentation
-
-2001-04-12 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- TODO: *** empty log message ***
-
-2001-04-11 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- QUICKSTART
- RELEASE_NOTES: added RELEASE_NOTES file to cvs
-
- * NEWS
- docs.sgml: update ChangeLog, update documentation
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- templates/index.tpl:
- update Smarty to compile at run-time. added ability to get files from
- absolute paths, added work around for LOCK_EX and windows, changed a few
- file permissions to be more secure.
-
-2001-03-29 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.addons.php:
- allow arbitrary date strings instead of just timestamps
-
-2001-03-28 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- docs.sgml
- FAQ
- NEWS
- README
- Smarty.addons.php:
- update version in class, update docs for count_ and new vars
-
- * templates/index.tpl
- docs.sgml: update docs, example template
-
-2001-03-28 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Some variable renaming.
-
-2001-03-23 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php
- NEWS: Fixed nested include infinite repeat bug.
-
-2001-03-23 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: fix version number
-
- * Smarty.class.php
- NEWS: added optional HTML header to output
-
-2001-03-22 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Fixed inclusion of dynamic files.
-
-2001-03-16 Andrei Zmievski <andrei@php.net>
-
- * Smarty_Compiler.class.php: Fixing the config_load scoping.
-
- * Smarty_Compiler.class.php: making config variables global for now.
-
-2001-03-15 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty_Compiler.class.php:
- * Includes are now always done via generated function call to protect
- namespace.
- * config_load now always uses global config object to improve
- performance.
-
-2001-03-13 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: update math documentation with format attribute
-
-2001-03-11 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml
- NEWS
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php: update math function with format attribute
-
-2001-03-10 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php: *** empty log message ***
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php: Added html_select_time custom function.
-
-2001-03-08 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php
- NEWS
- README
- Smarty.addons.php: rename 1.3.1b to 1.3.1pl1
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php: update version numbers, changelog
-
- * Smarty.class.php
- Smarty_Compiler.class.php:
- moved _syntax_error to Smarty_Compiler.class.php
-
- * Smarty.class.php
- docs.sgml:
- missing _syntax_error function recovered. fixed minor syntax in docs
-
-2001-03-07 Monte Ohrt <monte@ispi.net>
-
- * QUICKSTART
- README
- Smarty.addons.php
- Smarty.class.php
- Smarty_Compiler.class.php
- BUGS
- INSTALL
- NEWS: update everything to 1.3.1
-
-2001-03-03 Monte Ohrt <monte@ispi.net>
-
- * Smarty_Compiler.class.php
- Smarty.class.php: fixed bug with cached insert tags
-
-2001-03-02 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- Smarty_Compiler.class.php:
- fix cache fuctions with separated compiled class
-
- * FAQ
- NEWS
- docs.sgml: update changelog
-
-2001-03-02 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty_Compiler.class.php: Added 'first' and 'last' section properties.
-
-2001-03-02 Monte Ohrt <monte@ispi.net>
-
- * TODO: remove compiling separation TODO
-
- * Smarty_Compiler.class.php
- Smarty.addons.php
- Smarty.class.php: update function headers
-
- * templates/index.tpl
- NEWS
- Smarty.class.php
- Smarty_Compiler.class.php
- index.php: split out compiling code for faster execution
-
- * Smarty.class.php: fixed a few warning messages
-
- * Smarty.addons.php
- Smarty.class.php
- docs.sgml
- NEWS: added fetch, unregister mod/fun, updated docs
-
-2001-03-01 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php: added "int" to available list
-
- * docs.sgml
- FAQ
- Smarty.class.php: update FAQ, add math functions & update documetation
-
- * index.php
- Smarty.addons.php
- Smarty.class.php
- docs.sgml: fixed literal tags and other optional delimiters
-
-2001-02-26 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php:
- Added index_prev, index_next section properties and ability to
- index by them.
-
- * NEWS
- Smarty.addons.php
- Smarty.class.php: Reverting the plugins patch - needs more thought.
-
- * Smarty.class.php: Fixing plugin loading.
-
-2001-02-23 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- Smarty.class.php
- plugins/standard.plugin.php
- NEWS: Added plugin functionality.
-
-2001-02-22 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml
- templates/index.tpl
- NEWS
- README
- Smarty.class.php: fixed issue with php tags executed in literal blocks
-
-2001-02-21 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update changelog for LGPL change
-
- * Smarty.class.php
- docs.sgml
- README
- Smarty.addons.php: updated version numbers to 1.3.0
-
- * NEWS
- templates/index.tpl: update changelog, rearrange index.tpl file
-
-2001-02-21 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: *** empty log message ***
-
-2001-02-21 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: update parameters for is_cached and fetch
-
-2001-02-21 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: *** empty log message ***
-
-2001-02-21 Monte Ohrt <monte@ispi.net>
-
- * NEWS
- Smarty.addons.php
- docs.sgml: update docs, remove header function from addons
-
-2001-02-20 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- NEWS: update changelog
-
- * TODO: update todo
-
- * TODO: update todo list
-
- * Smarty.class.php: update php tag handling logic
-
-2001-02-19 Monte Ohrt <monte@ispi.net>
-
- * index.php
- Config_File.class.php
- FAQ
- Smarty.class.php
- docs.sgml: fixed <?php tag at beginning of files, updated docs
-
-2001-02-19 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php: *** empty log message ***
-
-2001-02-13 Andrei Zmievski <andrei@php.net>
-
- * TODO: *** empty log message ***
-
-2001-02-12 Andrei Zmievski <andrei@php.net>
-
- * templates/index.tpl
- Smarty.class.php: *** empty log message ***
-
-2001-02-10 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: remove unneeded preg_match
-
- * Smarty.class.php: remove comment
-
- * Smarty.class.php: updated php escape to handle <script language="php">
-
- * NEWS
- Smarty.class.php: fix php tag escapement logic
-
- * NEWS: commit changelog
-
- * docs.sgml: update header docs
-
- * docs.sgml
- Smarty.addons.php
- Smarty.class.php: added header custom function
-
-2001-02-09 Monte Ohrt <monte@ispi.net>
-
- * index.php
- templates/header.tpl
- templates/index.tpl
- INSTALL
- QUICKSTART
- docs.sgml: update documentation, add examples to test script.
-
-2001-02-08 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: *** empty log message ***
-
-2001-02-08 Monte Ohrt <monte@ispi.net>
-
- * COPYING.lib: added COPYING.lib
-
- * COPYING
- Config_File.class.php
- Smarty.addons.php
- Smarty.class.php
- docs.sgml: changed license to LGPL for commercial use
-
- * docs.sgml
- Smarty.class.php: fix clear_assign syntax error
-
-2001-02-07 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: added ability to pass array to clear_assign
-
- * index.php
- templates/index.tpl
- docs.sgml:
- update documentation, remove tests from index file and template
-
-2001-02-07 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php: Adding file locking.
-
- * templates/index.tpl
- Smarty.addons.php
- Smarty.class.php
- index.php: More cache work.
-
-2001-02-06 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml
- Smarty.class.php:
- change register_ function names, update documents with tables
-
-2001-02-06 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- templates/index.tpl: Reworking and optimizing the cache system.
-
- * Smarty.class.php: Restoring ?> in patterns.
-
-2001-02-05 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- docs.sgml: update cache directory creation logic
-
-2001-02-05 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Removing once-only subpattern for now..
-
- * Smarty.class.php: Fix modifier arg parsing.
-
-2001-02-02 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- Smarty.class.php
- templates/index.tpl: See changelog.
-
-2001-02-01 Andrei Zmievski <andrei@php.net>
-
- * README: *** empty log message ***
-
- * Smarty.class.php: Use 'echo' instead of 'print'.
-
- * Smarty.addons.php: *** empty log message ***
-
-2001-02-01 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: rearranged variables at top of script
-
-2001-02-01 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Retabbing.
-
- * templates/index.tpl
- Smarty.class.php
- index.php: *** empty log message ***
-
-2001-02-01 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: update caching logic
-
- * Smarty.class.php: fixed clear_all_cache bugs
-
- * Smarty.class.php: fix .cache check
-
- * docs.sgml
- FAQ
- Smarty.class.php: update .che to .cache
-
- * FAQ
- Smarty.class.php
- docs.sgml: updated docs for caching, added clear_all_cache() directive
-
-2001-01-31 Monte Ohrt <monte@ispi.net>
-
- * index.php
- templates/index.tpl
- docs.sgml: upated docs for date_format and html_options
-
-2001-01-31 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty.addons.php
- index.php: Added ability to pass 'options' attribute to html_options.
-
- * Smarty.addons.php
- Smarty.class.php
- docs.sgml
- index.php
- templates/index.tpl
- Config_File.class.php
- NEWS
- README: Reworking, simplifying, and speeding up cache implementation.
- Fixing the infelicity where you couldn't have '|' and ':' inside
- quoted modifier arguments.
-
-2001-01-31 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php
- index.php
- templates/index.tpl: removed DEBUG lines
-
-2001-01-30 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: changed default expire to 3600
-
- * Config_File.class.php
- NEWS
- README
- Smarty.addons.php
- Smarty.class.php: updated version numbers
-
- * docs.sgml
- NEWS
- Smarty.class.php:
- added caching, force compile, force cache, misc performance updates
-
-2001-01-30 Andrei Zmievski <andrei@php.net>
-
- * NEWS: *** empty log message ***
-
- * Smarty.class.php
- templates/index.tpl: Remove debug message.
-
- * Smarty.class.php
- templates/index.tpl: Fixing the compile directory mayhem...
-
- * Smarty.class.php:
- Fix problem with {strip} around {section} and {include}
-
- * Smarty.addons.php: *** empty log message ***
-
-2001-01-29 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- NEWS
- README
- Smarty.class.php: fixed PHP_VERSION check, misc doc updates
-
- * index.php
- Config_File.class.php
- NEWS
- QUICKSTART
- README
- Smarty.addons.php
- Smarty.class.php
- docs.sgml: updated for 1.2.1 compile_dir changes, misc doc updates
-
-2001-01-26 Monte Ohrt <monte@ispi.net>
-
- * BUGS
- README: update BUGS and README files
-
- * FAQ: updated FAQ
-
- * Config_File.class.php
- FAQ
- NEWS
- README
- Smarty.addons.php
- docs.sgml
- templates/index.tpl
- AUTHORS: update again
-
-2001-01-26 Andrei Zmievski <andrei@php.net>
-
- * docs.sgml
- NEWS
- README
- Smarty.class.php
- templates/index.tpl: *** empty log message ***
-
- * Smarty.class.php
- index.php
- templates/index.tpl: Added ability to index by key.
-
-2001-01-25 Monte Ohrt <monte@ispi.net>
-
- * NEWS: update changelog
-
- * README
- Smarty.addons.php
- Smarty.class.php
- docs.sgml
- AUTHORS: updated versions to 1.1.0
-
- * docs.sgml
- templates/index.tpl
- Config_File.class.php
- Smarty.addons.php
- Smarty.class.php: update copyright notice
-
- * Config_File.class.php
- Smarty.addons.php
- Smarty.class.php
- docs.sgml: added misc info
-
-2001-01-24 Monte Ohrt <monte@ispi.net>
-
- * Smarty.addons.php
- index.php
- templates/index.tpl
- Config_File.class.php: initial commit
-
-2001-01-23 Monte Ohrt <monte@ispi.net>
-
- * docs.sgml: fix typo
-
-2001-01-22 Monte Ohrt <monte@ispi.net>
-
- * doc.sgm
- docs.sgml: updated docs, renamed file
-
- * FAQ: updated FAQ
-
- * NEWS
- README: updated Changelog and Readme
-
- * doc.sgm: updated doc.sgm error
-
- * AUTHORS
- COPYING
- INSTALL
- NEWS
- QUICKSTART: misc doc changes, added AUTHORS, COPYING
-
-2001-01-22 Andrei Zmievski <andrei@php.net>
-
- * NEWS
- templates/index.tpl: *** empty log message ***
-
- * Smarty.class.php
- templates/index.tpl:
- Fixed bug that wouldn't let you do specify non-array values for 'loop'
- attribute.
-
-2001-01-22 Monte Ohrt <monte@ispi.net>
-
- * QUICKSTART: updated QUICKSTART
-
- * BUGS
- FAQ
- INSTALL
- README
- doc.sgm: added BUGS and INSTALL, updated docs, FAQ, README
-
-2001-01-21 Monte Ohrt <monte@ispi.net>
-
- * FAQ
- doc.sgm: updates to FAQ and docs
-
-2001-01-19 Monte Ohrt <monte@ispi.net>
-
- * FAQ: initial commit of FAQ
-
- * QUICKSTART
- README
- doc.sgm
- index.php:
- updated README, doc.sgm with preg_replace() parameter issue. also removed "./" from index.php file
-
- * NEWS: initial commit of changelog
-
- * doc.sgm
- QUICKSTART: update quickstart text
-
-2001-01-19 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Fix the compiled template check.
-
-2001-01-18 Andrei Zmievski <andrei@php.net>
-
- * doc.sgm: *** empty log message ***
-
-2001-01-18 Monte Ohrt <monte@ispi.net>
-
- * index.php
- templates/index.tpl
- QUICKSTART
- Smarty.addons.php
- Smarty.class.php
- doc.sgm: update changes
-
-2001-01-18 Andrei Zmievski <andrei@php.net>
-
- * QUICKSTART
- Smarty.addons.php: *** empty log message ***
-
-2001-01-18 Monte Ohrt <monte@ispi.net>
-
- * QUICKSTART
- doc.sgm: add QUICKSTART, update docs for default modifier
-
- * Smarty.addons.php
- Smarty.class.php: added default modifier
-
- * README
- Smarty.addons.php
- Smarty.class.php
- doc.sgm
- templates/index.tpl: added dislaimers
-
-2001-01-18 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: *** empty log message ***
-
-2001-01-16 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- templates/index.tpl: Implement 'div by'.
-
-2001-01-12 Monte Ohrt <monte@ispi.net>
-
- * doc.sgm: update docs
-
- * doc.sgm: doc changes
-
- * doc.sgm: update docs
-
-2001-01-12 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- doc.sgm: *** empty log message ***
-
- * Smarty.class.php: Fix template traversal.
-
-2001-01-11 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: *** empty log message ***
-
-2001-01-09 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- Smarty.class.php: *** empty log message ***
-
-2001-01-09 Monte Ohrt <monte@ispi.net>
-
- * doc.sgm: update manual
-
-2001-01-05 Monte Ohrt <monte@ispi.net>
-
- * doc.sgm
- Smarty.addons.php: commit changes
-
-2001-01-04 Monte Ohrt <monte@ispi.net>
-
- * doc.sgm
- templates/index.tpl
- Smarty.class.php: update changes
-
- * index.php
- Smarty.addons.php
- doc.sgm: add documentation
-
-2001-01-02 Monte Ohrt <monte@ispi.net>
-
- * index.php
- templates/index.tpl
- Smarty.addons.php
- Smarty.class.php: prepend insert_ to insert tag functions
-
- * Smarty.class.php
- index.php
- templates/index.tpl: remove caching logic
-
- * README
- Smarty.class.php
- index.php
- templates/index.tpl: update changes
-
-2000-12-27 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- templates/header.tpl
- templates/index.tpl
- Smarty.addons.php: *** empty log message ***
-
-2000-12-21 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php: Fix access to template variables.
-
- * Smarty.class.php
- templates/header.tpl:
- Added support for passing variables to included files.
-
-2000-12-20 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php:
- Added support for inserting results of function processing a template.
-
-2000-12-18 Monte Ohrt <monte@ispi.net>
-
- * Smarty.class.php: added string_format function
-
- * Smarty.addons.php: update format to string_format
-
- * README
- Smarty.addons.php
- Smarty.class.php: added format addon function
-
-2000-12-13 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- Smarty.class.php: Fix sectionelse.
-
-2000-12-07 Andrei Zmievski <andrei@php.net>
-
- * Smarty.addons.php
- Smarty.class.php
- templates/index.tpl: *** empty log message ***
-
-2000-12-04 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- templates/index.tpl
- Smarty.addons.php: *** empty log message ***
-
-2000-11-27 Andrei Zmievski <andrei@php.net>
-
- * templates/index.tpl
- Smarty.class.php: *** empty log message ***
-
-2000-11-22 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- templates/index.tpl: *** empty log message ***
-
-2000-11-21 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- templates/index.tpl
- Smarty.addons.php: *** empty log message ***
-
-2000-11-20 Andrei Zmievski <andrei@php.net>
-
- * templates/index.tpl
- Smarty.class.php
- Smarty.addons.php
- index.php: *** empty log message ***
-
- * Smarty.class.php
- index.php
- templates/index.tpl: Made sections work mostly.
-
-2000-11-19 Andrei Zmievski <andrei@php.net>
-
- * index.php
- templates/index.tpl: *** empty log message ***
-
-2000-11-17 Andrei Zmievski <andrei@php.net>
-
- * Smarty.class.php
- Smarty.addons.php: *** empty log message ***
-
-2000-11-15 Monte Ohrt <monte@ispi.net>
-
- * index.php
- templates/footer.tpl
- templates/header.tpl
- templates/index.tpl: added template files to cvs dir
-
- * README
- Smarty.class.php: commit changes
-
-2000-08-08 Monte Ohrt <monte@ispi.net>
-
- * README
- Smarty.class.php: update include path bug
-
- * README: add README file
-
- * Smarty.class.php: New file.
-
- * Smarty.class.php: initial import
-
+++ /dev/null
-QUESTION INDEX
---------------
-
-GENERAL
-
-Q: What is Smarty?
-Q: What's the difference between Smarty and other template engines?
-Q: What do you mean "Compiled PHP Scripts" ?
-Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
-Q: Why does smarty have a built in cache? Wouldn't it be better to handle this
- in a separate class?
-Q: Is Smarty faster than <insert other PHP template engine>?
-Q: How can I be sure to get the best performance from Smarty?
-Q: Do you have a mailing list?
-Q: Can you change the mailing list so reply-to sends to the list and not the
- user?
-
-TROUBLESHOOTING
-
-Q: Smarty doesn't work.
-Q: I get the following error when running Smarty:
- Warning: Smarty error: problem creating directory "templates_c/239/239105369"
- in /path/to/Smarty.class.php on line 542
-Q: I get the following error when running Smarty:
- Warning: Wrong parameter count for preg_replace() in
- Smarty.class.php on line 371
-Q: I get this error when passing variables to {include}:
- Fatal error: Call to undefined function: get_defined_vars() in
- /path/to/Smarty/templates_c/index.tpl.php on line 8
-Q: I get PHP errors in my {if} tag logic.
-Q: I'm changing my php code and/or templates, and my results are not getting
- updated.
-Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
- also zero length.
-Q: The template goes into an infinite loop when I include included templates
- that pass local variables
-Q: Javascript is causing Smarty errors in my templates.
-Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
-
-MISC
-
-Q: Can I use Macromedia's Dreamweaver to edit my templates?
-Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
- HREF link. How do I get around this?
-
-HOWTO
-
-Q: How do I generate different cache files per template based on arguments
- passed to the page?
-Q: How do I pass a template variable as a parameter? {function param={$varname}}
- does not work.
-Q: How do I include cached template(s) within a non-cached template?
-
-
-GENERAL
--------
-
-Q: What is Smarty?
-A: Smarty is a template engine for PHP... but be aware this isn't just another
- PHP template engine. It's much more than that.
-
-Q: What's the difference between Smarty and other template engines?
-A: Most other template engines for PHP provide basic variable substitution and
- dynamic block functionality. Smarty takes a step further to be a "smart"
- template engine, adding features such as configuration files, template
- functions, variable modifiers (see the docs!) and making all of this
- functionality as easy as possible to use for both programmers and template
- designers. Smarty also compiles the templates into PHP scripts, eliminating
- the need to parse the templates on every invocation, making Smarty extremely
- scalable and manageable for large application needs.
-
-Q: What do you mean "Compiled PHP Scripts" ?
-A: Smarty reads the template files and creates PHP scripts from them. Once
- these PHP scripts are created, Smarty executes these, never having to parse
- the template files again. If you change a template file, Smarty will
- recreate the PHP script for it. All this is done automatically by Smarty.
- Template designers never need to mess with the generated PHP scripts or even
- know of their existance. (NOTE: you can turn off this compile checking step
- in Smarty for increased performance.)
-
-Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
-A: You certainly can, and we highly recommend it! What PHPA does is caches
- compiled bytecode of your PHP scripts in shared memory or in a file. This
- speeds up server response and saves the compilation step. Smarty creates PHP
- scripts, which PHPA will cache nicely. Now, Smarty's built-in cache is
- something completely different. It caches the _output_ of the template
- contents. For example, if you have a template that requires several database
- queries, Smarty can cache this output, saving the need to call the database
- every time. Smarty and PHPA (or Zend Cache) complement each other nicely. If
- performance is of the utmost importance, we would recommend using one of
- these with any PHP application, using Smarty or not. As you can see in the
- benchmarks, Smartys performance _really_ excels in combination with a PHP
- accelerator.
-
-Q: Why does Smarty have a built in cache? Wouldn't it be better to handle this
- in a separate class?
-A: Smarty's caching functionality is tightly integrated with the template
- engine, making it quite a bit more flexible than a simple caching wrapper.
- For instance, you can cache select portions of a template page. Let's say
- you have a polling box on your site. With Smarty, you can leave the poll
- dynamic and cache the rest of the page. You can also pass templates
- multiple cache ids, meaning that a template can have several caches
- depending on URL, cookies, etc.
-
-Q: Is Smarty faster than <insert other PHP template engine>?
-A: See the benchmark page for some performance comparisons. Smarty's approach
- to templates is a bit different from some languages: it compiles templates
- into PHP scripts instead of parsing them on each invocation. This usually
- results in great performance gains, especially with complex templates.
- Coupled with the built-in caching of Smarty templates, the performance is
- outstanding.
-
-Q: How can I be sure to get the best performance from Smarty?
-A: Be sure you set $compile_check=false once your templates are initially
- compiled. This will skip the unneeded step of testing if the template has
- changed since it was last compiled. If you have complex pages that don't
- change too often, turn on the caching engine and adjust your application so
- it doesn't do unnecessary work (like db calls) if a cached page is
- available. See the documentation for examples.
-
-Q: Do you have a mailing list?
-A: We have a few mailing lists. "general" for you to share your ideas or ask
- questions, "dev" for those interested in the development efforts of Smarty,
- and "cvs" for those that would like to track the updates made in the cvs
- repository.
-
- send a blank e-mail message to:
- smarty-general-subscribe@lists.php.net (subscribe to the general list)
- smarty-general-unsubscribe@lists.php.net (unsubscribe from the general list)
- smarty-general-digest-subscribe@lists.php.net (subscribe to digest)
- smarty-general-digest-unsubscribe@lists.php.net (unsubscribe from digest)
- smarty-dev-subscribe@lists.php.net (subscribe to the dev list)
- smarty-dev-unsubscribe@lists.php.net (unsubscribe from the dev list)
- smarty-cvs-subscribe@lists.php.net (subscribe to the cvs list)
- smarty-cvs-unsubscribe@lists.php.net (unsubscribe from the cvs list)
- You can also browse the mailing list archives at
- http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
-
-
-
-Q: Can you change the mailing list so Reply-To sends to the list and not the
- user?
-A: Yes we could, but no we won't. Use "Reply-All" in your e-mail client to send
- to the list. http://www.unicom.com/pw/reply-to-harmful.html
-
-TROUBLESHOOTING
----------------
-
-Q: Smarty doesn't work.
-A: You must be using PHP 4.0.6 or later if you use any version of Smarty
- past 2.0.1. Read the BUGS file for more info.
-
-Q: I get the following error when running Smarty:
- Warning: Smarty error: problem creating directory "templates_c/239/239105369"
- in /path/to/Smarty.class.php on line 542
-A: Your web server user does not have permission to write to the templates_c
- directory, or is unable to create the templates_c directory. Be sure the
- templates_c directory exists in the location defined in Smarty.class.php,
- and the web server user can write to it. If you do not know the web server
- user, chmod 777 the templates_c directory, reload the page, then check the
- file ownership of the files created in templates_c. Or, you can check the
- httpd.conf (usually in /usr/local/apache/conf) file for this setting:
- User nobody
- Group nobody
-
-Q: I get the following error when running Smarty: Warning: Wrong parameter
- count for preg_replace() in Smarty.class.php on line 371
-A: preg_replace had a parameter added in PHP 4.0.2 that Smarty
- requires. Upgrade to at least 4.0.6 to fix all known PHP issues with
- Smarty.
-
-Q: I get this error when passing variables to {include}:
- Fatal error: Call to undefined function: get_defined_vars() in
- /path/to/Smarty/templates_c/index.tpl.php on line 8
-A: get_defined_vars() was added to PHP 4.0.4. If you plan on passing
- variables to included templates, you will need PHP 4.0.6 or later.
-
-Q: I get PHP errors in my {if} tag logic.
-A: All conditional qualifiers must be separated by spaces. This syntax will not
- work: {if $name=="Wilma"} You must instead do this: {if $name == "Wilma"}.
- The reason for this is syntax ambiguity. Both "==" and "eq" are equivalent
- in the template parser, so something like {if $nameeq"Wilma"} wouldn't be
- parsable by the tokenizer.
-
-Q: I'm changing my php code and/or templates, and my results are not getting
- updated.
-A: This may be the result of your compile or cache settings. If you are
- changing your php code, your templates will not necessarily get recompiled
- to reflect the changes. Use $force_compile during develpment to avoid these
- situations. Also turn off caching during development when you aren't
- specifically testing it. You can also remove everything from your
- compile_dir and cache_dir and reload the page to be sure everything gets
- regenerated.
-
-Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
- also zero length.
-A: There seems to be a problem with some W2k machines and exclusive file
- locking. Comment out the flock() call in _write_file to get around this,
- although be aware this could possibly cause a problem with simultaneous
- writes to a file, especially with caching turned on. NOTE: As of Smarty
- 1.4.0, a workaround was put in place that should solve this.
-
-Q: The template goes into an infinite loop when I include included templates
- that pass local variables
-A: This was fixed in 1.3.2 (new global attribute)
-
-Q: Javascript is causing Smarty errors in my templates.
-A: Surround your javascript with {literal}{/literal} tags. See the docs.
-
-Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
-A: Use $smarty->use_sub_dirs = false when running php in safe mode.
-
-MISC
-----
-
-Q: Can I use Macromedia's Dreamweaver to edit my templates?
-A: Certainly. You might want to change your tag delimiters from {} to something
- that resembles valid HTML, like <!--{ }--> or <{ }> or something similar.
- This way the editor won't view the template tags as errors.
-
-Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
- HREF link. How do I get around this?
-A: In Edit - Properties - Rewrite HTML you can specify if Dreamweaver should
- change special letters to %-equivalent or not. The default is on which
- produces this error.
-
-HOWTO
------
-
-Q: How do I generate different cache files per template based on arguments
- passed to the page?
-A: Use your $REQUEST_URI as the cache_id when fetching the page:
-
- global $REQUEST_URI; // if not already present
- $smarty->display('index.tpl',$REQUEST_URI);
-
- This will create a separate cache file for each unique URL when you call
- index.tpl. See the documentation for display() and fetch()
-
-Q: How do I pass a template variable as a parameter? {function param={$varname}}
- does not work.
-A: {function param=$varname} (You cannot nest template delimiters.)
-
-Q: How do I include cached template(s) within a non-cached template?
-A: One way to do it:
-
- $smarty->caching = true;
- $tpl1 = $smarty->fetch("internal1.tpl");
- $tpl2 = $smarty->fetch("internal2.tpl");
- $tpl3 = $smarty->fetch("internal3.tpl");
-
- $smarty->assign("tpl1_contents",$tpl1);
- $smarty->assign("tpl2_contents",$tpl2);
- $smarty->assign("tpl3_contents",$tpl3);
-
- $smarty->caching = false;
- $smarty->display('index.tpl');
-
- index.tpl
- ---------
-
- <table>
- <tr>
- <td>{$tpl1_contents}</td>
- <td>{$tpl2_contents}</td>
- <td>{$tpl3_contents}</td>
- </tr>
- </table>
-
-
-
-
- Another approach:
-
- You could write a custom insert function to fetch your internal
- templates:
-
- <table>
- <tr>
- <td>{insert name=fetch_tpl tpl="internal1.tpl"}</td>
- <td>{insert name=fetch_tpl tpl="internal2.tpl"}</td>
- <td>{insert name=fetch_tpl tpl="internal3.tpl"}</td>
- </tr>
- </table>
+++ /dev/null
-REQUIREMENTS:
-
-Smarty requires PHP 4.0.6 or later.
-See the on-line documentation for complete install instructions.
-
-INSTALLATION (quick):
-
-* copy the files under the libs/ directory to a directory that is in your PHP
- include_path, or set the SMARTY_DIR constant and put them in this directory.
- (if you upgrade from versions before 2.5.0 be aware that up to Smarty 2.4.2
- all necessary files where in the distribution's root directory, but are now
- in libs/.)
-
-* for each application using Smarty, create a "templates", "configs", and a
- "templates_c" directory, be sure to set the appropriate directory settings in
- Smarty for them. If they are located in the same directory as your
- application, they shouldn't need to be modified. Be sure the "templates_c"
- directory is writable by your web server user (usually nobody). chown
- nobody:nobody templates_c; chmod 700 templates_c You can also chmod 777 this
- directory, but be aware of security issues for multi-user systems. If you are
- using Smarty's built-in caching, create a "cache" directory and also chown
- nobody:nobody.
-
-* setup your php and template files. A good working example is in the on-line
- documentation.
-
-* TECHNICAL NOTE: If you do not have access to the php.ini file, you can change
- non-server settings (such as your include_path) with the ini_set() command.
- example: ini_set("include_path",".:/usr/local/lib/php");
+++ /dev/null
-Version 2.6.26 (June 18th, 2009)
--------------------------------
-- revert super global access changes, and instead rely on
- USE_SUPER_GLOBALS for security
-
-Version 2.6.25 (May 19th, 2009)
--------------------------------
-- fix E_NOTICE when sessions are disabled (mohrt)
-
-Version 2.6.24 (May 16th, 2009)
--------------------------------
-- fix problem introduced with super global changes (mohrt)
-
-Version 2.6.23 (May 13th, 2009)
--------------------------------
-- strip backticks from {math} equations (mohrt)
-- make PHP super globals read-only from template (mohrt)
-- throw error when template exists but not readable (mohrt)
-
-Version 2.6.22 (Dec 17th, 2008)
--------------------------------
-
-- back out method chaining, bug in some versions of PCRE causes errors (mohrt)
-
-Version 2.6.21 (Dec 2nd, 2008)
-------------------------------
-
-- fix function injection security hole closed (U.Tews)
-- fix pass expiration time at cache_handler_fuc call in core.write_cache_file.php (U.Tews)
-- Update of compiler.class.php to allow method chaining for PHP4 and PHP5 (U.Tews)
-
-Version 2.6.20 (Feb 15th, 2008)
--------------------------------
-
-- fix cache tag bug when multiple cache tags on a page (mankyd,
- mohrt)
-- fix /e tag checking when using arrays with regex_replace
- (mohrt)
-- fix that function results can be used with condition like "is even" in
- {if} tags (U.Tews)
-- fix handling of non-empty <pre>-tags and empty <textarea>- and
- <script>-tags (Spuerhund, messju)
-
-Version 2.6.19 (Feb 11th, 2008)
--------------------------------
-
-- fix regex_replace allowing \0 in the search string (c960657,
- monte)
-- add append feature to {capture} (jablko, monte)
-- fix when (un)registering filters with the same method name but different class
- name (danilo)
-- fix calling registered objects' methods with an empty argument list
- (marcello, messju)
-
-Version 2.6.18 (Mar 7th, 2007)
-------------------------------
-
-- fix html_select_date separator when parts are missing (hayk,
- monte)
-- fix broken detection of non-cached blocks introduced in 2.6.17
- (messju)
-
-Version 2.6.17 (Mar 5th, 2007)
-------------------------------
-
-- fix php handling (monte, boots, danilo)
-- fix handling of plugin tags directly followed by an else tag (Fahr, danilo)
-- fix handling of $etc in the truncate modifier when $etc is longer
- than $length (Sylvinus, messju)
-- fix handling of %I with mysql timestamps in the date_format modifier
- (danilo, boots)
-- update smarty_core_write_file() and smarty_modifier_date_format() to better
- recognize Windows (boots, danilo)
-- emulate %h, %n, %r, %R, %t in the date_format modifier on Windows
- (danilo, boots)
-
-Version 2.6.16 (Dec 1st, 2006)
-------------------------------
-
-- fixed replacement bug in trimwhitespace output filter that was introduced
- in the last release (Spuerhund, boots)
-
-Version 2.6.15 (Nov 30th, 2006)
--------------------------------
-
-- change file writing semantics in smarty_core_write_file() to unlink() only
- when rename() fails or a Windows system is detected (c960657, boots)
-- update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug
- output and apply a Smarty based color scheme (cybot, boots)
-- enhance reporting precision of debug_print_var modifier (cybot, boots)
-- make html_select_date work consistently with 0000-00-00 00:00:00 and
- 0000-00-00 inputs (cybot, boots)
-- fix wrong handling of insert's name attribute. (messju)
-- fix false replacement of "$t" inside double quotes (checat, messju)
-- added support for column headings and caption element to html_table and
- updated the output to use thead/tbody elements (boots)
-- fixed ordering of replacements in trimwhitespace output filter (Getty, boots)
-- update mailto function plugin to work around a firefox/thunderbird
- escaping bug (elijahlofgren, boots)
-- emulate %l in the date_format modifier on windows (boots)
-- fix handling of apostrophes in capitalize modifier (Alec Smecher, boots)
-
-Version 2.6.14 (May 28th, 2006)
--------------------------------
-
-- fix compiler bug allowing php tags in secure templates
- (boots,monte)
-- un-hide hidden xml open tags (boots)
-- fix handling of block-methods of registered objects (El Hombre Gris,
- messju)
-
-Version 2.6.13 (March 9th, 2006)
---------------------------------
-
- - update regex_replace, removing possible use of "e" modifier
-
-Version 2.6.12 (Jan 18th, 2006)
--------------------------------
-
- - fix improper use of references in the compiler handling cached
- attributes and in compiled code handling block plugins (messju)
- - make Smarty::_read_file() work on latest php (messju)
- - fixed improper tokenization of certain inline math expressions (boots)
-
-Version 2.6.11 (Dec 14, 2005)
------------------------------
-
- - fixed code generation of non-cacheable blocks to play well with php's
- "Alternative syntax for control structures" (kihara, messju)
- - fix handling of multiple identical inserts in one display()-call (messju)
- - replace {} string access with equivalent substr() to avoid E_STRICT
- warnings in PHP 5.1 (boots)
- - return valid reference in get_config_vars() when given var is
- non-existant (Thomas Schulz, boots)
- - plugin html_image: fix incorrect secure_dir error when
- file doesn't exist (monte)
- - plugin html_image: add path_prefix param (monte)
- - add char_set parameter to escape modifier (Loading, monte)
- - fix notice in debug security check (Drakla, monte)
- - return valid reference in get_template_vars() when given var is
- non-existant (monte)
- - add escape type "urlpathinfo" to escape modifier (monte)
-
-Version 2.6.10 (Aug 5, 2005)
-----------------------------
-
- - allow secure_dir to be a filename, not just
- a directory name (monte)
- - set debug.tpl as a secure_dir, not the entire
- SMARTY_DIR (monte)
- - fix proper escaping for literal strings in
- Smarty_Compiler::_parse_var_props() (boots, messju)
- - remove ambiguity for numeric values passed to smarty_make_timestamp()
- (and thus the date_format modifier). numeric values are treated as
- timestamps now. (andreas, messju)
- - add passthru attribute feature to html_select_date (Sedgar,
- monte)
- - add "middle" parameter to truncate (monte)
- - make form input label ids optional (monte)
- - add error message for empty if/elseif statements (eykanal,
- monte)
- - cast selected value to string for comparison in html_radios
- (Exeption, monte)
- - updated html_select_date's year_as_text-feature to be xhtml compliant
- (Mark West, messju)
- - fix handling of selected month html_select_date (Yuri Weseman, messju)
-
-Version 2.6.9 (Mar 31, 2005)
-----------------------------
-
- - disallow variable function calls in {if} statements (messju, monte)
- - disallow variable function calls in {math} equations (messju, monte)
-
-Version 2.6.8 (Mar 21, 2005)
-----------------------------
-
- - remove e-modifier from regex_replace modifier (messju)
- - remove cast of object to array in foreach's from-attribute (messju)
- - add "null" as a valid token for {if} when security is enabled (messju)
- - add javascript_charcode encoding option to mailto function
- (monte)
- - add ids to html_radios labels (monte, menulis)
- - fix handling of strip-tags with non-default delimiters (Mark West, messju)
-
-Version 2.6.7 (Feb 3, 2005)
----------------------------
-
- - fix handling of hashed opening php-tags inside strip-blocks (messju)
- - removed border tag from html_image function (monte)
- - change escape:url use rawurlencode() instead of urlencode() (messju)
- - make $smarty.const.FOO compile to "FOO", and not to "constant('foo')".
- this is less code and a little faster execution. note that undefined
- constants are now displayed as the constant's name. (messju)
- - make block functions and registered objects' block methods use a
- local variable for block_content instead of a property of $smarty (messju)
- - fix escaping in the generated code that calls smarty_core_load_plugins
- (jes5199, messju)
- - fix invalid HTML issue with popup (Stefanos Harhalakis,
- Monte)
- - fixed {popup} to properly handle inarray and function parameters and added
- support for mouseoff and followmouse options (boots)
-
-Version 2.6.6 (Oct 13, 2004)
-----------------------------
-
- - fixed nocache-handling with nested includes (Lars Jankowfsky, messju)
- - moved /libs/core to /libs/internals (boots)
- - fixed more parsing problems (messju)
-
-Version 2.6.5 (Sept 13, 2004)
------------------------------
-
- - fixed some parsing problems with object calls introduced
- in 2.6.4 (Monte)
- - add $smarty->security_settings['ALLOW_CONSTANTS']. note: this
- defaults to false which means you have to allow them explicitly
- in your secured templates from now on! (messju)
-
-Version 2.6.4 (Sept 7, 2004)
-----------------------------
-
- - add $smarty.ldelim and $smarty.rdelim to smarty special var (Monte)
- - fall back to old uniqid()-behaviour when tempnam() fails in
- core.write_file.php (messju)
- - fix capitalize modifier, don't rely on buggy ucwords (Monte)
- - make html_select_date work with negative timestamps, also
- force year range to include given date unless explicitly
- set (Garo, Monte)
- - fix bug with {fetch}, passing user/pass in url did not work
- (Monte)
- - fix occasional wrong error messages on mismatched tags when
- {else}, {elseif}, {foreachelse} or {sectionelse} is involved (messju)
- - fix handling of methods arguments (messju, Manfred Wischin)
- - remove touch() call that made the compiled-template's timestamp the
- same as the source-template's one. (messju)
- - add assign attribute to html_checkboxes and html_radios
- (pcg, Monte)
- - remove non-xhtml conformant tag from mailto function
- (tacker, Monte)
- - handle date_format codes %e, %T and %D for windows (tip,
- Monte)
- - fix unnecessary call to smarty_core_get_include_path() inside
- Smarty::_get_auto_filename() (c960657, messju)
- - add error-messages when anything else than an identifier is passed
- to foreach's key- or item-attribute (messju)
- - fix handling of digits inside tagnames (messju)
- - fix escaping of backslashes in Smarty_Compiler::_quote_replace() (messju)
-
-Version 2.6.3 (June 16, 2004)
------------------------------
-
- - added escapement of '</' to '<\/' in escape:javascript
- modifier (c960657, Monte)
- - added obfuscation of protocol-string in {mailto} when using hex-
- encoding (bharat, messju)
- - enhanced auto-generated filenames for templates_c and cache (messju)
- - add 'nonstd' to escape modifier for escaping non-std chars,
- such as ms doc quote (Monte)
- - adjusted textformat to not output wrap chars after last para
- (Monte)
- - use tempnam() instead of unqid() to create better temporary files in
- smarty_core_write_file() (xces, messju)
- - add 'mail' to escape modifier for safe display of e-mail
- addresses (Monte)
- - add cycle function attribute "reset" to english docs (Monte)
- - enhanced support of numeric constants as variable-expressions (messju)
- - add case decentity to smarty_modifier_escape() (Konstantin A. Pelepelin,
- messju)
- - make smarty_core_write_compiled_include() php5-aware (messju)
- - removed unused functionality to load a subset of lines from a file (messju)
- - fix is_secure() should only check if a file is_readable, not if
- the directory where it is in is readable (sagi, messju)
- - fix problem displaying debug console when $default_resource_type
- is not "file:" (c960657, Monte)
- - fix permission handling with security and config_load (messju)
- - removed '.' from the list of default template locations in
- _parse_resource_name() (messju)
- - fix avoid warning with template_exists() on an absolute paths (messju)
- - fix parameters passed to resource's secure()-function (messju)
- - fix handling of integer values like width and delay im
- smarty_function_popup() (messju)
-
-Version 2.6.2 (Feb 17, 2004)
-----------------------------
-
- - fix allow empty years, months and days in html_select_date's
- time-attribute (messju)
- - fix YES and NO should not be booleanized inside triple-quotes in a
- config-file (messju)
- - fix accidently slurped line following a triple-quoted value in a
- config-file (messju)
- - change default for use_sub_dirs to false (messju)
- - fix quoting of values in smarty_function_popup() (messju)
- - fix handling of hidden sections in Config_File (messju)
- - add handling of resources for {config_load} (messju)
- - fix bug when using arrays with tr_attr and td_attr in {html_table} (messju)
- - add unit testing to cvs core (Monte)
-
-Version 2.6.1 (Jan 16, 2004)
-----------------------------
-
- - rename $smarty->tpl_error_reporting to $smarty->error_reporting
- (messju)
- - fix interpretation of $smarty->security in {html_image} (messju)
- - add caching of requested paths to _assemble_plugin_filepath() (messju)
- - fix handling of comments inside {php}- and {literal}-blocks (messju)
- - fix bug handling triple-quotes in config-files (BRDude, messju)
- - change default of request_use_auto_globals to true - $_SERVER is
- now preferred over $HTTP_SERVER_VARS (messju)
- - re-add support for $SCRIPT_NAME (messju)
- - reactivate $smarty->default_modifiers (messju)
- - add cookie persistance to debug console (Monte)
- - allow single-digit days and months without smarty_make_timestamp()
- in html_select_date (messju)
- - fix headers sent erroneously with cache_modified_check and fetch()
- (wphilips, messju)
- - fix config_file path bug (Marc Cabadas, Monte)
- - fix 'is even by' and 'is odd by' logic (Monte)
- - add day_empty, month_empty, year_empty and all_empty attributes to
- html_select_date (messju)
- - add table of explanation for {if} qualifiers in docs (boots)
- - fix bug when comparing array-keys to "selected" in html_options
- and html_checkboxes (messju)
- - add better checks for correctly nested tags when compiling (messju)
- - remove {$SCRIPT_NAME}. use {$smarty.server.SCRIPT_NAME} instead (messju)
- - remove $global_assign. assign global variables explicitly instead (messju)
- - fix example for count_characters in docs (boots)
- - add section new basic syntax section "Escaping Smarty Parsing" in docs (boots)
- - fix error handler call in config_load (boots)
- - remove warning in debug_print_var on php-resources (messju)
- - move function.assign.php to compiler.assign.php (messju)
- - add property $tpl_error_reporting (messju)
- - remove property $undefined. "null" is used literally instead (messju)
-
-Version 2.6.0 (Nov 19, 2003)
-----------------------------
-
- - move Smarty::quote_replace() to Smarty_Compiler::_quote_replace() (messju)
- - remove import of of attributes of {include_php} to php's namespace.
- use $params[name] instead (messju)
-
-Version 2.6.0-RC3 (Nov 13, 2003)
---------------------------------
-
- - fix handling of $var.key inside [] (messju)
- - fix handling of assign inside {insert}-tags (messju)
- - fix handling if [...] inside triple-quotes in config-files (messju)
- - fix handling of simple-math-operators inside modifiers (Dominik, messju)
- - fix handling of trailing-slashes in open_basedir in
- smarty_core_create_dir_structure() (packman, messju)
-
-Version 2.6.0-RC2 (Oct 8, 2003)
--------------------------------
-
- - apply modifiers only once to section-loop and foreach-from attrs (messju)
- - remove use of _smarty_cached_paths-files (messju)
- - remove Smarty::_plugin_implementation_exists() - use is_callable() (messju)
- - ignore {strip}/{/strip) inside {strip}-blocks (messju)
- - fixed removal of leading/trailing newlines in {strip}-blocks (messju)
- - fixed proper escaping of " and ' with escape:javascript (messju)
- - fixed bug in traversal of $smarty->plugins_dir-array. now the
- first matching plugin is taken (messju)
- - moved {strip} back into the compiler (messju)
- - fixed config_load: handling of section-attribute and use of
- multiple config-files in one template (atu, messju)
-
-Version 2.6.0-RC1 (August 11, 2003)
------------------------------------
-
- - fixed status-header for cache_modified_check under cgi-sapi (messju)
- - added optional parameter $cache_attrs to register_function() and
- register_block(). $cache_attrs is an array containing attribute-
- names that should be cached on calls to functions that have
- $cacheable set to false. (messju)
- - enabled registration of class-methods as callbacks for the register_*-
- functions (use: array('classname', 'method_name')) as callback) (messju)
- - added filepath caching (Monte)
- - added optional assign-attribute to {capture}-tag (messju)
- - added $cacheable-parameter to register_compiler_function() (messju)
- - added $cacheable-parameter with default=true to register_function()
- and register_block() (messju)
- - add math speedup to core (Dominik, Monte)
- - fix newlines for tags without template output (Monte)
- - added config-option "request_use_auto_globals" to make auto-globals be
- used as request vars instead of HTTP_*_VARS (messju)
- - speed up config_load, simplify compiling (Monte)
- - added block-methods for registered objects (Bharat Mediratta, messju)
- - ignore one char resource names like c:foo.tpl (Monte)
- - added default_resource_type feature (Monte)
- - fix bug where config file starts with hidden section (boots, Monte)
- - add discrete error checking pertaining to $cache_dir
- and $compile_dir, their existance and writability (Monte)
- - fixed behaviour of start=... for {counter} (messju)
- - fixed assign for {counter} (messju)
- - added params vdir, hdir and inner to html_table to allow looping
- over the data in various directions (messju)
- - allow spaces in literal tags (Paul Lockaby, Monte)
- - speed up compiled templates, hardcode plugin filepaths
- instead of dynamically calculate at runtime. (Monte)
- - abstract many core components from Smarty.class.php,
- speeding up core class instantiation (Monte)
- - fixed bug in _create_dir_structure() when used with open_basedir-
- restriction and relative paths (messju)
- - use DIRECTORY_SEPARATOR exclusively, keep DIR_SEP for BC (Monte)
- - changed "link" to "href" in html_image. "link" is still working
- but deprecated (messju)
- - html_image always renders an alt-tag now (default alt="") (messju)
- - fixed assign attribute for multiple counters (messju)
- - added simple math operators to variables (Monte)
- - enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted')
- as callback for register_resource() (messju);
- - enabled array(&$obj, 'method') as callback for
- $default_template_handler_func (messju)
- - remove unnecessary close/open tags from compiled templates
- (Monte)
- - fixed errornous creation of '//' in image_path in html_image (messju)
- - fix escapement of special chars for key vals in debug
- console (Monte)
- - fixed debug timing logic for config_load (Tom Sommer, Monte)
- - all in-code doc comments converted to phpDocumentor format (Greg)
- - moved strip from smarty core to plugin (Monte)
- - moved config_load from smarty core to plugin (Monte)
- - added &$repeat-parameter to block-functions (messju)
- - enabled hex-constants in function.math.php (messju)
- - enabled hex-constants (0x...) as function-attributes, inside if-statements
- and as modifier-parameters (messju)
- - fixed bug with passing $smarty as reference in Smarty.compiler.class
- (messju)
- - corrected output with {strip} and PHP tag newlines (Monte)
- - added possibility to register function-callbacks as "array(&$obj, 'method)"
- this affects register_function(), -block, -compiler_function, -modifier,
- -prefilter, -postfilter, -outputfilter-functions() and $cache_handler_func
- (messju)
- - added <labels> to html_checkboxes and html_radios (Philippe, messju)
- - added "labels"-options to turn off labels in html_checkboxes and _radios
- (messju)
-
-Version 2.5.0 (April 11, 2003)
-------------------------------
-
- - fixed bug with default modifier when passing integer 0
- (Monte)
- - change backtic syntax from $`foo` to `$foo` (Monte)
- - recognize $foo[][] syntax inside embedded quotes without
- backtics (Monte)
- - name=123 is passed as an integer (not a string) to plugins now (messju)
- - $length is now propagated to sub-values in debug_print_var (messju)
-
-Version 2.5.0-RC2 (March 26, 2003)
-----------------------------------
-
- - made clear_cache() ignore compile_id, when clearing cache-groups (this
- is when no $tpl_file is supplied) (messju)
- - made onmouseout XHTML-compliant in function.popup.php (messju)
- - applied local-var-naming-scheme to fetch() (messju)
- - renamed $localvars to $_localvars in cache-file-handling-functions,
- added _get_auto_id()-function (messju)
- - swapped compile_id and cache_id in read_cache_file and write_cache_file
- (messju)
- - reverted patch for cache-file-handling (messju)
- - made html_radios and html_checkboxes accept "selected" instead
- of "checked" optionally. (messju)
- - made compile_id ignored in clear_cache, made order of
- auto_file_name $cache_id.$compile_id again, applied the the new
- variable-naming-scheme for cache_file_handing functions (messju)
- - removed notice of undefined var in _rm_auto() (messju)
- - added warning message when an array is passed as
- the "checked" value of html_radios (Monte)
- - fixed errormessage in _compile_smarty_ref() (messju)
- - updated docs for html_image "name" -> "file" (messju)
- - fixed bug with html_options-optgroups (Nichlas Löfdahl, messju)
- - cleaned up calls to readdir() (messju)
- - fixed bug with passing multiple modifiers to a parameter
- (Monte)
- - updated docs for html_checkboxes, html_options and html_radios (messju)
- - fixed wrong default "name" attribute for html_options (messju)
- - html_checkboxes now expect the options as attribute "options" instead
- of "checkboxes. html_radios expect "options" instead of "radios".
- cleaned up indentiation (messju)
- - fixed too greedy str_replace in trimwhitespace outputfilter (messju)
- - html_checkboxes and html_radios passthru all unknown paramters now
- additionally their output is now XHTML compliant (messju)
- - html_options passthru all unknown paramters now (messju)
- - fix link functionality of html_image, also make
- output XHTML compatible (Hinrich Donner, Monte)
- - append "@" to default modifier vars/args
- supress possible warnings (Monte)
- - fix problem with escaped double quotes (Monte)
- - fix html_radios to not return an array (Monte)
- - fixed length in modifier.truncate.php (messju)
- - fixed handling of '$'-signs in trimwhitespace outputfilter (messju)
- - fix bug that makes config files recompile every time
- (Nagger, Monte)
- - add dpi functionality to html_image, change "name"
- parameter to "file" (Thomas Shulz, Monte)
- - fix height/width parameter index in html_image (Gerard,
- Monte)
- - get rid of unsetting name and script attributes
- to insert tag (Thomas Schulz, Monte)
- - changed argument order of string_format modifier back,
- was right in the first place (Monte)
-
-Version 2.5.0-RC1 (March 5, 2003)
----------------------------------
-
- - fixed notice in popup function (Nagger, Monte)
- - fix "once" var compiling for include_php (Monte)
- - added nl2br modifier to distribution (Monte)
- - added html_image to distribution (Monte)
- - added cat modifier to distribution (Monte)
- - added html_table to distribution (Monte)
- - added << >> <> support to if statments (SMK, Monte)
- - fix _assign_smarty_interface to not overwrite keys
- other than 'request' (Jerome Poudevigne, Monte)
- - added html_checkboxes to distribution (Christopher Kvarme, Monte)
- - added html_radios to distribution (Christopher Kvarme, Monte)
- - fixed string_format modifier args (wrong order) (Paul
- Lockaby, Monte)
- - use tmp file for file writes, avoid file lock race (Monte)
- - support syntax "$`smarty.config.foo`.tpl" for embedded
- vars in quotes, and allow full dollar var syntax (Monte)
- - add $smarty.config.varname variable for accessing config vars (Paul
- Lockaby, Monte)
- - silence PHP warnings in function.fetch.php (Eduardo,
- Monte)
- - added get_config_vars(), same basic functionality as
- get_template_vars() (Monte)
- - update get_template_vars() to be able to get
- individual vars (Monte)
- - fix minor logic in _fetch_template_info (Dennis Gearon,
- Monte)
- - fix cache groups with compile_id set (Monte)
- - add support for merging appended vars (messju, Monte)
- - allow null as function attribute value
- (André Rabold, Monte)
- - support $foo->bar[index] syntax (Monte)
- - add get_registered_object function (messju, Monte)
- - treat unrecognized param attribute syntax as string (Monte)
- - support $smarty.const.$foo syntax (messju, Monte)
- - remove E_NOTICE warnings from debug.tpl,
- escape modifier (Kanstantin, Monte)
- - don't count non-ascii chars in count_words modifier
- (Kanstantin, Monte)
- - clean up param calls to _parse_var and _parse_attrs (Monte)
- - define $template_source var, elude possible warning
- (Monte)
- - fix syntax problem with evaluating PHP constants (Monte)
- - add @ and === as valid if statement tokens (Monte)
- - enable error messages for config_load errors,
- use $this->config_class for loading class name (Monte)
- - fix html_options to not escape already escaped entities (Monte)
- - send Last-Modified header on cache creation (Monte)
- - check strict syntax of function attributes (Monte)
- - dropped support for modifers on object parameters,
- added support for objects as modifier parameters (Monte)
- - fixed bug with decimal numbers in if statements (Monte)
-
-Version 2.4.2 (Feb 11, 2003)
-----------------------------
- - support embedded variables in objects (Monte)
- - fix bug with objects with no properties (M Mohr, Monte)
- - support full dollar var syntax in quoted text (Monte)
- - fixed bug in $smarty.const.FOO introduced in 2.4.1 (M
- Mohr, Monte)
-
-Version 2.4.1 (Feb 6, 2003)
----------------------------
-
- - ignore case in IF statements (Rainer Collet, Monte)
- - treat undefined constants as null (Ferdinand Beyer, Monte)
- - fix problem with inserts and nested fetches
- (Rainer Collet, Monte)
- - added support for passing params to include_php
- (Tim Riley, Monte)
- - added support for math operators in if statements (Monte)
- - added support for $foo->bar[$x].blah syntax (Monte)
-
-Version 2.4.0 (Feb 2, 2003)
----------------------------
-
- - fix known problems with php tag handling in templates
- (recursion, echoing xml tags) (Monte)
- - add support for object registration (Monte)
- - add debug template to secure_dir, add template_dir
- to secure_dir by default (Ferdinand Beyer, Monte)
- - added support for assigned object access (Monte)
- - fixed bug with directories named '0' (Frank Bauer, Monte)
- - add javascript parameter to escape modifier (Monte)
- - added calling function line numbers to syntax error
- messages in compiler (Monte)
- - added support for modifiers to function calls (Monte)
- - support return value for custom functions
- instead of echoing (but echo still works) (Monte)
- - added direct access to constants
- via $smarty.const.FOO (Monte)
- - added support for passing modifiers
- to static values (Monte)
- - fix up regex code in compiler, more accurate and
- maintainable (Monte)
- - added day_value_format to html_select_date (Marcus
- Bointon, Monte)
- - assigned variables are no longer in global
- namespace, saving extract() calls and speeding
- up fetch() and display() linearly with no. of
- assigned variables (Monte)
- - added trimwhitespace output filter to dist. (Monte)
- - fix popup function to allow newlines in text (Monte)
- - escape html entities in html_options (Monte)
- - fixed bug with label for html_options (Monte)
- - added config_load API function (Monte)
- - added caching to config file loading (Monte)
- - added "extra" parameter to mailto function (Monte,
- Massimiliano Perantoni)
- - added mailto plugin to dist. (Monte)
-
-Version 2.3.1 (Nov 19, 2002)
-----------------------------
-
- - added optgroup support to html_options (Monte, Robert
- Amos)
- - set mtime on compile files so they match source
- files (Monte, Peter Bowen)
- - added proper support for open_basedir setting
- (Monte, Alessandro Astarita)
- - added strip variable modifier, updated docs (Monte)
- - fixed access to $smarty.x variables as arrays. (Andrei)
- - fixed errors with example setup docs (Monte, Matthew
- Hagerty)
- - added textformat block function (Monte)
-
-Version 2.3.0 (Aug 7, 2002)
----------------------------
-
- - added assign_by_ref() and append_by_ref() functions
- (Bob Silva, Monte)
- - changed default warning type for plugin errors from
- E_USER_WARNING to E_USER_ERROR (Monte)
- - added $all_extra, $hour_extra, $minute_extra,
- $second_extra and $meridian_extra parameters to
- html_select_time function (Rainer Collet, Monte)
- - update debug console to print objects (Simon Willison,
- Monte)
- - fix Config_File class to not error when there are no
- sections (Peter Kmet, Monte)
- - add default modifier logic (Monte)
- - updated popup_init to be xhtml compliant (Tom Oram, Monte)
- - fix filename bug with windows (Gary Loescher, Monte)
- - add ability to supply expire time in seconds when clearing
- cache or compile files (Monte)
- - add {debug} plugin to distribution (Monte)
- - fixed bug with insert tags, loading from "script" attribute
- when caching is enabled (Monte)
- - fix bug with debug_tpl file path with Windows (.SMK., Monte)
- - fix append() function with string/array problem (Monte)
-
-Version 2.2.0 (July 11, 2002)
------------------------------
-
- - make debug.tpl work with any delimiter (Monte)
- - change logic in assign() and append() to test var names
- against != '' instead of empty() (Monte)
- - fix PHP notice in append() function (Monte)
- - allow $plugins_dir to be an array of directories
- (Andreas Kossmeier, Monte)
- - move debug.tpl to SMARTY_DIR, add to constructor (Monte)
- - fixed warning message in function.assign_debug_info (Monte)
- - fixed $template_dir, $compile_dir, $cache_dir, $config_dir,
- $plugin_dir to respect include_path (Monte)
- - fixed warning message with output filter array (Monte)
- - add optional 2nd parameter to date_format, used as
- the default date if the passed date is empty (Monte)
- - gave $reset a default value in cycle plugin (Monte)
- - fixed warnings with html_select_date and timestamp
- functions (Monte)
- - added support for sub directory exlusion format (Monte)
- - added support for grouping by cache_id, compile_id
- and segments thereof (Monte)
- - changed cache and compile files to human readable
- format (Monte)
- - remove overlib.js file from distribution (Monte)
- - fixed bug with 304 Not Modified response sending
- content (Monte)
- - fixed cycle function to respect delimiter after
- initial setting (Monte)
- - update $GLOBALS references to work properly with
- track_globals settings (Michal Prinke, Monte)
- - fixed bug in math function with call to assign
- (Grigory V. Kareev, Monte)
- - optimized for loops with count() function calls (Monte)
- - add month_value_format attribute to html_select_date
- plugin (Gary Loescher, Monte)
- - made it possible to use simple variables inside [] for
- indexing. (Andrei)
- - added "once" attribute to {include_php}. (Monte)
-
-Version 2.1.1
--------------
- - added cycle function. (Monte)
- - fixed bug with resource testing, and include_path. (Monte)
- - fixed a bug with register_outputfilter function. (Monte)
-
-Version 2.1.0
--------------
-
- - introduced output filters. (Andrei)
- - changed the way filters are loaded, added load_filter()
- API function and $autoload_filters variable. (Andrei)
- - added caching logic for expire times per cache file
- (Norbert Rocher, Monte)
- - fixed html_select_date when field separator is "/"
- (Roberto Berto, Monte)
- - added YYYY-MM-DD format support to html_select_date
- (Jan Rosier, Monte)
- - fixed cache_lifetime logic bug, also made -1 = never
- expire (Monte)
- - fixed directory separator issue for Windows. (Andrei)
- - added ability to use simple variables as array indices or
- object properties. (Andrei)
- - added ability to unregister pre/postfilters plugins at
- runtime. (Andrei)
- - added 'htmlall' attribute to escape modifier. (Monte)
- - added template_exists() API function. (Andrei)
- - fixed a problem with using dynamic values for 'file'
- attribute of {include_php} tag. (Andrei)
- - added $smarty.template variable. (Andrei)
- - fixed several plugins that would not work if the plugin
- directory was not the default one. (Andrei)
- - implemented support for block functions. (Andrei)
- - made it possible to assign variables in pre/postfilter
- plugins. (Andrei)
-
-Version 2.0.1
--------------
- - rename plugin .make_timestamp.php to shared.make_timestamp.php.
- (Monte)
- - changed crc32() generated values, replace '-' with 'N'. (Monte)
- - added support for +/- N syntax in html_select_date year values.
- (Monte)
- - fixed behavior of inserts with script attribute. (Andrei)
- - fixed bug with $smarty.cookies and $smarty.server. (Andrei)
- - wordwrap and indent are missing from 2.0 release, now fixed.
- (Monte)
- - removed show_info_header and show_info_include variables. (Monte)
-
-Version 2.0.0
--------------
- - added "eval" function plugin for evaluating variables as
- templates. (Monte)
- - removed $tpl_file_ext class variable, no longer used. (Monte)
- - added "hex" and "hexentity" escape types to escape modifier.
- (Monte)
- - removed dependency on PEAR. (Andrei)
- - update popup_init to accept src attribute. (Monte, Duncan Forrest)
- - implemented several optimizations, speeding up Smarty
- significantly in most cases. (Andrei,Monte)
- - implemented plugin architecture. (Andrei)
- - added wordwrap and indent modifiers. (Monte)
- - added support for 'If-Modified-Since' headers for cached content.
- (Monte)
- - removed insert_tag_check class variable, no longer needed. (Monte)
- - optimized cache fetches by scanning for insert tags only if they
- exist. (Monte)
- - fixed bugs in overlib. (Monte, Duncan Forrest)
- - fixed a problem with compile_id usage. (Andrei)
- - fixed problem with using assigned vars with {include_php ...}
- filepath. (Monte)
-
-Version 1.5.2
--------------
- - added Smarty object as fifth argument for template resource functions.
- (Monte)
- - fixed a bug with incorrectly combined cache and compile id in
- clear_cache(). (Andrei)
- - fixed bug in smarty_make_timestamp introduced in PHP 4.1.0. (Monte)
- - fixed bug with cached insert debug timing. (Monte)
- - added 'script' attribute to {insert..} which specifies the script that
- the insert function can be found in. (Andrei)
- - added default template function handler. (Monte)
-
-Version 1.5.1
--------------
- - removed error message from the generic _read_file() method, the caller
- should take care of that. (Andrei)
- - fixed a bug with incorrectly combined cache and compile id. (Andrei)
-
-Version 1.5.0
--------------
- - added include_php built-in function, documented. (Monte)
- - added trusted_dir functionality, documented. (Monte)
- - consolidated secure_dir tests to one function. (Monte)
- - prepended _smarty_ to variable names in fetch() class function to avoid
- namespace conflicts. (Monte)
- - introduced $compile_id class variable that can be used to set persistent
- compile identifier across multiple display calls, documented. (Andrei)
- - fixed bug with concatenated null cache and compile identifiers. (Andrei)
- - added $smarty.section.* syntax for accessing section properties,
- documented. (Andrei)
- - added custom cache handling function ability, documented. (Monte)
- - added assign attribute to include, include_php, insert, fetch, math, and
- counter functions, documented. (Monte)
- - fixed bug with fetch testing for local file when http address. (Monte)
- - fixed bug with counter and skipval setting. (Monte)
- - made {config_load ...} merge globals from each config file only once per
- scope, thus avoiding several problems. (Andrei)
- - added {foreach ...} tag that can be used to iterate through
- non-sequential and associative arrays, documented. (Andrei)
- - speeded up section property access a bit. (Andrei)
- - removed $smarty variable from storage used by normal template variables,
- to prevent any problems. (Andrei)
- - fixed a bug that could cause parse error with quotes inside literal
- blocks. (Andrei, Alexander Belonosov)
- - added 'field_array' attribute to html_select_time function, documented.
- (Andrei, Michael Caplan)
- - documented {section} "max" attribute. (Monte)
- - fixed notice message in Smarty_Compiler.class.php. (Monte)
- - fixed bug with clear_cache introduced in 1.4.6, third parameter should
- default to null. (Monte)
- - updated Config_File class to support '\' path separator in OS/2. (Monte,
- Francesco Cipriani)
- - removed secure_ext setting (not used). (Monte)
- - made cache reading process more efficient. (Monte)
- - fixed bug, is_cached() now supports new 1.4.6 caching behavior. (Monte)
- - update FAQ with mailing list Reply-To header FAQ. (Monte)
- - supress error messages for fopen(), fix cache to regenerate if cache
- file is not available (i.e. cluster race condition). (Monte)
- - added index key example to QUICKSTART guide. (Monte)
-
-Version 1.4.6
--------------
- - fixed bug with {assign ...} when passing an empty value. (Monte)
- - add more warning message fixes. (Monte, Tara Johnson)
- - documentation updates. (Monte)
- - update fetch function to give proper warning when fetching a non-readable
- or non-existant file. (Monte)
- - fixed problem with newline at the end of included templates (Monte, Andrei)
- - added feature to regenerate cache if compile_check is enabled and an
- involved template or config file gets modified. (Monte)
- - added DEBUG execution times to included files: REQUIRES updated debug.tpl
- file! (Monte)
- - added support for hidden config variables that cannot be read by
- templates. (Andrei)
- - added execution time to DEBUG console, total and inserts. (Monte)
- - fixed bug where DEBUG console would not appear with cached content. (Monte)
- - added support for postfilter functions that are applied to compiled
- template right after compilation. (Andrei)
- - fixed the name of clear_compile_tpl() API function to clear_compiled_tpl.
- (Andrei)
- - added fix for removing comments so that the line numbers are reported
- correctly in case of errors. (patch from Anders Janson)
- - made html_options output xhtml compatible code. (Monte, Arnaud Limbourg)
-
-Version 1.4.5
--------------
- - update FAQ with index of questions at the top
- - update overlib to 3.50, adjust addon code so that the overlib.js
- file isn't modified, and not using the mini one. (Monte)
- - added many more options to html_select_date. (Alexander Skwar, Andrei)
- - added support for generating different compiled templates from the same
- source template. (Hans-Peter Oeri, Andrei)
- - modified Smarty to pass itself to insert functions as the second
- parameter. (Andrei)
- - modified Smarty to pass itself to prefilter functions as the second
- parameter. (Andrei)
- - fixed syntax error when including a non-existant template with security
- enabled. (Monte)
- - fixed comments handling to allow commenting out template blocks. (Andrei)
- - implemented named capture buffers, with results accessible via
- $smarty.capture.<name>. (Andrei)
- - added ability to index arrays directly by numbers. (Andrei)
- - fixed bug with SMARTY_DIR not prepended to Config_File include. (Monte)
-
-Version 1.4.4
--------------
- - fixed problem with including insecure templates with security enabled.
- (Monte)
- - numerous documentation updates. (Monte)
- - added ENT_QUOTES to escapement of html. (Monte, Sam Beckwith)
- - implemented access to request variables via auto-assigned $smarty
- template variable. (Andrei)
- - fixed a bug with parsing function arguments inside {if} tags if a comma
- was present. (Andrei)
- - updated debug console with config file vars. (Monte)
- - added SMARTY_DIR constant as an alternative to relying on include_path.
- (Monte)
- - added popup_init and popup functions (requires overlib.js). (Monte)
- - updated debug console with config file vars. (Monte)
- - added debugging url control. (Monte)
- - added 'quotes' type to escape modifier. (Monte, Mike Krus)
- - added 'total' and 'iteration' section properties. (Andrei)
- - added 'start', 'max', and 'step' section attributes/properties. (Andrei)
- - fixed a bug with security checking of functions inside {if} tags.
- (Andrei)
- - fixed a bug in Config_File that would incorrectly booleanize values that
- weren't really booleans. (Andrei)
-
-Version 1.4.3
--------------
- - added regex_replace modifier, documented. (Monte)
- - added debugging console feature and custom function assign_debug_info,
- documented. (Monte)
- - added 'scope' attribute for {config_load}, 'global' is now deprecated but
- is still supported. (Andrei)
- - reduced template symbol table pollution by moving config array into the
- class itself. (Andrei)
- - fixed a bug with passing quoted arguments to modifiers inside {if}
- statements. (Andrei, Sam Beckwith)
- - added security features for third party template editing, documented
- (Monte)
- - added assign custom function, documented. (Monte)
- - fixed bug with template header using version instead of _version. (Monte)
- - fixed a problem with putting $ followed by numbers inside {strip} and
- {/strip} tags. (Andrei)
- - fixed Config_File class to allow empty config paths (defaults to current
- directory). (Andrei)
-
-Version 1.4.2
--------------
- - move $version to internal variable, remove from docs. (Monte)
- - cleaned up compiled templates global scope by moving some variables into
- the class itself. (Andrei)
- - fixed a bug that would not allow referring to a section in the including
- file from the included file. (Andrei)
- - configs directory missing from 1.4.1 release, added back in. (Monte)
- - added windows include_path setup instructions to FAQ & QUICKSTART.
- (Monte)
-
-Version 1.4.1
--------------
- - fix LOCK_EX logic for all windows platforms (Monte)
- - fixed indexing by section properties with the new syntax. (Andrei)
- - updated Smarty to use absolute paths when requiring/including Smarty
- components. (Andrei, John Lim)
-
-Version 1.4.0
--------------
- - added {capture}{/capture} function, documented (Monte)
- - added {counter} function, documented (Monte)
-
-Version 1.4.0b2
----------------
- - fixed issue in Config_File.class with referencing blank sections (Andrei)
- - fixed problem with passing variables to included files (Andrei)
- - fixed resource path recognition for windows (Monte)
-
-Version 1.4.0b1
----------------
- - added "componentized templates" tip into documentation (Monte)
- - added {php}{/php} tags for embedding php code into templates (Monte)
- - changed default value of $show_info_header to false (Monte)
- - implemented '->' syntax for accessing properties of objects passed to the
- template. (Andrei)
- - allowed custom functions to receive Smarty object as the second
- parameter; this can be used to dynamically change template variables, for
- example. (Andrei)
- - added custom compiler functions support, register_compiler_function() and
- unregister_compiler_function() API functions. (Andrei, Ivo Jansch).
- - updated GLOBAL_ASSIGN to take SCRIPT_NAME from HTTP_SERVER_VARS
- instead of global variable. You can also assign several variables
- in one shot with an array. (Monte, Roman Neuhauser)
- - added template prefilters, register_prefilter() and
- unregister_prefilter() API functions. (Monte)
- - added RELEASE_NOTES file to distribution. (Monte)
- - moved CREDITS out of manual into its own file. (Monte)
- - added register_resource() and unregister_resource() API functions. (Monte)
- - changed the syntax of indexing template variables, thus supporting
- structures of arbitrary complexity; supplied fix_vars.php script to fix
- old syntax. (Andrei)
- - added $insert_tag_check to speed up cached pages if {insert ...} is not
- used. (Monte)
- - added $compiler_class variable to allow specifying a different compiler
- class. (Andrei)
- - changed Smarty to compile templates at runtime, allowing for arbitrary
- template resources. (Monte)
- - added fix for LOCK_EX under Windows and changed a couple of file
- permissions for security. (Monte, Fernando Nunes)
- - allow arbitrary date strings to date_format, html_select_date and
- html_select_time (Monte)
-
-Version 1.3.2
--------------
- - fixed a bug that caused some nested includes to loop infinitely. (Andrei)
- - added optional HTML header to output. (Monte)
- - significantly improved config_load performance. (Andrei)
- - added format attribute to math function. (Monte)
- - added html_select_time custom function. (Andrei)
- - fixed minor PHP warning when attempting to unset an unset variable
- (Monte)
- - added count_characters, count_words, count_sentences, count_paragraphs
- modifiers (Monte)
-
-Version 1.3.1pl1
---------------
- - bug fix, recovered missing _syntax_error function (Monte)
-
-Version 1.3.1
--------------
- - document first, last, index_prev, index_next (Monte)
- - added 'first' and 'last' section properties. (Andrei)
- - split out compiling code to separate class for faster template execution
- time (Monte)
- - fixed a couple of minor PHP warnings (Monte)
- - added and documented unregister_modifier() and unregister_function() API
- calls. (Monte)
- - added and documented 'fetch' and 'math' functions. (Monte)
- - added ability to index looped variables by section properties, e.g.
- $foo.index_prev/bar. (Andrei)
- - added index_prev and index_next section properties. (Andrei)
- - fixed issue with php executing in literal blocks. (Monte)
-
-Version 1.3.0
--------------
- - moved license from GPL to LGPL (Monte)
- - implemented workaround for PHP "feature" that eats carriage returns
- if the PHP tag is at the end of the line. (Andrei)
- - removed $allow_php, added $php_handling logic (Monte)
- - added file locking to prevent reader/writer problem. (Andrei)
- - made Smarty catch unimplemented modifiers and custom functions and output
- error messages during compilation instead of failing during run time.
- (Andrei)
- - removed short-tags at the top of the smarty scripts (Monte)
- - added register_function() and register_modifier() API calls to make
- registering stuff easier. (Andrei)
- - added template results caching capability. (Monte, Andrei)
- - added optional 'options' attribute to html_options custom function
- that allows passing associative arrays for values/output. (Andrei)
- - modifier arguments can now contain '|' and ':' characters inside quoted
- strings. (Andrei)
-
-Version 1.2.2
--------------
- - fixed bug that would not respect nested template directories and would
- put all compiled files into top-level one. (Andrei)
- - fixed bug using $PHP_VERSION instead of environment var PHP_VERSION.
- (Monte)
- - a couple small warning fixes. (Monte)
-
-Version 1.2.1
--------------
- - added $compile_dir, removed $compile_dir_ext, simplified usage. (Monte)
- - added tips & tricks chapter to documentation. (Monte)
- - misc documentation updates. (Monte)
-
-Version 1.2.0
--------------
- - updated documentation (Monte)
- - added file and line number information to syntax error messages. (Andrei)
- - added ability to index template vars by a key. (Andrei)
-
-Version 1.1.0
--------------
- - misc documentation changes, official stable release
-
-Version 1.0b
-------------
- - fixed the bug that prevented using non-array values for 'loop' attribute.
- (Andrei)
- - many misc documentation changes & additions (Monte)
-
-Version 1.0a
-------------
- - fixed bug that caused templates to recompile every time (Monte)
-
-Version 1.0
-------------
- - initial release
-
-/* vim: set et tw=64 ft=changelog: */
+++ /dev/null
-This is a simple guide to get Smarty setup and running quickly. The online
-documentation includes a very thorough explanation of a Smarty installation.
-This guide is meant to be a quick and painless way of getting Smarty working,
-and nothing more. The guide assumes you are familiar with the UNIX system
-environment. Windows users will need to make adjustments where necessary.
-
-INSTALL SMARTY LIBRARY FILES
-
-Copy the Smarty library files to your system. In our example, we place them in
-/usr/local/lib/php/Smarty/
-
-$> cd YOUR_DOWNLOAD_DIRECTORY
-$> gtar -ztvf Smarty-2.6.7.tar.gz
-$> mkdir /usr/local/lib/php/Smarty
-$> cp -r Smarty-2.6.7/libs/* /usr/local/lib/php/Smarty
-
-You should now have the following file structure:
-
-/usr/local/lib/php/Smarty/
- Config_File.class.php
- debug.tpl
- internals/
- plugins/
- Smarty.class.php
- Smarty_Compiler.class.php
-
-
-SETUP SMARTY DIRECTORIES
-
-You will need four directories setup for Smarty to work. These files are for
-templates, compiled templates, cached templates and config files. You may or
-may not use caching or config files, but it is a good idea to set them up
-anyways. It is also recommended to place them outside of the web server
-document root. The web server PHP user will need write access to the cache and
-compile directories as well.
-
-In our example, the document root is /web/www.domain.com/docs and the
-web server username is "nobody". We will keep our Smarty files under
-/web/www.domain.com/smarty
-
-$> cd /web/www.domain.com
-$> mkdir smarty
-$> mkdir smarty/templates
-$> mkdir smarty/templates_c
-$> mkdir smarty/cache
-$> mkdir smarty/configs
-$> chown nobody:nobody smarty/templates_c
-$> chown nobody:nobody smarty/cache
-$> chmod 775 smarty/templates_c
-$> chmod 775 smarty/cache
-
-
-SETUP SMARTY PHP SCRIPTS
-
-Now we setup our application in the document root:
-
-$> cd /web/www.domain.com/docs
-$> mkdir myapp
-$> cd myapp
-$> vi index.php
-
-Edit the index.php file to look like the following:
-
-<?php
-
-// put full path to Smarty.class.php
-require('/usr/local/lib/php/Smarty/Smarty.class.php');
-$smarty = new Smarty();
-
-$smarty->template_dir = '/web/www.domain.com/smarty/templates';
-$smarty->compile_dir = '/web/www.domain.com/smarty/templates_c';
-$smarty->cache_dir = '/web/www.domain.com/smarty/cache';
-$smarty->config_dir = '/web/www.domain.com/smarty/configs';
-
-$smarty->assign('name', 'Ned');
-$smarty->display('index.tpl');
-
-?>
-
-
-SETUP SMARTY TEMPLATE
-
-$> vi /web/www.domain.com/smarty/templates/index.tpl
-
-Edit the index.tpl file with the following:
-
-<html>
-<head>
-<title>Smarty</title>
-</head>
-<body>
-Hello, {$name}!
-</body>
-</html>
-
-
-
-Now go to your new application through the web browser,
-http://www.domain.com/myapp/index.php in our example. You should see the text
-"Hello Ned!" in your browser.
-
-Once you get this far, you can continue on to the Smarty Crash Course to learn
-a few more simple things, or on to the documentation to learn it all.
+++ /dev/null
-
-NAME:
-
- Smarty - the PHP compiling template engine
-
-VERSION: 2.6.26
-
-AUTHORS:
-
- Monte Ohrt <monte at ohrt dot com>
- Andrei Zmievski <andrei@php.net>
-
-MAILING LISTS:
-
- We have a few mailing lists. "discussion" for you to share your ideas or ask
- questions, "developers" for those interested in the development efforts of Smarty,
- and "svn" for those that would like to track the updates made in the svn
- repository.
-
- send a blank e-mail message to:
- smarty-discussion-subscribe@googlecode.com(subscribe to the general discussion list)
- smarty-discussion-unsubscribe@googlecode.com (unsubscribe from the general discussion list)
- smarty-discussion-digest-subscribe@googlecode.com (subscribe to digest)
- smarty-discussion-digest-unsubscribe@googlecode.com (unsubscribe from digest)
- smarty-developers-subscribe@googlecode.com (subscribe to the dev list)
- smarty-developers-unsubscribe@googlecode.com (unsubscribe from the dev list)
- smarty-svn-subscribe@googlecode.com (subscribe to the svn list)
- smarty-svn-unsubscribe@googlecode.com (unsubscribe from the svn list)
-
- You can also browse the mailing list archives at
- http://groups.google.com/group/smarty-discussion
- http://groups.google.com/group/smarty-developers
-
- and the OLD list archives at
- http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
-
-SYNOPSIS:
-
- require("Smarty.class.php");
-
- $smarty = new Smarty;
-
- $smarty->assign("Title","My Homepage");
- $smarty->assign("Names",array("John","Gary","Gregg","James"));
-
- $smarty->display("index.tpl");
-
-
-DESCRIPTION:
-
- What is Smarty?
-
- Smarty is a template engine for PHP. Many other template engines for PHP
- provide basic variable substitution and dynamic block functionality.
- Smarty takes a step further to be a "smart" template engine, adding
- features such as configuration files, template functions, and variable
- modifiers, and making all of this functionality as easy as possible to
- use for both programmers and template designers. Smarty also converts
- the templates into PHP scripts, eliminating the need to parse the
- templates on every invocation. This makes Smarty extremely scalable and
- manageable for large application needs.
-
- Some of Smarty's features:
-
- * it is extremely fast
- * no template parsing overhead, only compiles once.
- * it is smart about recompiling only the template files that have
- changed.
- * the template language is remarkably extensible via the plugin
- architecture.
- * configurable template delimiter tag syntax, so you can use
- {}, {{}}, <!--{}-->, or whatever you like.
- * built-in caching of template output.
- * arbitrary template sources (filesystem, databases, etc.)
- * template if/elseif/else/endif constructs are passed to the PHP parser,
- so the if syntax can be as simple or as complex as you like.
- * unlimited nesting of sections, conditionals, etc. allowed
- * it is possible to embed PHP code right in your template files,
- although not recommended and doubtfully needed since the engine
- is so customizable.
- * and many more.
-
-COPYRIGHT:
- Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved.
- This software is released under the GNU Lesser General Public License.
- Please read the disclaimer at the top of the Smarty.class.php file.
+++ /dev/null
-2.6.7
------
-
-Those using Smarty with security enabled: a hole was found that allowed PHP code to be executed from within a template file. This has been fixed and you are engouraged to upgrade immediately. Note that this hole does NOT affect the security of your web server or PHP applications, only the ability for someone editing a template to execute PHP code. Other changes in this release can be found in the NEWS file.
-
-2.5.0
------
-
-Very minor adjustments since RC2, see the NEWS file for details.
-
-2.5.0-RC2
----------
-
-Many fixes since the RC1 release. This one is as close to production quality as
-they come, so this will be the last release before 2.5.0. The SGML documentation
-files have also been removed from the tarball. If you want them, get them from
-the CVS repository.
-
-2.5.0-RC1
----------
-
-Release Candidate 1. All $smarty vars can now be dynamic, such as
-$smarty.get.$foo. A new class function get_function_object() gets you a
-reference to an assigned object, useful within your own custom functions.
-append() can now merge as well as append with a third optional attribute. A new
-class function get_config_vars() was added, and get_template_vars() can now be
-used to get individual vars. Full variable syntax is now supported within
-double quotes via a backtick (`) syntax. Files created by smarty are now
-written to a tmp file then renamed to avoid file lock retention. html_radios,
-html_checkboxes, html_table, html_image, nl2br functions added, see the NEWS
-file for full details.
-
-2.4.2
------
-Another point release. Added support for dynamic object reference syntax
-($foo->$bar), support for full variable syntax within quotes ("$foo[0].bar"),
-and other minor fixes. See the NEWS file for full details.
-
-2.4.1
------
-
-This is basically a point release, cleaning up a few things caught
-in the 2.4.0 release. See the NEWS file for full details.
-
-2.4.0
------
-
-Smarty now supports the ability to access objects within the templates. Two
-methods are available, one which closely follows Smartys conventions, and
-another that follows more traditional object syntax for those familiar with
-PHP.
-
-The internal compiling engine has also undergone some major work. The regex
-parsing was rewritten to be much more strict, more secure and more
-maintainable. Config files are now compiled, which can speed up pages quite a
-bit that use config files extensively. Assigned variables are no longer
-extracted to PHP namespace, saving an extract call for every template. There is
-now support for applying modifiers to static values and functions. You can now
-access constants with $smarty.const.VAR. See the NEWS file for complete
-changes.
-
-2.3.1
------
-
-The mtime on compiled files will now match the source files, in the case where
-the source file may not get the current timestamp, recompiling will still work
-as expected. Proper support for open_basedir has been added, so Smarty should
-work correctly in safe mode. Added a few new features such as textformat block
-function, strip variable modifier and optgroup support for html_options. Also
-other minor bug fixes, see the Change Log.
-
-2.3.0
------
-
-Smarty now has a {debug} template function that brings up the debugging console
-right where {debug} is called, regardless of $debugging settings. This works a
-little different than turning on $debugging in the sense that it shows all the
-template variables available at the time {debug} is called, including local
-scope vars. It does not show the templates names however, since this
-executed during runtime of the template.
-
-You can now supply an expire time when clearing cache or compile files. This is
-mostly useful for removing stale files via the API.
-
-Plugins now stop execution upon error, instead of outputting a warning and
-continuing.
-
-Two new API functions, assign_by_ref() and append_by_ref() were added. They
-allow assigning template variables by reference. This can make a significant
-performance gain, especially if you are assigning large arrays of data. PHP 5.0
-will do this implicitly, so these functions are basically workarounds.
-
-Several misc bug fixes, see the Change Log for information.
-
-
-2.2.0
------
-
-Smarty now allows an array of paths for the $plugin_dir class variable. The
-directories will be searched in the order they are given, so for efficiency keep
-the most-used plugins at the top. Also, absolute paths to the plugin directories are
-more efficient than relying on the PHP include_path.
-
-Cache files can now be grouped with the cache_id. See the documentation under
-the new "Caching" section for details. compile_id also respects the same
-grouping syntax. The cache/compile file structure changed, so be sure to clear
-out all your cache and compile files when upgrading Smarty. Also if you are
-using PHP-accelerator, restart apache. I've seen some quirky things happen if
-the phpa files do not get cleared (known issue with phpa and parent
-class-member changes, so just clear 'em.)
-
-Smarty now correctly respects the PHP include_path for $template_dir, $compile_dir,
-$cache_dir, $config_dir and $plugin_dir. Be aware that relying on the
-include_path is an overhead, try to use absolute pathnames when possible
-(or relative to working directory.)
-
-Documentation has been updated and rearranged a bit. Most notably, the
-installation instructions are completely revamped, and a new Caching section
-explains Smarty's caching in detail along with the new grouping functionality.
-
-Many misc. bug fixes and enhancements, see the full ChangeLog (NEWS file) for
-details.
-
-2.1.1
------
-
-There was a bug with template paths and the include_path, this has been fixed.
-Also register_outputfilter() did not work, this is fixed. A new template
-function named "cycle" has been added to the distribution, nice for cycling
-through a list (or array) of values.
-
-2.1.0
------
-
-This release has quite a few new features and fixes. Most notable are the
-introduction of block functions, so you can write plugins that work on a block
-of text with {func}{/func} notation. Also output filters were added, so you can
-apply a function against the output of your templates. This differs from the
-postfilter function, which works on the compiled template at compile time, and
-output filters work on the template output at runtime.
-
-Many other features and bug fixes are noted in the NEWS file.
-
-
-2.0.1
------
-
-This is a point release, fixing a few bugs and cleaning things up. A plugin
-was renamed, the dash "-" was removed from compiled template and cached file
-names. If you're upgrading, you might want to clear them out first. See the
-ChangeLog for details.
-
-2.0.0
------
-
-This release is a huge milestone for Smarty. Most notable new things are a
-plugin architecture, removal of PEAR dependency, and optimizations that
-drastically improve the performance of Smarty in most cases.
-
-The plugin architecture allows modifiers, custom functions, compiler functions,
-prefilters, postfilters, resources, and insert functions to be added by
-simply dropping a file into the plugins directory. Once dropped in, they are
-automatically registered by the template engine. This makes user-contributed
-plugins easy to manage, as well as the internal workings of Smarty easy to
-control and customize. This new architecture depends on the __FILE__ constant,
-which contains the full path to the executing script. Some older versions of
-PHP incorrectly gave the script name and not the full filesystem path. Be sure
-your version of PHP populates __FILE__ correctly. If you use custom template
-resource functions, the format of these changed with the plugin architecture.
-Be sure to update your functions accordingly. See the template resource section
-of the documentation.
-
-The PEAR dependancy was removed from Smarty. The Config_File class that comes
-with Smarty was actually what needed PEAR for error handling which Smarty didn't
-use, but now everything is self-contained.
-
-Performance improvements are graphed on the benchmark page, you will see that
-overall performance has been sped up by as much as 80% in some cases.
-
-Smarty-cached pages now support If-Modified-Since headers, meaning that if a
-cached template page has not changed since the last request, a "304 Not
-Modified" header will be sent instead of resending the same page. This is
-disabled by default, change the setting of $cache_modified_check.
-
-
-1.5.2
------
-
-Mostly bug fixes, added a default template resource handler.
-
-
-1.5.1
------
-
-Critical bug fix release. If you use caching, you'll need to upgrade.
-
-
-1.5.0
------
-
-Several feature enhancements were made to this version, most notably the
-{foreach ...} command which is an alternative to {section ...} with an easier
-syntax for looping through a single array of values. Several functions were
-enhanced so that the output can be automatically assigned to a template
-variable instead of displayed (assign attribute). Cache files can now be
-controlled with a custom function as an alternative to the built-in file based
-method. Many code cleanups and bug fixed went into this release as well.
-
-
-1.4.6
------
-
-The behavior with caching and compile_check has been slightly enhanced. If
-caching is enabled AND compile_check is enabled, the cache will immediately get
-regenerated if _any_ involved template or config file is updated. This imposes
-a slight performance hit because it must check all the files for changes, so be
-sure to run live sites with caching enabled and compile_check disabled for best
-performance. If you update a template or config file, simply turn on
-compile_check, load the page, then turn it back off. This will update the cache
-file with the new content. This is accomplished by maintaining a list of
-included/loaded templates and config files at the beginning of the cache file.
-Therefore it is advisable to remove all cache files after upgrading to 1.4.6
-(although not absolutely necessary, old cache files will regenerate)
-
-The debug console now has script timing and array values printed. You MUST
-update your debug.tpl file with this version of Smarty. Also, the new debug.tpl
-will not work with older versions of Smarty.
-
-
-1.4.5
------
-
-Mostly bug fixes and minor improvements. Added compile id for separate compiled
-versions of the same script. The directory format and filename convention for
-the files in templates_c has changed, so you may want to remove all of the
-existing ones before you upgrade.
-
-
-1.4.4
------
-
-A few bug fixes, new section looping attributes and properties, debugging
-console function for control via URL, and overLib integration and access
-to request variables from within the template.
-
-
-1.4.3
------
-
-This release has a few bug fixes and several enhancements. Smarty now supports
-template security for third-party template editing. These features disallow the
-ability for someone to execute commands or PHP code from the template language.
-Smarty also now has a built-in debugging console, which is a javascript pop-up
-window that displays all the included template names and assigned variables.
-
-
-1.4.2
------
-
-This was mostly one bug fix with variable scoping within included templates
-and a few documentation changes and updates. See the ChangeLog file for full
-details.
-
-
-1.4.1
------
-
-It seems that the EX_LOCK logic from the previous release didn't fix all the
-problems with windows platforms. Hopefully this one does. It basically
-disables file locking on windows, so there is a potential that two programs
-could write over the same file at the same time, fyi.
-
-The reset is minor bug fixes, please refer to the ChangeLog file.
-
-
-1.4.0
------
-
-IMPORTANT NOTICE
-
-Smarty now has a new syntax for accessing elements within section loops. The
-new syntax is easier to use and nicely handles data structures of any
-complexity. Consequently, this breaks the old syntax.
-
-Here is an example of the syntax change:
-
-old syntax:
-{$sec1/sec2/sec3/customer.phone}
-
-new syntax:
-{$customer[$sec1][$sec2][$sec3].phone}
-
-The section names used to come first, followed by the variable name. Now the
-variable name always comes first, followed by the section names in brackets.
-You can access variable indexes anywhere, depending on how you passed the
-variables in.
-
-To fix your current templates, we have provided a script that will adjust the
-syntax for you. Located in misc/fix_vars.php, run this script from the the
-command line, giving each template as an argument. Be sure to use absolute
-pathnames, or pathnames relative to the executing script. Probably the easiest
-way to do this is to copy the fix_vars.php script into your template directory
-and run 'php -q fix_vars.php *.tpl' Be sure you have proper write permission,
-and backup your scripts first to be safe! The examples in the 1.4.0
-documentation have been updated to reflect the changes.
-
-cd /path/to/templates
-cp /path/to/fix_vars.php .
-find . -name "*.tpl" -exec php -q ./fix_vars.php {} \;
-
-NEW AND IMPROVED COMPILATION PROCESS
-
-Smarty 1.4.0 also has a new compilation process. Instead of compiling all the
-templates up front, it now compiles them at runtime. This has several
-advantages. First of all, there is no longer a need to have a single template
-directory. You can now have arbitrary template sources, such as multiple
-directories or even database calls. This also speeds the performance of Smarty
-when $compile_check is enabled, since it is only checking the template that is
-being executed instead of everything found in the template directory. The
-$tpl_file_ext is no longer needed, but kept for backward compatability.
-Templates can now be named anything you like with any extension.
-
-MINOR FIXES
-
-A workaround for LOCK_EX on Windows systems was added, and changed a couple of
-file permissions for better security on public servers.
-
-$show_info_header is now defaulted to false instead of true. This header causes
-problems when displaying content other than HTML, so now you must explicitly
-set this flag to true to show the header information (or change the default in
-your copy of Smarty.)
-
-Documentation is written in docbook format. I updated the docbook -> HTML
-generating software & style-sheets, and consequently the examples are no longer
-in a different background color. If anyone wants to contribute a better
-stylesheet or help with documentation, drop me a line. <monte at ohrt dot com>
-
-CHANGES/ENHANCEMENTS/UPDATES
-
-date_format, html_select_date and html_select_time used to require a unix
-timestamp as the format of the date passed into the template. Smarty is now a
-bit smarter at this. It will take a unix timestamp, a mysql timestamp, or any
-date string that is parsable by strtotime, such as 10/01/2001 or 2001-10-01,
-etc. Just give some formats a try and see what works.
-
-Smarty now has template prefilters, meaning that you can run your templates
-through custom functions before they are compiled. This is good for things like
-removing unwanted comments, keeping an eye on words or functionality people are
-putting in templates, translating XML -> HTML, etc. See the register_prefilter
-documentation for more info.
-
-Another addition are the so-called compiler functions. These are custom
-functions registered by the user that are executed at compilation time of the
-template. They can be used to inject PHP code or time-sensitive static content
-into the compiled template.
-
-The run-time custom functions are now passed the Smarty object as the second
-parameter. This can be used, for example, to assign or clear template variables
-from inside the custom function.
-
-clear_compile_dir() was added for clearing out compiled versions of your
-templates. Not something normally needed, but you may have a need for this if
-you have $compile_check set to false and you periodically update templates via
-some automated process. As of 1.4.0, uncompiled templates _always_ get
-compiled regardless of $compile_check setting, although they won't be checked
-for recompile if $compile_check is set to false.
-
-You can now refer to properties of objects assigned from PHP by using the '->'
-symbol and specifying the property name after it, e.g. $foo->bar.
-
-{php}{/php} tags were added to embed php into the templates. Not normally
-needed, but some circumstances may call for it. Check out the "componentized
-templates" tip in the documentation for an example.
-
-{capture}{/capture} and {counter} functions were added. See the documentation
-for a complete description and examples.
-
-UPGRADE NOTES
-
-The format of the files created in the $compile_dir are now a bit different.
-The compiled template filename is the template resource name url-encoded.
-Therefore, all compiled files are now in the top directory of $compile_dir.
-This was done to make way for arbitrary template resources. Each compiled
-template also has a header that states what template resource was used to
-create it. From a unix command prompt, you can use "head -2 *" to see the first
-two lines of each file.
-
-When upgrading to 1.4.0, you will want to clear out all your old files in the
-$compile_dir. If you have $compile_check set to false and the compiled template
-does not yet exist, it will compile it regardless of this setting. This way you
-can clear out the $compile_dir and not worry about setting $compile_check to
-true to get the inital compilation under way.
-
-
-1.3.2
------
-
-Smarty now has (an optional) header prepended to the output of the Smarty
-templates. This displays the Smarty version and the date/time when the page was
-generated. This is useful for debugging your cache routines, and purely
-informational so there is evidence that the page was generated by Smarty. Set
-$show_info_header to false to disable it.
-
-{config_load ...} performance was tuned by placing the loaded variables into a
-global array, so basically a config file is read from the file system and
-placed into a php array structure only once, no matter how many times it is
-called in any of the templates. The scope of the loaded variables has changed a
-bit as well. Variables loaded by config_load used to be treated as global
-variables, meaning that parent templates (templates that included the current
-template) could see them. Now the default behavior is such that loaded
-variables are only visible by the current template and child templates (all
-templates included after the {config_load ...} is called.) To mimic the
-original behavior, provide the attribute "global=yes" like so: {config_load
-file="mystuff.conf" global=yes}. Now when you load in mystuff.conf, the
-variables will be visible to parent templates (merged with any existing config
-variables.)
-
-A formatting attribute was added to the {math ...} function, adding the ability
-to control the format of the output. Use the same formatting syntax as the PHP
-function sprintf().
-
-{html_select_time ...} was added, a custom function that works much like
-{html_select_date ...} except it displays time elements instead of dates.
-
-A few custom modifiers were added: count_characters, count_words,
-count_sentences, count_paragraphs. All pretty self-explanatory.
-
-/* vim: set et: */
+++ /dev/null
-* handle asp style tags in $php_handler
-* fix all E_NOTICE warnings
-* make simple math easier
-* caching all but parts of the template
-* change plugins so $smarty variable always comes first
-* get cache ttl with function call
-FIX: make inserts use normal functions before plugins
-UPD: change it so that if template comes from some resource,
- that resource stays as the default, no need to specify it
- in includes.
+++ /dev/null
-title = Welcome to Smarty!
-cutoff_size = 40
-
-[setup]
-bold = true
+++ /dev/null
-<?php
-
-require '../libs/Smarty.class.php';
-
-$smarty = new Smarty;
-
-$smarty->compile_check = true;
-$smarty->debugging = true;
-
-$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill");
-$smarty->assign("FirstName",array("John","Mary","James","Henry"));
-$smarty->assign("LastName",array("Doe","Smith","Johnson","Case"));
-$smarty->assign("Class",array(array("A","B","C","D"), array("E", "F", "G", "H"),
- array("I", "J", "K", "L"), array("M", "N", "O", "P")));
-
-$smarty->assign("contacts", array(array("phone" => "1", "fax" => "2", "cell" => "3"),
- array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234")));
-
-$smarty->assign("option_values", array("NY","NE","KS","IA","OK","TX"));
-$smarty->assign("option_output", array("New York","Nebraska","Kansas","Iowa","Oklahoma","Texas"));
-$smarty->assign("option_selected", "NE");
-
-$smarty->display('index.tpl');
-
-?>
+++ /dev/null
-</BODY>
-</HTML>
+++ /dev/null
-<HTML>
-<HEAD>
-{popup_init src="/javascripts/overlib.js"}
-<TITLE>{$title} - {$Name}</TITLE>
-</HEAD>
-<BODY bgcolor="#ffffff">
+++ /dev/null
-{config_load file=test.conf section="setup"}
-{include file="header.tpl" title=foo}
-
-<PRE>
-
-{* bold and title are read from the config file *}
-{if #bold#}<b>{/if}
-{* capitalize the first letters of each word of the title *}
-Title: {#title#|capitalize}
-{if #bold#}</b>{/if}
-
-The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
-
-The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
-
-Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
-
-The value of {ldelim}$Name{rdelim} is <b>{$Name}</b>
-
-variable modifier example of {ldelim}$Name|upper{rdelim}
-
-<b>{$Name|upper}</b>
-
-
-An example of a section loop:
-
-{section name=outer loop=$FirstName}
-{if $smarty.section.outer.index is odd by 2}
- {$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
-{else}
- {$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
-{/if}
-{sectionelse}
- none
-{/section}
-
-An example of section looped key values:
-
-{section name=sec1 loop=$contacts}
- phone: {$contacts[sec1].phone}<br>
- fax: {$contacts[sec1].fax}<br>
- cell: {$contacts[sec1].cell}<br>
-{/section}
-<p>
-
-testing strip tags
-{strip}
-<table border=0>
- <tr>
- <td>
- <A HREF="{$SCRIPT_NAME}">
- <font color="red">This is a test </font>
- </A>
- </td>
- </tr>
-</table>
-{/strip}
-
-</PRE>
-
-This is an example of the html_select_date function:
-
-<form>
-{html_select_date start_year=1998 end_year=2010}
-</form>
-
-This is an example of the html_select_time function:
-
-<form>
-{html_select_time use_24_hours=false}
-</form>
-
-This is an example of the html_options function:
-
-<form>
-<select name=states>
-{html_options values=$option_values selected=$option_selected output=$option_output}
-</select>
-</form>
-
-{include file="footer.tpl"}
+++ /dev/null
-<?php
-
-/**
- * Config_File class.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For questions, help, comments, discussion, etc., please join the
- * Smarty mailing list. Send a blank e-mail to
- * smarty-discussion-subscribe@googlegroups.com
- *
- * @link http://www.smarty.net/
- * @version 2.6.26
- * @copyright Copyright: 2001-2005 New Digital Group, Inc.
- * @author Andrei Zmievski <andrei@php.net>
- * @access public
- * @package Smarty
- */
-
-/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */
-
-/**
- * Config file reading class
- * @package Smarty
- */
-class Config_File {
- /**#@+
- * Options
- * @var boolean
- */
- /**
- * Controls whether variables with the same name overwrite each other.
- */
- var $overwrite = true;
-
- /**
- * Controls whether config values of on/true/yes and off/false/no get
- * converted to boolean values automatically.
- */
- var $booleanize = true;
-
- /**
- * Controls whether hidden config sections/vars are read from the file.
- */
- var $read_hidden = true;
-
- /**
- * Controls whether or not to fix mac or dos formatted newlines.
- * If set to true, \r or \r\n will be changed to \n.
- */
- var $fix_newlines = true;
- /**#@-*/
-
- /** @access private */
- var $_config_path = "";
- var $_config_data = array();
- /**#@-*/
-
- /**
- * Constructs a new config file class.
- *
- * @param string $config_path (optional) path to the config files
- */
- function Config_File($config_path = NULL)
- {
- if (isset($config_path))
- $this->set_path($config_path);
- }
-
-
- /**
- * Set the path where configuration files can be found.
- *
- * @param string $config_path path to the config files
- */
- function set_path($config_path)
- {
- if (!empty($config_path)) {
- if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
- $this->_trigger_error_msg("Bad config file path '$config_path'");
- return;
- }
- if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
- $config_path .= DIRECTORY_SEPARATOR;
- }
-
- $this->_config_path = $config_path;
- }
- }
-
-
- /**
- * Retrieves config info based on the file, section, and variable name.
- *
- * @param string $file_name config file to get info for
- * @param string $section_name (optional) section to get info for
- * @param string $var_name (optional) variable to get info for
- * @return string|array a value or array of values
- */
- function get($file_name, $section_name = NULL, $var_name = NULL)
- {
- if (empty($file_name)) {
- $this->_trigger_error_msg('Empty config file name');
- return;
- } else {
- $file_name = $this->_config_path . $file_name;
- if (!isset($this->_config_data[$file_name]))
- $this->load_file($file_name, false);
- }
-
- if (!empty($var_name)) {
- if (empty($section_name)) {
- return $this->_config_data[$file_name]["vars"][$var_name];
- } else {
- if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
- return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
- else
- return array();
- }
- } else {
- if (empty($section_name)) {
- return (array)$this->_config_data[$file_name]["vars"];
- } else {
- if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
- return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
- else
- return array();
- }
- }
- }
-
-
- /**
- * Retrieves config info based on the key.
- *
- * @param $file_name string config key (filename/section/var)
- * @return string|array same as get()
- * @uses get() retrieves information from config file and returns it
- */
- function &get_key($config_key)
- {
- list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
- $result = &$this->get($file_name, $section_name, $var_name);
- return $result;
- }
-
- /**
- * Get all loaded config file names.
- *
- * @return array an array of loaded config file names
- */
- function get_file_names()
- {
- return array_keys($this->_config_data);
- }
-
-
- /**
- * Get all section names from a loaded file.
- *
- * @param string $file_name config file to get section names from
- * @return array an array of section names from the specified file
- */
- function get_section_names($file_name)
- {
- $file_name = $this->_config_path . $file_name;
- if (!isset($this->_config_data[$file_name])) {
- $this->_trigger_error_msg("Unknown config file '$file_name'");
- return;
- }
-
- return array_keys($this->_config_data[$file_name]["sections"]);
- }
-
-
- /**
- * Get all global or section variable names.
- *
- * @param string $file_name config file to get info for
- * @param string $section_name (optional) section to get info for
- * @return array an array of variables names from the specified file/section
- */
- function get_var_names($file_name, $section = NULL)
- {
- if (empty($file_name)) {
- $this->_trigger_error_msg('Empty config file name');
- return;
- } else if (!isset($this->_config_data[$file_name])) {
- $this->_trigger_error_msg("Unknown config file '$file_name'");
- return;
- }
-
- if (empty($section))
- return array_keys($this->_config_data[$file_name]["vars"]);
- else
- return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
- }
-
-
- /**
- * Clear loaded config data for a certain file or all files.
- *
- * @param string $file_name file to clear config data for
- */
- function clear($file_name = NULL)
- {
- if ($file_name === NULL)
- $this->_config_data = array();
- else if (isset($this->_config_data[$file_name]))
- $this->_config_data[$file_name] = array();
- }
-
-
- /**
- * Load a configuration file manually.
- *
- * @param string $file_name file name to load
- * @param boolean $prepend_path whether current config path should be
- * prepended to the filename
- */
- function load_file($file_name, $prepend_path = true)
- {
- if ($prepend_path && $this->_config_path != "")
- $config_file = $this->_config_path . $file_name;
- else
- $config_file = $file_name;
-
- ini_set('track_errors', true);
- $fp = @fopen($config_file, "r");
- if (!is_resource($fp)) {
- $this->_trigger_error_msg("Could not open config file '$config_file'");
- return false;
- }
-
- $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
- fclose($fp);
-
- $this->_config_data[$config_file] = $this->parse_contents($contents);
- return true;
- }
-
- /**
- * Store the contents of a file manually.
- *
- * @param string $config_file file name of the related contents
- * @param string $contents the file-contents to parse
- */
- function set_file_contents($config_file, $contents)
- {
- $this->_config_data[$config_file] = $this->parse_contents($contents);
- return true;
- }
-
- /**
- * parse the source of a configuration file manually.
- *
- * @param string $contents the file-contents to parse
- */
- function parse_contents($contents)
- {
- if($this->fix_newlines) {
- // fix mac/dos formatted newlines
- $contents = preg_replace('!\r\n?!', "\n", $contents);
- }
-
- $config_data = array();
- $config_data['sections'] = array();
- $config_data['vars'] = array();
-
- /* reference to fill with data */
- $vars =& $config_data['vars'];
-
- /* parse file line by line */
- preg_match_all('!^.*\r?\n?!m', $contents, $match);
- $lines = $match[0];
- for ($i=0, $count=count($lines); $i<$count; $i++) {
- $line = $lines[$i];
- if (empty($line)) continue;
-
- if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
- /* section found */
- if (substr($match[1], 0, 1) == '.') {
- /* hidden section */
- if ($this->read_hidden) {
- $section_name = substr($match[1], 1);
- } else {
- /* break reference to $vars to ignore hidden section */
- unset($vars);
- $vars = array();
- continue;
- }
- } else {
- $section_name = $match[1];
- }
- if (!isset($config_data['sections'][$section_name]))
- $config_data['sections'][$section_name] = array('vars' => array());
- $vars =& $config_data['sections'][$section_name]['vars'];
- continue;
- }
-
- if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
- /* variable found */
- $var_name = rtrim($match[1]);
- if (strpos($match[2], '"""') === 0) {
- /* handle multiline-value */
- $lines[$i] = substr($match[2], 3);
- $var_value = '';
- while ($i<$count) {
- if (($pos = strpos($lines[$i], '"""')) === false) {
- $var_value .= $lines[$i++];
- } else {
- /* end of multiline-value */
- $var_value .= substr($lines[$i], 0, $pos);
- break;
- }
- }
- $booleanize = false;
-
- } else {
- /* handle simple value */
- $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
- $booleanize = $this->booleanize;
-
- }
- $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
- }
- /* else unparsable line / means it is a comment / means ignore it */
- }
- return $config_data;
- }
-
- /**#@+ @access private */
- /**
- * @param array &$container
- * @param string $var_name
- * @param mixed $var_value
- * @param boolean $booleanize determines whether $var_value is converted to
- * to true/false
- */
- function _set_config_var(&$container, $var_name, $var_value, $booleanize)
- {
- if (substr($var_name, 0, 1) == '.') {
- if (!$this->read_hidden)
- return;
- else
- $var_name = substr($var_name, 1);
- }
-
- if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
- $this->_trigger_error_msg("Bad variable name '$var_name'");
- return;
- }
-
- if ($booleanize) {
- if (preg_match("/^(on|true|yes)$/i", $var_value))
- $var_value = true;
- else if (preg_match("/^(off|false|no)$/i", $var_value))
- $var_value = false;
- }
-
- if (!isset($container[$var_name]) || $this->overwrite)
- $container[$var_name] = $var_value;
- else {
- settype($container[$var_name], 'array');
- $container[$var_name][] = $var_value;
- }
- }
-
- /**
- * @uses trigger_error() creates a PHP warning/error
- * @param string $error_msg
- * @param integer $error_type one of
- */
- function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
- {
- trigger_error("Config_File error: $error_msg", $error_type);
- }
- /**#@-*/
-}
-
-?>
+++ /dev/null
-<?php
-
-/**
- * Project: Smarty: the PHP compiling template engine
- * File: Smarty.class.php
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For questions, help, comments, discussion, etc., please join the
- * Smarty mailing list. Send a blank e-mail to
- * smarty-discussion-subscribe@googlegroups.com
- *
- * @link http://www.smarty.net/
- * @copyright 2001-2005 New Digital Group, Inc.
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author Andrei Zmievski <andrei@php.net>
- * @package Smarty
- * @version 2.6.26
- */
-
-/* $Id: Smarty.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
-
-/**
- * DIR_SEP isn't used anymore, but third party apps might
- */
-if(!defined('DIR_SEP')) {
- define('DIR_SEP', DIRECTORY_SEPARATOR);
-}
-
-/**
- * set SMARTY_DIR to absolute path to Smarty library files.
- * if not defined, include_path will be used. Sets SMARTY_DIR only if user
- * application has not already defined it.
- */
-
-if (!defined('SMARTY_DIR')) {
- define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
-}
-
-if (!defined('SMARTY_CORE_DIR')) {
- define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
-}
-
-define('SMARTY_PHP_PASSTHRU', 0);
-define('SMARTY_PHP_QUOTE', 1);
-define('SMARTY_PHP_REMOVE', 2);
-define('SMARTY_PHP_ALLOW', 3);
-
-/**
- * @package Smarty
- */
-class Smarty
-{
- /**#@+
- * Smarty Configuration Section
- */
-
- /**
- * The name of the directory where templates are located.
- *
- * @var string
- */
- var $template_dir = 'templates';
-
- /**
- * The directory where compiled templates are located.
- *
- * @var string
- */
- var $compile_dir = 'templates_c';
-
- /**
- * The directory where config files are located.
- *
- * @var string
- */
- var $config_dir = 'configs';
-
- /**
- * An array of directories searched for plugins.
- *
- * @var array
- */
- var $plugins_dir = array('plugins');
-
- /**
- * If debugging is enabled, a debug console window will display
- * when the page loads (make sure your browser allows unrequested
- * popup windows)
- *
- * @var boolean
- */
- var $debugging = false;
-
- /**
- * When set, smarty does uses this value as error_reporting-level.
- *
- * @var integer
- */
- var $error_reporting = null;
-
- /**
- * This is the path to the debug console template. If not set,
- * the default one will be used.
- *
- * @var string
- */
- var $debug_tpl = '';
-
- /**
- * This determines if debugging is enable-able from the browser.
- * <ul>
- * <li>NONE => no debugging control allowed</li>
- * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
- * </ul>
- * @link http://www.foo.dom/index.php?SMARTY_DEBUG
- * @var string
- */
- var $debugging_ctrl = 'NONE';
-
- /**
- * This tells Smarty whether to check for recompiling or not. Recompiling
- * does not need to happen unless a template or config file is changed.
- * Typically you enable this during development, and disable for
- * production.
- *
- * @var boolean
- */
- var $compile_check = true;
-
- /**
- * This forces templates to compile every time. Useful for development
- * or debugging.
- *
- * @var boolean
- */
- var $force_compile = false;
-
- /**
- * This enables template caching.
- * <ul>
- * <li>0 = no caching</li>
- * <li>1 = use class cache_lifetime value</li>
- * <li>2 = use cache_lifetime in cache file</li>
- * </ul>
- * @var integer
- */
- var $caching = 0;
-
- /**
- * The name of the directory for cache files.
- *
- * @var string
- */
- var $cache_dir = 'cache';
-
- /**
- * This is the number of seconds cached content will persist.
- * <ul>
- * <li>0 = always regenerate cache</li>
- * <li>-1 = never expires</li>
- * </ul>
- *
- * @var integer
- */
- var $cache_lifetime = 3600;
-
- /**
- * Only used when $caching is enabled. If true, then If-Modified-Since headers
- * are respected with cached content, and appropriate HTTP headers are sent.
- * This way repeated hits to a cached page do not send the entire page to the
- * client every time.
- *
- * @var boolean
- */
- var $cache_modified_check = false;
-
- /**
- * This determines how Smarty handles "<?php ... ?>" tags in templates.
- * possible values:
- * <ul>
- * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
- * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li>
- * <li>SMARTY_PHP_REMOVE -> remove php tags</li>
- * <li>SMARTY_PHP_ALLOW -> execute php tags</li>
- * </ul>
- *
- * @var integer
- */
- var $php_handling = SMARTY_PHP_PASSTHRU;
-
- /**
- * This enables template security. When enabled, many things are restricted
- * in the templates that normally would go unchecked. This is useful when
- * untrusted parties are editing templates and you want a reasonable level
- * of security. (no direct execution of PHP in templates for example)
- *
- * @var boolean
- */
- var $security = false;
-
- /**
- * This is the list of template directories that are considered secure. This
- * is used only if {@link $security} is enabled. One directory per array
- * element. {@link $template_dir} is in this list implicitly.
- *
- * @var array
- */
- var $secure_dir = array();
-
- /**
- * These are the security settings for Smarty. They are used only when
- * {@link $security} is enabled.
- *
- * @var array
- */
- var $security_settings = array(
- 'PHP_HANDLING' => false,
- 'IF_FUNCS' => array('array', 'list',
- 'isset', 'empty',
- 'count', 'sizeof',
- 'in_array', 'is_array',
- 'true', 'false', 'null'),
- 'INCLUDE_ANY' => false,
- 'PHP_TAGS' => false,
- 'MODIFIER_FUNCS' => array('count'),
- 'ALLOW_CONSTANTS' => false,
- 'ALLOW_SUPER_GLOBALS' => true
- );
-
- /**
- * This is an array of directories where trusted php scripts reside.
- * {@link $security} is disabled during their inclusion/execution.
- *
- * @var array
- */
- var $trusted_dir = array();
-
- /**
- * The left delimiter used for the template tags.
- *
- * @var string
- */
- var $left_delimiter = '{';
-
- /**
- * The right delimiter used for the template tags.
- *
- * @var string
- */
- var $right_delimiter = '}';
-
- /**
- * The order in which request variables are registered, similar to
- * variables_order in php.ini E = Environment, G = GET, P = POST,
- * C = Cookies, S = Server
- *
- * @var string
- */
- var $request_vars_order = 'EGPCS';
-
- /**
- * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
- * are uses as request-vars or $_*[]-vars. note: if
- * request_use_auto_globals is true, then $request_vars_order has
- * no effect, but the php-ini-value "gpc_order"
- *
- * @var boolean
- */
- var $request_use_auto_globals = true;
-
- /**
- * Set this if you want different sets of compiled files for the same
- * templates. This is useful for things like different languages.
- * Instead of creating separate sets of templates per language, you
- * set different compile_ids like 'en' and 'de'.
- *
- * @var string
- */
- var $compile_id = null;
-
- /**
- * This tells Smarty whether or not to use sub dirs in the cache/ and
- * templates_c/ directories. sub directories better organized, but
- * may not work well with PHP safe mode enabled.
- *
- * @var boolean
- *
- */
- var $use_sub_dirs = false;
-
- /**
- * This is a list of the modifiers to apply to all template variables.
- * Put each modifier in a separate array element in the order you want
- * them applied. example: <code>array('escape:"htmlall"');</code>
- *
- * @var array
- */
- var $default_modifiers = array();
-
- /**
- * This is the resource type to be used when not specified
- * at the beginning of the resource path. examples:
- * $smarty->display('file:index.tpl');
- * $smarty->display('db:index.tpl');
- * $smarty->display('index.tpl'); // will use default resource type
- * {include file="file:index.tpl"}
- * {include file="db:index.tpl"}
- * {include file="index.tpl"} {* will use default resource type *}
- *
- * @var array
- */
- var $default_resource_type = 'file';
-
- /**
- * The function used for cache file handling. If not set, built-in caching is used.
- *
- * @var null|string function name
- */
- var $cache_handler_func = null;
-
- /**
- * This indicates which filters are automatically loaded into Smarty.
- *
- * @var array array of filter names
- */
- var $autoload_filters = array();
-
- /**#@+
- * @var boolean
- */
- /**
- * This tells if config file vars of the same name overwrite each other or not.
- * if disabled, same name variables are accumulated in an array.
- */
- var $config_overwrite = true;
-
- /**
- * This tells whether or not to automatically booleanize config file variables.
- * If enabled, then the strings "on", "true", and "yes" are treated as boolean
- * true, and "off", "false" and "no" are treated as boolean false.
- */
- var $config_booleanize = true;
-
- /**
- * This tells whether hidden sections [.foobar] are readable from the
- * tempalates or not. Normally you would never allow this since that is
- * the point behind hidden sections: the application can access them, but
- * the templates cannot.
- */
- var $config_read_hidden = false;
-
- /**
- * This tells whether or not automatically fix newlines in config files.
- * It basically converts \r (mac) or \r\n (dos) to \n
- */
- var $config_fix_newlines = true;
- /**#@-*/
-
- /**
- * If a template cannot be found, this PHP function will be executed.
- * Useful for creating templates on-the-fly or other special action.
- *
- * @var string function name
- */
- var $default_template_handler_func = '';
-
- /**
- * The file that contains the compiler class. This can a full
- * pathname, or relative to the php_include path.
- *
- * @var string
- */
- var $compiler_file = 'Smarty_Compiler.class.php';
-
- /**
- * The class used for compiling templates.
- *
- * @var string
- */
- var $compiler_class = 'Smarty_Compiler';
-
- /**
- * The class used to load config vars.
- *
- * @var string
- */
- var $config_class = 'Config_File';
-
-/**#@+
- * END Smarty Configuration Section
- * There should be no need to touch anything below this line.
- * @access private
- */
- /**
- * where assigned template vars are kept
- *
- * @var array
- */
- var $_tpl_vars = array();
-
- /**
- * stores run-time $smarty.* vars
- *
- * @var null|array
- */
- var $_smarty_vars = null;
-
- /**
- * keeps track of sections
- *
- * @var array
- */
- var $_sections = array();
-
- /**
- * keeps track of foreach blocks
- *
- * @var array
- */
- var $_foreach = array();
-
- /**
- * keeps track of tag hierarchy
- *
- * @var array
- */
- var $_tag_stack = array();
-
- /**
- * configuration object
- *
- * @var Config_file
- */
- var $_conf_obj = null;
-
- /**
- * loaded configuration settings
- *
- * @var array
- */
- var $_config = array(array('vars' => array(), 'files' => array()));
-
- /**
- * md5 checksum of the string 'Smarty'
- *
- * @var string
- */
- var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f';
-
- /**
- * Smarty version number
- *
- * @var string
- */
- var $_version = '2.6.26';
-
- /**
- * current template inclusion depth
- *
- * @var integer
- */
- var $_inclusion_depth = 0;
-
- /**
- * for different compiled templates
- *
- * @var string
- */
- var $_compile_id = null;
-
- /**
- * text in URL to enable debug mode
- *
- * @var string
- */
- var $_smarty_debug_id = 'SMARTY_DEBUG';
-
- /**
- * debugging information for debug console
- *
- * @var array
- */
- var $_smarty_debug_info = array();
-
- /**
- * info that makes up a cache file
- *
- * @var array
- */
- var $_cache_info = array();
-
- /**
- * default file permissions
- *
- * @var integer
- */
- var $_file_perms = 0644;
-
- /**
- * default dir permissions
- *
- * @var integer
- */
- var $_dir_perms = 0771;
-
- /**
- * registered objects
- *
- * @var array
- */
- var $_reg_objects = array();
-
- /**
- * table keeping track of plugins
- *
- * @var array
- */
- var $_plugins = array(
- 'modifier' => array(),
- 'function' => array(),
- 'block' => array(),
- 'compiler' => array(),
- 'prefilter' => array(),
- 'postfilter' => array(),
- 'outputfilter' => array(),
- 'resource' => array(),
- 'insert' => array());
-
-
- /**
- * cache serials
- *
- * @var array
- */
- var $_cache_serials = array();
-
- /**
- * name of optional cache include file
- *
- * @var string
- */
- var $_cache_include = null;
-
- /**
- * indicate if the current code is used in a compiled
- * include
- *
- * @var string
- */
- var $_cache_including = false;
-
- /**#@-*/
- /**
- * The class constructor.
- */
- function Smarty()
- {
- $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
- : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
- }
-
- /**
- * assigns values to template variables
- *
- * @param array|string $tpl_var the template variable name(s)
- * @param mixed $value the value to assign
- */
- function assign($tpl_var, $value = null)
- {
- if (is_array($tpl_var)){
- foreach ($tpl_var as $key => $val) {
- if ($key != '') {
- $this->_tpl_vars[$key] = $val;
- }
- }
- } else {
- if ($tpl_var != '')
- $this->_tpl_vars[$tpl_var] = $value;
- }
- }
-
- /**
- * assigns values to template variables by reference
- *
- * @param string $tpl_var the template variable name
- * @param mixed $value the referenced value to assign
- */
- function assign_by_ref($tpl_var, &$value)
- {
- if ($tpl_var != '')
- $this->_tpl_vars[$tpl_var] = &$value;
- }
-
- /**
- * appends values to template variables
- *
- * @param array|string $tpl_var the template variable name(s)
- * @param mixed $value the value to append
- */
- function append($tpl_var, $value=null, $merge=false)
- {
- if (is_array($tpl_var)) {
- // $tpl_var is an array, ignore $value
- foreach ($tpl_var as $_key => $_val) {
- if ($_key != '') {
- if(!@is_array($this->_tpl_vars[$_key])) {
- settype($this->_tpl_vars[$_key],'array');
- }
- if($merge && is_array($_val)) {
- foreach($_val as $_mkey => $_mval) {
- $this->_tpl_vars[$_key][$_mkey] = $_mval;
- }
- } else {
- $this->_tpl_vars[$_key][] = $_val;
- }
- }
- }
- } else {
- if ($tpl_var != '' && isset($value)) {
- if(!@is_array($this->_tpl_vars[$tpl_var])) {
- settype($this->_tpl_vars[$tpl_var],'array');
- }
- if($merge && is_array($value)) {
- foreach($value as $_mkey => $_mval) {
- $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
- }
- } else {
- $this->_tpl_vars[$tpl_var][] = $value;
- }
- }
- }
- }
-
- /**
- * appends values to template variables by reference
- *
- * @param string $tpl_var the template variable name
- * @param mixed $value the referenced value to append
- */
- function append_by_ref($tpl_var, &$value, $merge=false)
- {
- if ($tpl_var != '' && isset($value)) {
- if(!@is_array($this->_tpl_vars[$tpl_var])) {
- settype($this->_tpl_vars[$tpl_var],'array');
- }
- if ($merge && is_array($value)) {
- foreach($value as $_key => $_val) {
- $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
- }
- } else {
- $this->_tpl_vars[$tpl_var][] = &$value;
- }
- }
- }
-
-
- /**
- * clear the given assigned template variable.
- *
- * @param string $tpl_var the template variable to clear
- */
- function clear_assign($tpl_var)
- {
- if (is_array($tpl_var))
- foreach ($tpl_var as $curr_var)
- unset($this->_tpl_vars[$curr_var]);
- else
- unset($this->_tpl_vars[$tpl_var]);
- }
-
-
- /**
- * Registers custom function to be used in templates
- *
- * @param string $function the name of the template function
- * @param string $function_impl the name of the PHP function to register
- */
- function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
- {
- $this->_plugins['function'][$function] =
- array($function_impl, null, null, false, $cacheable, $cache_attrs);
-
- }
-
- /**
- * Unregisters custom function
- *
- * @param string $function name of template function
- */
- function unregister_function($function)
- {
- unset($this->_plugins['function'][$function]);
- }
-
- /**
- * Registers object to be used in templates
- *
- * @param string $object name of template object
- * @param object &$object_impl the referenced PHP object to register
- * @param null|array $allowed list of allowed methods (empty = all)
- * @param boolean $smarty_args smarty argument format, else traditional
- * @param null|array $block_functs list of methods that are block format
- */
- function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
- {
- settype($allowed, 'array');
- settype($smarty_args, 'boolean');
- $this->_reg_objects[$object] =
- array(&$object_impl, $allowed, $smarty_args, $block_methods);
- }
-
- /**
- * Unregisters object
- *
- * @param string $object name of template object
- */
- function unregister_object($object)
- {
- unset($this->_reg_objects[$object]);
- }
-
-
- /**
- * Registers block function to be used in templates
- *
- * @param string $block name of template block
- * @param string $block_impl PHP function to register
- */
- function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
- {
- $this->_plugins['block'][$block] =
- array($block_impl, null, null, false, $cacheable, $cache_attrs);
- }
-
- /**
- * Unregisters block function
- *
- * @param string $block name of template function
- */
- function unregister_block($block)
- {
- unset($this->_plugins['block'][$block]);
- }
-
- /**
- * Registers compiler function
- *
- * @param string $function name of template function
- * @param string $function_impl name of PHP function to register
- */
- function register_compiler_function($function, $function_impl, $cacheable=true)
- {
- $this->_plugins['compiler'][$function] =
- array($function_impl, null, null, false, $cacheable);
- }
-
- /**
- * Unregisters compiler function
- *
- * @param string $function name of template function
- */
- function unregister_compiler_function($function)
- {
- unset($this->_plugins['compiler'][$function]);
- }
-
- /**
- * Registers modifier to be used in templates
- *
- * @param string $modifier name of template modifier
- * @param string $modifier_impl name of PHP function to register
- */
- function register_modifier($modifier, $modifier_impl)
- {
- $this->_plugins['modifier'][$modifier] =
- array($modifier_impl, null, null, false);
- }
-
- /**
- * Unregisters modifier
- *
- * @param string $modifier name of template modifier
- */
- function unregister_modifier($modifier)
- {
- unset($this->_plugins['modifier'][$modifier]);
- }
-
- /**
- * Registers a resource to fetch a template
- *
- * @param string $type name of resource
- * @param array $functions array of functions to handle resource
- */
- function register_resource($type, $functions)
- {
- if (count($functions)==4) {
- $this->_plugins['resource'][$type] =
- array($functions, false);
-
- } elseif (count($functions)==5) {
- $this->_plugins['resource'][$type] =
- array(array(array(&$functions[0], $functions[1])
- ,array(&$functions[0], $functions[2])
- ,array(&$functions[0], $functions[3])
- ,array(&$functions[0], $functions[4]))
- ,false);
-
- } else {
- $this->trigger_error("malformed function-list for '$type' in register_resource");
-
- }
- }
-
- /**
- * Unregisters a resource
- *
- * @param string $type name of resource
- */
- function unregister_resource($type)
- {
- unset($this->_plugins['resource'][$type]);
- }
-
- /**
- * Registers a prefilter function to apply
- * to a template before compiling
- *
- * @param callback $function
- */
- function register_prefilter($function)
- {
- $this->_plugins['prefilter'][$this->_get_filter_name($function)]
- = array($function, null, null, false);
- }
-
- /**
- * Unregisters a prefilter function
- *
- * @param callback $function
- */
- function unregister_prefilter($function)
- {
- unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
- }
-
- /**
- * Registers a postfilter function to apply
- * to a compiled template after compilation
- *
- * @param callback $function
- */
- function register_postfilter($function)
- {
- $this->_plugins['postfilter'][$this->_get_filter_name($function)]
- = array($function, null, null, false);
- }
-
- /**
- * Unregisters a postfilter function
- *
- * @param callback $function
- */
- function unregister_postfilter($function)
- {
- unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
- }
-
- /**
- * Registers an output filter function to apply
- * to a template output
- *
- * @param callback $function
- */
- function register_outputfilter($function)
- {
- $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
- = array($function, null, null, false);
- }
-
- /**
- * Unregisters an outputfilter function
- *
- * @param callback $function
- */
- function unregister_outputfilter($function)
- {
- unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
- }
-
- /**
- * load a filter of specified type and name
- *
- * @param string $type filter type
- * @param string $name filter name
- */
- function load_filter($type, $name)
- {
- switch ($type) {
- case 'output':
- $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- break;
-
- case 'pre':
- case 'post':
- if (!isset($this->_plugins[$type . 'filter'][$name]))
- $this->_plugins[$type . 'filter'][$name] = false;
- break;
- }
- }
-
- /**
- * clear cached content for the given template and cache id
- *
- * @param string $tpl_file name of template file
- * @param string $cache_id name of cache_id
- * @param string $compile_id name of compile_id
- * @param string $exp_time expiration time
- * @return boolean
- */
- function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
- {
-
- if (!isset($compile_id))
- $compile_id = $this->compile_id;
-
- if (!isset($tpl_file))
- $compile_id = null;
-
- $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
-
- if (!empty($this->cache_handler_func)) {
- return call_user_func_array($this->cache_handler_func,
- array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
- } else {
- $_params = array('auto_base' => $this->cache_dir,
- 'auto_source' => $tpl_file,
- 'auto_id' => $_auto_id,
- 'exp_time' => $exp_time);
- require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
- return smarty_core_rm_auto($_params, $this);
- }
-
- }
-
-
- /**
- * clear the entire contents of cache (all templates)
- *
- * @param string $exp_time expire time
- * @return boolean results of {@link smarty_core_rm_auto()}
- */
- function clear_all_cache($exp_time = null)
- {
- return $this->clear_cache(null, null, null, $exp_time);
- }
-
-
- /**
- * test to see if valid cache exists for this template
- *
- * @param string $tpl_file name of template file
- * @param string $cache_id
- * @param string $compile_id
- * @return string|false results of {@link _read_cache_file()}
- */
- function is_cached($tpl_file, $cache_id = null, $compile_id = null)
- {
- if (!$this->caching)
- return false;
-
- if (!isset($compile_id))
- $compile_id = $this->compile_id;
-
- $_params = array(
- 'tpl_file' => $tpl_file,
- 'cache_id' => $cache_id,
- 'compile_id' => $compile_id
- );
- require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
- return smarty_core_read_cache_file($_params, $this);
- }
-
-
- /**
- * clear all the assigned template variables.
- *
- */
- function clear_all_assign()
- {
- $this->_tpl_vars = array();
- }
-
- /**
- * clears compiled version of specified template resource,
- * or all compiled template files if one is not specified.
- * This function is for advanced use only, not normally needed.
- *
- * @param string $tpl_file
- * @param string $compile_id
- * @param string $exp_time
- * @return boolean results of {@link smarty_core_rm_auto()}
- */
- function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
- {
- if (!isset($compile_id)) {
- $compile_id = $this->compile_id;
- }
- $_params = array('auto_base' => $this->compile_dir,
- 'auto_source' => $tpl_file,
- 'auto_id' => $compile_id,
- 'exp_time' => $exp_time,
- 'extensions' => array('.inc', '.php'));
- require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
- return smarty_core_rm_auto($_params, $this);
- }
-
- /**
- * Checks whether requested template exists.
- *
- * @param string $tpl_file
- * @return boolean
- */
- function template_exists($tpl_file)
- {
- $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
- return $this->_fetch_resource_info($_params);
- }
-
- /**
- * Returns an array containing template variables
- *
- * @param string $name
- * @param string $type
- * @return array
- */
- function &get_template_vars($name=null)
- {
- if(!isset($name)) {
- return $this->_tpl_vars;
- } elseif(isset($this->_tpl_vars[$name])) {
- return $this->_tpl_vars[$name];
- } else {
- // var non-existant, return valid reference
- $_tmp = null;
- return $_tmp;
- }
- }
-
- /**
- * Returns an array containing config variables
- *
- * @param string $name
- * @param string $type
- * @return array
- */
- function &get_config_vars($name=null)
- {
- if(!isset($name) && is_array($this->_config[0])) {
- return $this->_config[0]['vars'];
- } else if(isset($this->_config[0]['vars'][$name])) {
- return $this->_config[0]['vars'][$name];
- } else {
- // var non-existant, return valid reference
- $_tmp = null;
- return $_tmp;
- }
- }
-
- /**
- * trigger Smarty error
- *
- * @param string $error_msg
- * @param integer $error_type
- */
- function trigger_error($error_msg, $error_type = E_USER_WARNING)
- {
- trigger_error("Smarty error: $error_msg", $error_type);
- }
-
-
- /**
- * executes & displays the template results
- *
- * @param string $resource_name
- * @param string $cache_id
- * @param string $compile_id
- */
- function display($resource_name, $cache_id = null, $compile_id = null)
- {
- $this->fetch($resource_name, $cache_id, $compile_id, true);
- }
-
- /**
- * executes & returns or displays the template results
- *
- * @param string $resource_name
- * @param string $cache_id
- * @param string $compile_id
- * @param boolean $display
- */
- function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
- {
- static $_cache_info = array();
-
- $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
- ? $this->error_reporting : error_reporting() & ~E_NOTICE);
-
- if (!$this->debugging && $this->debugging_ctrl == 'URL') {
- $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
- if (@strstr($_query_string, $this->_smarty_debug_id)) {
- if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
- // enable debugging for this browser session
- @setcookie('SMARTY_DEBUG', true);
- $this->debugging = true;
- } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
- // disable debugging for this browser session
- @setcookie('SMARTY_DEBUG', false);
- $this->debugging = false;
- } else {
- // enable debugging for this page
- $this->debugging = true;
- }
- } else {
- $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
- }
- }
-
- if ($this->debugging) {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $_debug_start_time = smarty_core_get_microtime($_params, $this);
- $this->_smarty_debug_info[] = array('type' => 'template',
- 'filename' => $resource_name,
- 'depth' => 0);
- $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
- }
-
- if (!isset($compile_id)) {
- $compile_id = $this->compile_id;
- }
-
- $this->_compile_id = $compile_id;
- $this->_inclusion_depth = 0;
-
- if ($this->caching) {
- // save old cache_info, initialize cache_info
- array_push($_cache_info, $this->_cache_info);
- $this->_cache_info = array();
- $_params = array(
- 'tpl_file' => $resource_name,
- 'cache_id' => $cache_id,
- 'compile_id' => $compile_id,
- 'results' => null
- );
- require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
- if (smarty_core_read_cache_file($_params, $this)) {
- $_smarty_results = $_params['results'];
- if (!empty($this->_cache_info['insert_tags'])) {
- $_params = array('plugins' => $this->_cache_info['insert_tags']);
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- $_params = array('results' => $_smarty_results);
- require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
- $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
- }
- if (!empty($this->_cache_info['cache_serials'])) {
- $_params = array('results' => $_smarty_results);
- require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
- $_smarty_results = smarty_core_process_compiled_include($_params, $this);
- }
-
-
- if ($display) {
- if ($this->debugging)
- {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
- require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
- $_smarty_results .= smarty_core_display_debug_console($_params, $this);
- }
- if ($this->cache_modified_check) {
- $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
- $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
- $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
- if (@count($this->_cache_info['insert_tags']) == 0
- && !$this->_cache_serials
- && $_gmt_mtime == $_last_modified_date) {
- if (php_sapi_name()=='cgi')
- header('Status: 304 Not Modified');
- else
- header('HTTP/1.1 304 Not Modified');
-
- } else {
- header('Last-Modified: '.$_gmt_mtime);
- echo $_smarty_results;
- }
- } else {
- echo $_smarty_results;
- }
- error_reporting($_smarty_old_error_level);
- // restore initial cache_info
- $this->_cache_info = array_pop($_cache_info);
- return true;
- } else {
- error_reporting($_smarty_old_error_level);
- // restore initial cache_info
- $this->_cache_info = array_pop($_cache_info);
- return $_smarty_results;
- }
- } else {
- $this->_cache_info['template'][$resource_name] = true;
- if ($this->cache_modified_check && $display) {
- header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
- }
- }
- }
-
- // load filters that are marked as autoload
- if (count($this->autoload_filters)) {
- foreach ($this->autoload_filters as $_filter_type => $_filters) {
- foreach ($_filters as $_filter) {
- $this->load_filter($_filter_type, $_filter);
- }
- }
- }
-
- $_smarty_compile_path = $this->_get_compile_path($resource_name);
-
- // if we just need to display the results, don't perform output
- // buffering - for speed
- $_cache_including = $this->_cache_including;
- $this->_cache_including = false;
- if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
- if ($this->_is_compiled($resource_name, $_smarty_compile_path)
- || $this->_compile_resource($resource_name, $_smarty_compile_path))
- {
- include($_smarty_compile_path);
- }
- } else {
- ob_start();
- if ($this->_is_compiled($resource_name, $_smarty_compile_path)
- || $this->_compile_resource($resource_name, $_smarty_compile_path))
- {
- include($_smarty_compile_path);
- }
- $_smarty_results = ob_get_contents();
- ob_end_clean();
-
- foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
- $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
- }
- }
-
- if ($this->caching) {
- $_params = array('tpl_file' => $resource_name,
- 'cache_id' => $cache_id,
- 'compile_id' => $compile_id,
- 'results' => $_smarty_results);
- require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
- smarty_core_write_cache_file($_params, $this);
- require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
- $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
-
- if ($this->_cache_serials) {
- // strip nocache-tags from output
- $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
- ,''
- ,$_smarty_results);
- }
- // restore initial cache_info
- $this->_cache_info = array_pop($_cache_info);
- }
- $this->_cache_including = $_cache_including;
-
- if ($display) {
- if (isset($_smarty_results)) { echo $_smarty_results; }
- if ($this->debugging) {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
- require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
- echo smarty_core_display_debug_console($_params, $this);
- }
- error_reporting($_smarty_old_error_level);
- return;
- } else {
- error_reporting($_smarty_old_error_level);
- if (isset($_smarty_results)) { return $_smarty_results; }
- }
- }
-
- /**
- * load configuration values
- *
- * @param string $file
- * @param string $section
- * @param string $scope
- */
- function config_load($file, $section = null, $scope = 'global')
- {
- require_once($this->_get_plugin_filepath('function', 'config_load'));
- smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
- }
-
- /**
- * return a reference to a registered object
- *
- * @param string $name
- * @return object
- */
- function &get_registered_object($name) {
- if (!isset($this->_reg_objects[$name]))
- $this->_trigger_fatal_error("'$name' is not a registered object");
-
- if (!is_object($this->_reg_objects[$name][0]))
- $this->_trigger_fatal_error("registered '$name' is not an object");
-
- return $this->_reg_objects[$name][0];
- }
-
- /**
- * clear configuration values
- *
- * @param string $var
- */
- function clear_config($var = null)
- {
- if(!isset($var)) {
- // clear all values
- $this->_config = array(array('vars' => array(),
- 'files' => array()));
- } else {
- unset($this->_config[0]['vars'][$var]);
- }
- }
-
- /**
- * get filepath of requested plugin
- *
- * @param string $type
- * @param string $name
- * @return string|false
- */
- function _get_plugin_filepath($type, $name)
- {
- $_params = array('type' => $type, 'name' => $name);
- require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
- return smarty_core_assemble_plugin_filepath($_params, $this);
- }
-
- /**
- * test if resource needs compiling
- *
- * @param string $resource_name
- * @param string $compile_path
- * @return boolean
- */
- function _is_compiled($resource_name, $compile_path)
- {
- if (!$this->force_compile && file_exists($compile_path)) {
- if (!$this->compile_check) {
- // no need to check compiled file
- return true;
- } else {
- // get file source and timestamp
- $_params = array('resource_name' => $resource_name, 'get_source'=>false);
- if (!$this->_fetch_resource_info($_params)) {
- return false;
- }
- if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
- // template not expired, no recompile
- return true;
- } else {
- // compile template
- return false;
- }
- }
- } else {
- // compiled template does not exist, or forced compile
- return false;
- }
- }
-
- /**
- * compile the template
- *
- * @param string $resource_name
- * @param string $compile_path
- * @return boolean
- */
- function _compile_resource($resource_name, $compile_path)
- {
-
- $_params = array('resource_name' => $resource_name);
- if (!$this->_fetch_resource_info($_params)) {
- return false;
- }
-
- $_source_content = $_params['source_content'];
- $_cache_include = substr($compile_path, 0, -4).'.inc';
-
- if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
- // if a _cache_serial was set, we also have to write an include-file:
- if ($this->_cache_include_info) {
- require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
- smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this);
- }
-
- $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
- require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
- smarty_core_write_compiled_resource($_params, $this);
-
- return true;
- } else {
- return false;
- }
-
- }
-
- /**
- * compile the given source
- *
- * @param string $resource_name
- * @param string $source_content
- * @param string $compiled_content
- * @return boolean
- */
- function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
- {
- if (file_exists(SMARTY_DIR . $this->compiler_file)) {
- require_once(SMARTY_DIR . $this->compiler_file);
- } else {
- // use include_path
- require_once($this->compiler_file);
- }
-
-
- $smarty_compiler = new $this->compiler_class;
-
- $smarty_compiler->template_dir = $this->template_dir;
- $smarty_compiler->compile_dir = $this->compile_dir;
- $smarty_compiler->plugins_dir = $this->plugins_dir;
- $smarty_compiler->config_dir = $this->config_dir;
- $smarty_compiler->force_compile = $this->force_compile;
- $smarty_compiler->caching = $this->caching;
- $smarty_compiler->php_handling = $this->php_handling;
- $smarty_compiler->left_delimiter = $this->left_delimiter;
- $smarty_compiler->right_delimiter = $this->right_delimiter;
- $smarty_compiler->_version = $this->_version;
- $smarty_compiler->security = $this->security;
- $smarty_compiler->secure_dir = $this->secure_dir;
- $smarty_compiler->security_settings = $this->security_settings;
- $smarty_compiler->trusted_dir = $this->trusted_dir;
- $smarty_compiler->use_sub_dirs = $this->use_sub_dirs;
- $smarty_compiler->_reg_objects = &$this->_reg_objects;
- $smarty_compiler->_plugins = &$this->_plugins;
- $smarty_compiler->_tpl_vars = &$this->_tpl_vars;
- $smarty_compiler->default_modifiers = $this->default_modifiers;
- $smarty_compiler->compile_id = $this->_compile_id;
- $smarty_compiler->_config = $this->_config;
- $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals;
-
- if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
- $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
- }
- $smarty_compiler->_cache_include = $cache_include_path;
-
-
- $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
-
- if ($smarty_compiler->_cache_serial) {
- $this->_cache_include_info = array(
- 'cache_serial'=>$smarty_compiler->_cache_serial
- ,'plugins_code'=>$smarty_compiler->_plugins_code
- ,'include_file_path' => $cache_include_path);
-
- } else {
- $this->_cache_include_info = null;
-
- }
-
- return $_results;
- }
-
- /**
- * Get the compile path for this resource
- *
- * @param string $resource_name
- * @return string results of {@link _get_auto_filename()}
- */
- function _get_compile_path($resource_name)
- {
- return $this->_get_auto_filename($this->compile_dir, $resource_name,
- $this->_compile_id) . '.php';
- }
-
- /**
- * fetch the template info. Gets timestamp, and source
- * if get_source is true
- *
- * sets $source_content to the source of the template, and
- * $resource_timestamp to its time stamp
- * @param string $resource_name
- * @param string $source_content
- * @param integer $resource_timestamp
- * @param boolean $get_source
- * @param boolean $quiet
- * @return boolean
- */
-
- function _fetch_resource_info(&$params)
- {
- if(!isset($params['get_source'])) { $params['get_source'] = true; }
- if(!isset($params['quiet'])) { $params['quiet'] = false; }
-
- $_return = false;
- $_params = array('resource_name' => $params['resource_name']) ;
- if (isset($params['resource_base_path']))
- $_params['resource_base_path'] = $params['resource_base_path'];
- else
- $_params['resource_base_path'] = $this->template_dir;
-
- if ($this->_parse_resource_name($_params)) {
- $_resource_type = $_params['resource_type'];
- $_resource_name = $_params['resource_name'];
- switch ($_resource_type) {
- case 'file':
- if ($params['get_source']) {
- $params['source_content'] = $this->_read_file($_resource_name);
- }
- $params['resource_timestamp'] = filemtime($_resource_name);
- $_return = is_file($_resource_name) && is_readable($_resource_name);
- break;
-
- default:
- // call resource functions to fetch the template source and timestamp
- if ($params['get_source']) {
- $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
- call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
- array($_resource_name, &$params['source_content'], &$this));
- } else {
- $_source_return = true;
- }
-
- $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
- call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
- array($_resource_name, &$params['resource_timestamp'], &$this));
-
- $_return = $_source_return && $_timestamp_return;
- break;
- }
- }
-
- if (!$_return) {
- // see if we can get a template with the default template handler
- if (!empty($this->default_template_handler_func)) {
- if (!is_callable($this->default_template_handler_func)) {
- $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
- } else {
- $_return = call_user_func_array(
- $this->default_template_handler_func,
- array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
- }
- }
- }
-
- if (!$_return) {
- if (!$params['quiet']) {
- $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
- }
- } else if ($_return && $this->security) {
- require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
- if (!smarty_core_is_secure($_params, $this)) {
- if (!$params['quiet'])
- $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
- $params['source_content'] = null;
- $params['resource_timestamp'] = null;
- return false;
- }
- }
- return $_return;
- }
-
-
- /**
- * parse out the type and name from the resource
- *
- * @param string $resource_base_path
- * @param string $resource_name
- * @param string $resource_type
- * @param string $resource_name
- * @return boolean
- */
-
- function _parse_resource_name(&$params)
- {
-
- // split tpl_path by the first colon
- $_resource_name_parts = explode(':', $params['resource_name'], 2);
-
- if (count($_resource_name_parts) == 1) {
- // no resource type given
- $params['resource_type'] = $this->default_resource_type;
- $params['resource_name'] = $_resource_name_parts[0];
- } else {
- if(strlen($_resource_name_parts[0]) == 1) {
- // 1 char is not resource type, but part of filepath
- $params['resource_type'] = $this->default_resource_type;
- $params['resource_name'] = $params['resource_name'];
- } else {
- $params['resource_type'] = $_resource_name_parts[0];
- $params['resource_name'] = $_resource_name_parts[1];
- }
- }
-
- if ($params['resource_type'] == 'file') {
- if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
- // relative pathname to $params['resource_base_path']
- // use the first directory where the file is found
- foreach ((array)$params['resource_base_path'] as $_curr_path) {
- $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
- if (file_exists($_fullpath) && is_file($_fullpath)) {
- $params['resource_name'] = $_fullpath;
- return true;
- }
- // didn't find the file, try include_path
- $_params = array('file_path' => $_fullpath);
- require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
- if(smarty_core_get_include_path($_params, $this)) {
- $params['resource_name'] = $_params['new_file_path'];
- return true;
- }
- }
- return false;
- } else {
- /* absolute path */
- return file_exists($params['resource_name']);
- }
- } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
- $_params = array('type' => $params['resource_type']);
- require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
- smarty_core_load_resource_plugin($_params, $this);
- }
-
- return true;
- }
-
-
- /**
- * Handle modifiers
- *
- * @param string|null $modifier_name
- * @param array|null $map_array
- * @return string result of modifiers
- */
- function _run_mod_handler()
- {
- $_args = func_get_args();
- list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
- list($_func_name, $_tpl_file, $_tpl_line) =
- $this->_plugins['modifier'][$_modifier_name];
-
- $_var = $_args[0];
- foreach ($_var as $_key => $_val) {
- $_args[0] = $_val;
- $_var[$_key] = call_user_func_array($_func_name, $_args);
- }
- return $_var;
- }
-
- /**
- * Remove starting and ending quotes from the string
- *
- * @param string $string
- * @return string
- */
- function _dequote($string)
- {
- if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
- substr($string, -1) == substr($string, 0, 1))
- return substr($string, 1, -1);
- else
- return $string;
- }
-
-
- /**
- * read in a file
- *
- * @param string $filename
- * @return string
- */
- function _read_file($filename)
- {
- if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) {
- $contents = '';
- while (!feof($fd)) {
- $contents .= fread($fd, 8192);
- }
- fclose($fd);
- return $contents;
- } else {
- return false;
- }
- }
-
- /**
- * get a concrete filename for automagically created content
- *
- * @param string $auto_base
- * @param string $auto_source
- * @param string $auto_id
- * @return string
- * @staticvar string|null
- * @staticvar string|null
- */
- function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
- {
- $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
- $_return = $auto_base . DIRECTORY_SEPARATOR;
-
- if(isset($auto_id)) {
- // make auto_id safe for directory names
- $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
- // split into separate directories
- $_return .= $auto_id . $_compile_dir_sep;
- }
-
- if(isset($auto_source)) {
- // make source name safe for filename
- $_filename = urlencode(basename($auto_source));
- $_crc32 = sprintf('%08X', crc32($auto_source));
- // prepend %% to avoid name conflicts with
- // with $params['auto_id'] names
- $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
- substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
- $_return .= '%%' . $_crc32 . '%%' . $_filename;
- }
-
- return $_return;
- }
-
- /**
- * unlink a file, possibly using expiration time
- *
- * @param string $resource
- * @param integer $exp_time
- */
- function _unlink($resource, $exp_time = null)
- {
- if(isset($exp_time)) {
- if(time() - @filemtime($resource) >= $exp_time) {
- return @unlink($resource);
- }
- } else {
- return @unlink($resource);
- }
- }
-
- /**
- * returns an auto_id for auto-file-functions
- *
- * @param string $cache_id
- * @param string $compile_id
- * @return string|null
- */
- function _get_auto_id($cache_id=null, $compile_id=null) {
- if (isset($cache_id))
- return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id;
- elseif(isset($compile_id))
- return $compile_id;
- else
- return null;
- }
-
- /**
- * trigger Smarty plugin error
- *
- * @param string $error_msg
- * @param string $tpl_file
- * @param integer $tpl_line
- * @param string $file
- * @param integer $line
- * @param integer $error_type
- */
- function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
- $file = null, $line = null, $error_type = E_USER_ERROR)
- {
- if(isset($file) && isset($line)) {
- $info = ' ('.basename($file).", line $line)";
- } else {
- $info = '';
- }
- if (isset($tpl_line) && isset($tpl_file)) {
- $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
- } else {
- $this->trigger_error($error_msg . $info, $error_type);
- }
- }
-
-
- /**
- * callback function for preg_replace, to call a non-cacheable block
- * @return string
- */
- function _process_compiled_include_callback($match) {
- $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
- ob_start();
- $_func($this);
- $_ret = ob_get_contents();
- ob_end_clean();
- return $_ret;
- }
-
-
- /**
- * called for included templates
- *
- * @param string $_smarty_include_tpl_file
- * @param string $_smarty_include_vars
- */
-
- // $_smarty_include_tpl_file, $_smarty_include_vars
-
- function _smarty_include($params)
- {
- if ($this->debugging) {
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $debug_start_time = smarty_core_get_microtime($_params, $this);
- $this->_smarty_debug_info[] = array('type' => 'template',
- 'filename' => $params['smarty_include_tpl_file'],
- 'depth' => ++$this->_inclusion_depth);
- $included_tpls_idx = count($this->_smarty_debug_info) - 1;
- }
-
- $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
-
- // config vars are treated as local, so push a copy of the
- // current ones onto the front of the stack
- array_unshift($this->_config, $this->_config[0]);
-
- $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
-
-
- if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
- || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
- {
- include($_smarty_compile_path);
- }
-
- // pop the local vars off the front of the stack
- array_shift($this->_config);
-
- $this->_inclusion_depth--;
-
- if ($this->debugging) {
- // capture time for debugging info
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
- }
-
- if ($this->caching) {
- $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
- }
- }
-
-
- /**
- * get or set an array of cached attributes for function that is
- * not cacheable
- * @return array
- */
- function &_smarty_cache_attrs($cache_serial, $count) {
- $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
-
- if ($this->_cache_including) {
- /* return next set of cache_attrs */
- $_return = current($_cache_attrs);
- next($_cache_attrs);
- return $_return;
-
- } else {
- /* add a reference to a new set of cache_attrs */
- $_cache_attrs[] = array();
- return $_cache_attrs[count($_cache_attrs)-1];
-
- }
-
- }
-
-
- /**
- * wrapper for include() retaining $this
- * @return mixed
- */
- function _include($filename, $once=false, $params=null)
- {
- if ($once) {
- return include_once($filename);
- } else {
- return include($filename);
- }
- }
-
-
- /**
- * wrapper for eval() retaining $this
- * @return mixed
- */
- function _eval($code, $params=null)
- {
- return eval($code);
- }
-
- /**
- * Extracts the filter name from the given callback
- *
- * @param callback $function
- * @return string
- */
- function _get_filter_name($function)
- {
- if (is_array($function)) {
- $_class_name = (is_object($function[0]) ?
- get_class($function[0]) : $function[0]);
- return $_class_name . '_' . $function[1];
- }
- else {
- return $function;
- }
- }
-
- /**#@-*/
-
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-
-/**
- * Project: Smarty: the PHP compiling template engine
- * File: Smarty_Compiler.class.php
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @link http://smarty.php.net/
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author Andrei Zmievski <andrei@php.net>
- * @version 2.6.26
- * @copyright 2001-2005 New Digital Group, Inc.
- * @package Smarty
- */
-
-/* $Id: Smarty_Compiler.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
-
-/**
- * Template compiling class
- * @package Smarty
- */
-class Smarty_Compiler extends Smarty {
-
- // internal vars
- /**#@+
- * @access private
- */
- var $_folded_blocks = array(); // keeps folded template blocks
- var $_current_file = null; // the current template being compiled
- var $_current_line_no = 1; // line number for error messages
- var $_capture_stack = array(); // keeps track of nested capture buffers
- var $_plugin_info = array(); // keeps track of plugins to load
- var $_init_smarty_vars = false;
- var $_permitted_tokens = array('true','false','yes','no','on','off','null');
- var $_db_qstr_regexp = null; // regexps are setup in the constructor
- var $_si_qstr_regexp = null;
- var $_qstr_regexp = null;
- var $_func_regexp = null;
- var $_reg_obj_regexp = null;
- var $_var_bracket_regexp = null;
- var $_num_const_regexp = null;
- var $_dvar_guts_regexp = null;
- var $_dvar_regexp = null;
- var $_cvar_regexp = null;
- var $_svar_regexp = null;
- var $_avar_regexp = null;
- var $_mod_regexp = null;
- var $_var_regexp = null;
- var $_parenth_param_regexp = null;
- var $_func_call_regexp = null;
- var $_obj_ext_regexp = null;
- var $_obj_start_regexp = null;
- var $_obj_params_regexp = null;
- var $_obj_call_regexp = null;
- var $_cacheable_state = 0;
- var $_cache_attrs_count = 0;
- var $_nocache_count = 0;
- var $_cache_serial = null;
- var $_cache_include = null;
-
- var $_strip_depth = 0;
- var $_additional_newline = "\n";
-
- /**#@-*/
- /**
- * The class constructor.
- */
- function Smarty_Compiler()
- {
- // matches double quoted strings:
- // "foobar"
- // "foo\"bar"
- $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
-
- // matches single quoted strings:
- // 'foobar'
- // 'foo\'bar'
- $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
-
- // matches single or double quoted strings
- $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
-
- // matches bracket portion of vars
- // [0]
- // [foo]
- // [$bar]
- $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
-
- // matches numerical constants
- // 30
- // -12
- // 13.22
- $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
-
- // matches $ vars (not objects):
- // $foo
- // $foo.bar
- // $foo.bar.foobar
- // $foo[0]
- // $foo[$bar]
- // $foo[5][blah]
- // $foo[5].bar[$foobar][4]
- $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
- $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
- $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
- . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
- $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
-
- // matches config vars:
- // #foo#
- // #foobar123_foo#
- $this->_cvar_regexp = '\#\w+\#';
-
- // matches section vars:
- // %foo.bar%
- $this->_svar_regexp = '\%\w+\.\w+\%';
-
- // matches all valid variables (no quotes, no modifiers)
- $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
- . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
-
- // matches valid variable syntax:
- // $foo
- // $foo
- // #foo#
- // #foo#
- // "text"
- // "text"
- $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
-
- // matches valid object call (one level of object nesting allowed in parameters):
- // $foo->bar
- // $foo->bar()
- // $foo->bar("text")
- // $foo->bar($foo, $bar, "text")
- // $foo->bar($foo, "foo")
- // $foo->bar->foo()
- // $foo->bar->foo->bar()
- // $foo->bar($foo->bar)
- // $foo->bar($foo->bar())
- // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
- $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
- $this->_obj_restricted_param_regexp = '(?:'
- . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
- . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
- $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
- . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
- $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
- . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
- $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
- $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
-
- // matches valid modifier syntax:
- // |foo
- // |@foo
- // |foo:"bar"
- // |foo:$bar
- // |foo:"bar":$foobar
- // |foo|bar
- // |foo:$foo->bar
- $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
- . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
-
- // matches valid function name:
- // foo123
- // _foo_bar
- $this->_func_regexp = '[a-zA-Z_]\w*';
-
- // matches valid registered object:
- // foo->bar
- $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
-
- // matches valid parameter values:
- // true
- // $foo
- // $foo|bar
- // #foo#
- // #foo#|bar
- // "text"
- // "text"|bar
- // $foo->bar
- $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
- . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
-
- // matches valid parenthesised function parameters:
- //
- // "text"
- // $foo, $bar, "text"
- // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
- $this->_parenth_param_regexp = '(?:\((?:\w+|'
- . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
- . $this->_param_regexp . ')))*)?\))';
-
- // matches valid function call:
- // foo()
- // foo_bar($foo)
- // _foo_bar($foo,"bar")
- // foo123($foo,$foo->bar(),"foo")
- $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
- . $this->_parenth_param_regexp . '))';
- }
-
- /**
- * compile a resource
- *
- * sets $compiled_content to the compiled source
- * @param string $resource_name
- * @param string $source_content
- * @param string $compiled_content
- * @return true
- */
- function _compile_file($resource_name, $source_content, &$compiled_content)
- {
-
- if ($this->security) {
- // do not allow php syntax to be executed unless specified
- if ($this->php_handling == SMARTY_PHP_ALLOW &&
- !$this->security_settings['PHP_HANDLING']) {
- $this->php_handling = SMARTY_PHP_PASSTHRU;
- }
- }
-
- $this->_load_filters();
-
- $this->_current_file = $resource_name;
- $this->_current_line_no = 1;
- $ldq = preg_quote($this->left_delimiter, '~');
- $rdq = preg_quote($this->right_delimiter, '~');
-
- // run template source through prefilter functions
- if (count($this->_plugins['prefilter']) > 0) {
- foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
- if ($prefilter === false) continue;
- if ($prefilter[3] || is_callable($prefilter[0])) {
- $source_content = call_user_func_array($prefilter[0],
- array($source_content, &$this));
- $this->_plugins['prefilter'][$filter_name][3] = true;
- } else {
- $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
- }
- }
- }
-
- /* fetch all special blocks */
- $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
-
- preg_match_all($search, $source_content, $match, PREG_SET_ORDER);
- $this->_folded_blocks = $match;
- reset($this->_folded_blocks);
-
- /* replace special blocks by "{php}" */
- $source_content = preg_replace($search.'e', "'"
- . $this->_quote_replace($this->left_delimiter) . 'php'
- . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
- . $this->_quote_replace($this->right_delimiter)
- . "'"
- , $source_content);
-
- /* Gather all template tags. */
- preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
- $template_tags = $_match[1];
- /* Split content by template tags to obtain non-template content. */
- $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
-
- /* loop through text blocks */
- for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
- /* match anything resembling php tags */
- if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
- /* replace tags with placeholders to prevent recursive replacements */
- $sp_match[1] = array_unique($sp_match[1]);
- usort($sp_match[1], '_smarty_sort_length');
- for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
- $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
- }
- /* process each one */
- for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
- if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
- /* echo php contents */
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
- } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
- /* quote php tags */
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
- } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
- /* remove php tags */
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
- } else {
- /* SMARTY_PHP_ALLOW, but echo non php starting tags */
- $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
- $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
- }
- }
- }
- }
-
- /* Compile the template tags into PHP code. */
- $compiled_tags = array();
- for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
- $this->_current_line_no += substr_count($text_blocks[$i], "\n");
- $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
- $this->_current_line_no += substr_count($template_tags[$i], "\n");
- }
- if (count($this->_tag_stack)>0) {
- list($_open_tag, $_line_no) = end($this->_tag_stack);
- $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
- return;
- }
-
- /* Reformat $text_blocks between 'strip' and '/strip' tags,
- removing spaces, tabs and newlines. */
- $strip = false;
- for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
- if ($compiled_tags[$i] == '{strip}') {
- $compiled_tags[$i] = '';
- $strip = true;
- /* remove leading whitespaces */
- $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
- }
- if ($strip) {
- /* strip all $text_blocks before the next '/strip' */
- for ($j = $i + 1; $j < $for_max; $j++) {
- /* remove leading and trailing whitespaces of each line */
- $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
- if ($compiled_tags[$j] == '{/strip}') {
- /* remove trailing whitespaces from the last text_block */
- $text_blocks[$j] = rtrim($text_blocks[$j]);
- }
- $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
- if ($compiled_tags[$j] == '{/strip}') {
- $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
- if a newline is following the closing strip-tag */
- $strip = false;
- $i = $j;
- break;
- }
- }
- }
- }
- $compiled_content = '';
-
- $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
-
- /* Interleave the compiled contents and text blocks to get the final result. */
- for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
- if ($compiled_tags[$i] == '') {
- // tag result empty, remove first newline from following text block
- $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
- }
- // replace legit PHP tags with placeholder
- $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
- $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
-
- $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
- }
- $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
-
- // escape php tags created by interleaving
- $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
- $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
-
- // recover legit tags
- $compiled_content = str_replace($tag_guard, '<?', $compiled_content);
-
- // remove \n from the end of the file, if any
- if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
- $compiled_content = substr($compiled_content, 0, -1);
- }
-
- if (!empty($this->_cache_serial)) {
- $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
- }
-
- // run compiled template through postfilter functions
- if (count($this->_plugins['postfilter']) > 0) {
- foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
- if ($postfilter === false) continue;
- if ($postfilter[3] || is_callable($postfilter[0])) {
- $compiled_content = call_user_func_array($postfilter[0],
- array($compiled_content, &$this));
- $this->_plugins['postfilter'][$filter_name][3] = true;
- } else {
- $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
- }
- }
- }
-
- // put header at the top of the compiled template
- $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
- $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
-
- /* Emit code to load needed plugins. */
- $this->_plugins_code = '';
- if (count($this->_plugin_info)) {
- $_plugins_params = "array('plugins' => array(";
- foreach ($this->_plugin_info as $plugin_type => $plugins) {
- foreach ($plugins as $plugin_name => $plugin_info) {
- $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
- $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
- }
- }
- $_plugins_params .= '))';
- $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
- $template_header .= $plugins_code;
- $this->_plugin_info = array();
- $this->_plugins_code = $plugins_code;
- }
-
- if ($this->_init_smarty_vars) {
- $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
- $this->_init_smarty_vars = false;
- }
-
- $compiled_content = $template_header . $compiled_content;
- return true;
- }
-
- /**
- * Compile a template tag
- *
- * @param string $template_tag
- * @return string
- */
- function _compile_tag($template_tag)
- {
- /* Matched comment. */
- if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
- return '';
-
- /* Split tag into two three parts: command, command modifiers and the arguments. */
- if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
- . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
- (?:\s+(.*))?$
- ~xs', $template_tag, $match)) {
- $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $tag_command = $match[1];
- $tag_modifier = isset($match[2]) ? $match[2] : null;
- $tag_args = isset($match[3]) ? $match[3] : null;
-
- if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
- /* tag name is a variable or object */
- $_return = $this->_parse_var_props($tag_command . $tag_modifier);
- return "<?php echo $_return; ?>" . $this->_additional_newline;
- }
-
- /* If the tag name is a registered object, we process it. */
- if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
- return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
- }
-
- switch ($tag_command) {
- case 'include':
- return $this->_compile_include_tag($tag_args);
-
- case 'include_php':
- return $this->_compile_include_php_tag($tag_args);
-
- case 'if':
- $this->_push_tag('if');
- return $this->_compile_if_tag($tag_args);
-
- case 'else':
- list($_open_tag) = end($this->_tag_stack);
- if ($_open_tag != 'if' && $_open_tag != 'elseif')
- $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
- else
- $this->_push_tag('else');
- return '<?php else: ?>';
-
- case 'elseif':
- list($_open_tag) = end($this->_tag_stack);
- if ($_open_tag != 'if' && $_open_tag != 'elseif')
- $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
- if ($_open_tag == 'if')
- $this->_push_tag('elseif');
- return $this->_compile_if_tag($tag_args, true);
-
- case '/if':
- $this->_pop_tag('if');
- return '<?php endif; ?>';
-
- case 'capture':
- return $this->_compile_capture_tag(true, $tag_args);
-
- case '/capture':
- return $this->_compile_capture_tag(false);
-
- case 'ldelim':
- return $this->left_delimiter;
-
- case 'rdelim':
- return $this->right_delimiter;
-
- case 'section':
- $this->_push_tag('section');
- return $this->_compile_section_start($tag_args);
-
- case 'sectionelse':
- $this->_push_tag('sectionelse');
- return "<?php endfor; else: ?>";
- break;
-
- case '/section':
- $_open_tag = $this->_pop_tag('section');
- if ($_open_tag == 'sectionelse')
- return "<?php endif; ?>";
- else
- return "<?php endfor; endif; ?>";
-
- case 'foreach':
- $this->_push_tag('foreach');
- return $this->_compile_foreach_start($tag_args);
- break;
-
- case 'foreachelse':
- $this->_push_tag('foreachelse');
- return "<?php endforeach; else: ?>";
-
- case '/foreach':
- $_open_tag = $this->_pop_tag('foreach');
- if ($_open_tag == 'foreachelse')
- return "<?php endif; unset(\$_from); ?>";
- else
- return "<?php endforeach; endif; unset(\$_from); ?>";
- break;
-
- case 'strip':
- case '/strip':
- if (substr($tag_command, 0, 1)=='/') {
- $this->_pop_tag('strip');
- if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
- $this->_additional_newline = "\n";
- return '{' . $tag_command . '}';
- }
- } else {
- $this->_push_tag('strip');
- if ($this->_strip_depth++==0) { /* outermost opening {strip} */
- $this->_additional_newline = "";
- return '{' . $tag_command . '}';
- }
- }
- return '';
-
- case 'php':
- /* handle folded tags replaced by {php} */
- list(, $block) = each($this->_folded_blocks);
- $this->_current_line_no += substr_count($block[0], "\n");
- /* the number of matched elements in the regexp in _compile_file()
- determins the type of folded tag that was found */
- switch (count($block)) {
- case 2: /* comment */
- return '';
-
- case 3: /* literal */
- return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
-
- case 4: /* php */
- if ($this->security && !$this->security_settings['PHP_TAGS']) {
- $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- return '<?php ' . $block[3] .' ?>';
- }
- break;
-
- case 'insert':
- return $this->_compile_insert_tag($tag_args);
-
- default:
- if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
- return $output;
- } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
- return $output;
- } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
- return $output;
- } else {
- $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- }
- }
-
-
- /**
- * compile the custom compiler tag
- *
- * sets $output to the compiled custom compiler tag
- * @param string $tag_command
- * @param string $tag_args
- * @param string $output
- * @return boolean
- */
- function _compile_compiler_tag($tag_command, $tag_args, &$output)
- {
- $found = false;
- $have_function = true;
-
- /*
- * First we check if the compiler function has already been registered
- * or loaded from a plugin file.
- */
- if (isset($this->_plugins['compiler'][$tag_command])) {
- $found = true;
- $plugin_func = $this->_plugins['compiler'][$tag_command][0];
- if (!is_callable($plugin_func)) {
- $message = "compiler function '$tag_command' is not implemented";
- $have_function = false;
- }
- }
- /*
- * Otherwise we need to load plugin file and look for the function
- * inside it.
- */
- else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
- $found = true;
-
- include_once $plugin_file;
-
- $plugin_func = 'smarty_compiler_' . $tag_command;
- if (!is_callable($plugin_func)) {
- $message = "plugin function $plugin_func() not found in $plugin_file\n";
- $have_function = false;
- } else {
- $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
- }
- }
-
- /*
- * True return value means that we either found a plugin or a
- * dynamically registered function. False means that we didn't and the
- * compiler should now emit code to load custom function plugin for this
- * tag.
- */
- if ($found) {
- if ($have_function) {
- $output = call_user_func_array($plugin_func, array($tag_args, &$this));
- if($output != '') {
- $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
- . $output
- . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
- }
- } else {
- $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
- }
- return true;
- } else {
- return false;
- }
- }
-
-
- /**
- * compile block function tag
- *
- * sets $output to compiled block function tag
- * @param string $tag_command
- * @param string $tag_args
- * @param string $tag_modifier
- * @param string $output
- * @return boolean
- */
- function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
- {
- if (substr($tag_command, 0, 1) == '/') {
- $start_tag = false;
- $tag_command = substr($tag_command, 1);
- } else
- $start_tag = true;
-
- $found = false;
- $have_function = true;
-
- /*
- * First we check if the block function has already been registered
- * or loaded from a plugin file.
- */
- if (isset($this->_plugins['block'][$tag_command])) {
- $found = true;
- $plugin_func = $this->_plugins['block'][$tag_command][0];
- if (!is_callable($plugin_func)) {
- $message = "block function '$tag_command' is not implemented";
- $have_function = false;
- }
- }
- /*
- * Otherwise we need to load plugin file and look for the function
- * inside it.
- */
- else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
- $found = true;
-
- include_once $plugin_file;
-
- $plugin_func = 'smarty_block_' . $tag_command;
- if (!function_exists($plugin_func)) {
- $message = "plugin function $plugin_func() not found in $plugin_file\n";
- $have_function = false;
- } else {
- $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
-
- }
- }
-
- if (!$found) {
- return false;
- } else if (!$have_function) {
- $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
- return true;
- }
-
- /*
- * Even though we've located the plugin function, compilation
- * happens only once, so the plugin will still need to be loaded
- * at runtime for future requests.
- */
- $this->_add_plugin('block', $tag_command);
-
- if ($start_tag)
- $this->_push_tag($tag_command);
- else
- $this->_pop_tag($tag_command);
-
- if ($start_tag) {
- $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
- $attrs = $this->_parse_attrs($tag_args);
- $_cache_attrs='';
- $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
- $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
- $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
- $output .= 'while ($_block_repeat) { ob_start(); ?>';
- } else {
- $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
- $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
- if ($tag_modifier != '') {
- $this->_parse_modifiers($_out_tag_text, $tag_modifier);
- }
- $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
- $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
- }
-
- return true;
- }
-
-
- /**
- * compile custom function tag
- *
- * @param string $tag_command
- * @param string $tag_args
- * @param string $tag_modifier
- * @return string
- */
- function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
- {
- $found = false;
- $have_function = true;
-
- /*
- * First we check if the custom function has already been registered
- * or loaded from a plugin file.
- */
- if (isset($this->_plugins['function'][$tag_command])) {
- $found = true;
- $plugin_func = $this->_plugins['function'][$tag_command][0];
- if (!is_callable($plugin_func)) {
- $message = "custom function '$tag_command' is not implemented";
- $have_function = false;
- }
- }
- /*
- * Otherwise we need to load plugin file and look for the function
- * inside it.
- */
- else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
- $found = true;
-
- include_once $plugin_file;
-
- $plugin_func = 'smarty_function_' . $tag_command;
- if (!function_exists($plugin_func)) {
- $message = "plugin function $plugin_func() not found in $plugin_file\n";
- $have_function = false;
- } else {
- $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
-
- }
- }
-
- if (!$found) {
- return false;
- } else if (!$have_function) {
- $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
- return true;
- }
-
- /* declare plugin to be loaded on display of the template that
- we compile right now */
- $this->_add_plugin('function', $tag_command);
-
- $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
- $attrs = $this->_parse_attrs($tag_args);
- $_cache_attrs = '';
- $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
-
- $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
- if($tag_modifier != '') {
- $this->_parse_modifiers($output, $tag_modifier);
- }
-
- if($output != '') {
- $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
- . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
- }
-
- return true;
- }
-
- /**
- * compile a registered object tag
- *
- * @param string $tag_command
- * @param array $attrs
- * @param string $tag_modifier
- * @return string
- */
- function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
- {
- if (substr($tag_command, 0, 1) == '/') {
- $start_tag = false;
- $tag_command = substr($tag_command, 1);
- } else {
- $start_tag = true;
- }
-
- list($object, $obj_comp) = explode('->', $tag_command);
-
- $arg_list = array();
- if(count($attrs)) {
- $_assign_var = false;
- foreach ($attrs as $arg_name => $arg_value) {
- if($arg_name == 'assign') {
- $_assign_var = $arg_value;
- unset($attrs['assign']);
- continue;
- }
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
- }
-
- if($this->_reg_objects[$object][2]) {
- // smarty object argument format
- $args = "array(".implode(',', (array)$arg_list)."), \$this";
- } else {
- // traditional argument format
- $args = implode(',', array_values($attrs));
- if (empty($args)) {
- $args = '';
- }
- }
-
- $prefix = '';
- $postfix = '';
- $newline = '';
- if(!is_object($this->_reg_objects[$object][0])) {
- $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
- } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
- $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
- } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
- // method
- if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
- // block method
- if ($start_tag) {
- $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
- $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
- $prefix .= "while (\$_block_repeat) { ob_start();";
- $return = null;
- $postfix = '';
- } else {
- $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
- $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
- $postfix = "} array_pop(\$this->_tag_stack);";
- }
- } else {
- // non-block method
- $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
- }
- } else {
- // property
- $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
- }
-
- if($return != null) {
- if($tag_modifier != '') {
- $this->_parse_modifiers($return, $tag_modifier);
- }
-
- if(!empty($_assign_var)) {
- $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);";
- } else {
- $output = 'echo ' . $return . ';';
- $newline = $this->_additional_newline;
- }
- } else {
- $output = '';
- }
-
- return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
- }
-
- /**
- * Compile {insert ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_insert_tag($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $name = $this->_dequote($attrs['name']);
-
- if (empty($name)) {
- return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- if (!preg_match('~^\w+$~', $name)) {
- return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- if (!empty($attrs['script'])) {
- $delayed_loading = true;
- } else {
- $delayed_loading = false;
- }
-
- foreach ($attrs as $arg_name => $arg_value) {
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
-
- $this->_add_plugin('insert', $name, $delayed_loading);
-
- $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
-
- return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
- }
-
- /**
- * Compile {include ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_include_tag($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $arg_list = array();
-
- if (empty($attrs['file'])) {
- $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- foreach ($attrs as $arg_name => $arg_value) {
- if ($arg_name == 'file') {
- $include_file = $arg_value;
- continue;
- } else if ($arg_name == 'assign') {
- $assign_var = $arg_value;
- continue;
- }
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
-
- $output = '<?php ';
-
- if (isset($assign_var)) {
- $output .= "ob_start();\n";
- }
-
- $output .=
- "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
-
-
- $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
- $output .= "\$this->_smarty_include($_params);\n" .
- "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
- "unset(\$_smarty_tpl_vars);\n";
-
- if (isset($assign_var)) {
- $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
- }
-
- $output .= ' ?>';
-
- return $output;
-
- }
-
- /**
- * Compile {include ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_include_php_tag($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
-
- if (empty($attrs['file'])) {
- $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
- $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
-
- $arg_list = array();
- foreach($attrs as $arg_name => $arg_value) {
- if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
- if(is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- $arg_list[] = "'$arg_name' => $arg_value";
- }
- }
-
- $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
-
- return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
- }
-
-
- /**
- * Compile {section ...} tag
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_section_start($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $arg_list = array();
-
- $output = '<?php ';
- $section_name = $attrs['name'];
- if (empty($section_name)) {
- $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $output .= "unset(\$this->_sections[$section_name]);\n";
- $section_props = "\$this->_sections[$section_name]";
-
- foreach ($attrs as $attr_name => $attr_value) {
- switch ($attr_name) {
- case 'loop':
- $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
- break;
-
- case 'show':
- if (is_bool($attr_value))
- $show_attr_value = $attr_value ? 'true' : 'false';
- else
- $show_attr_value = "(bool)$attr_value";
- $output .= "{$section_props}['show'] = $show_attr_value;\n";
- break;
-
- case 'name':
- $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
- break;
-
- case 'max':
- case 'start':
- $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
- break;
-
- case 'step':
- $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
- break;
-
- default:
- $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
- }
-
- if (!isset($attrs['show']))
- $output .= "{$section_props}['show'] = true;\n";
-
- if (!isset($attrs['loop']))
- $output .= "{$section_props}['loop'] = 1;\n";
-
- if (!isset($attrs['max']))
- $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
- else
- $output .= "if ({$section_props}['max'] < 0)\n" .
- " {$section_props}['max'] = {$section_props}['loop'];\n";
-
- if (!isset($attrs['step']))
- $output .= "{$section_props}['step'] = 1;\n";
-
- if (!isset($attrs['start']))
- $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
- else {
- $output .= "if ({$section_props}['start'] < 0)\n" .
- " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
- "else\n" .
- " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
- }
-
- $output .= "if ({$section_props}['show']) {\n";
- if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
- $output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
- } else {
- $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
- }
- $output .= " if ({$section_props}['total'] == 0)\n" .
- " {$section_props}['show'] = false;\n" .
- "} else\n" .
- " {$section_props}['total'] = 0;\n";
-
- $output .= "if ({$section_props}['show']):\n";
- $output .= "
- for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
- {$section_props}['iteration'] <= {$section_props}['total'];
- {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
- $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
- $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
- $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
- $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
- $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
-
- $output .= "?>";
-
- return $output;
- }
-
-
- /**
- * Compile {foreach ...} tag.
- *
- * @param string $tag_args
- * @return string
- */
- function _compile_foreach_start($tag_args)
- {
- $attrs = $this->_parse_attrs($tag_args);
- $arg_list = array();
-
- if (empty($attrs['from'])) {
- return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
- }
- $from = $attrs['from'];
-
- if (empty($attrs['item'])) {
- return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
- }
- $item = $this->_dequote($attrs['item']);
- if (!preg_match('~^\w+$~', $item)) {
- return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- if (isset($attrs['key'])) {
- $key = $this->_dequote($attrs['key']);
- if (!preg_match('~^\w+$~', $key)) {
- return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
- }
- $key_part = "\$this->_tpl_vars['$key'] => ";
- } else {
- $key = null;
- $key_part = '';
- }
-
- if (isset($attrs['name'])) {
- $name = $attrs['name'];
- } else {
- $name = null;
- }
-
- $output = '<?php ';
- $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
- if (isset($name)) {
- $foreach_props = "\$this->_foreach[$name]";
- $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
- $output .= "if ({$foreach_props}['total'] > 0):\n";
- $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
- $output .= " {$foreach_props}['iteration']++;\n";
- } else {
- $output .= "if (count(\$_from)):\n";
- $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
- }
- $output .= '?>';
-
- return $output;
- }
-
-
- /**
- * Compile {capture} .. {/capture} tags
- *
- * @param boolean $start true if this is the {capture} tag
- * @param string $tag_args
- * @return string
- */
-
- function _compile_capture_tag($start, $tag_args = '')
- {
- $attrs = $this->_parse_attrs($tag_args);
-
- if ($start) {
- $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
- $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
- $append = isset($attrs['append']) ? $attrs['append'] : null;
-
- $output = "<?php ob_start(); ?>";
- $this->_capture_stack[] = array($buffer, $assign, $append);
- } else {
- list($buffer, $assign, $append) = array_pop($this->_capture_stack);
- $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
- if (isset($assign)) {
- $output .= " \$this->assign($assign, ob_get_contents());";
- }
- if (isset($append)) {
- $output .= " \$this->append($append, ob_get_contents());";
- }
- $output .= "ob_end_clean(); ?>";
- }
-
- return $output;
- }
-
- /**
- * Compile {if ...} tag
- *
- * @param string $tag_args
- * @param boolean $elseif if true, uses elseif instead of if
- * @return string
- */
- function _compile_if_tag($tag_args, $elseif = false)
- {
-
- /* Tokenize args for 'if' tag. */
- preg_match_all('~(?>
- ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
- ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string
- \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token
- \b\w+\b | # valid word token
- \S+ # anything else
- )~x', $tag_args, $match);
-
- $tokens = $match[0];
-
- if(empty($tokens)) {
- $_error_msg = $elseif ? "'elseif'" : "'if'";
- $_error_msg .= ' statement requires arguments';
- $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
- }
-
-
- // make sure we have balanced parenthesis
- $token_count = array_count_values($tokens);
- if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
- $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- $is_arg_stack = array();
-
- for ($i = 0; $i < count($tokens); $i++) {
-
- $token = &$tokens[$i];
-
- switch (strtolower($token)) {
- case '!':
- case '%':
- case '!==':
- case '==':
- case '===':
- case '>':
- case '<':
- case '!=':
- case '<>':
- case '<<':
- case '>>':
- case '<=':
- case '>=':
- case '&&':
- case '||':
- case '|':
- case '^':
- case '&':
- case '~':
- case ')':
- case ',':
- case '+':
- case '-':
- case '*':
- case '/':
- case '@':
- break;
-
- case 'eq':
- $token = '==';
- break;
-
- case 'ne':
- case 'neq':
- $token = '!=';
- break;
-
- case 'lt':
- $token = '<';
- break;
-
- case 'le':
- case 'lte':
- $token = '<=';
- break;
-
- case 'gt':
- $token = '>';
- break;
-
- case 'ge':
- case 'gte':
- $token = '>=';
- break;
-
- case 'and':
- $token = '&&';
- break;
-
- case 'or':
- $token = '||';
- break;
-
- case 'not':
- $token = '!';
- break;
-
- case 'mod':
- $token = '%';
- break;
-
- case '(':
- array_push($is_arg_stack, $i);
- break;
-
- case 'is':
- /* If last token was a ')', we operate on the parenthesized
- expression. The start of the expression is on the stack.
- Otherwise, we operate on the last encountered token. */
- if ($tokens[$i-1] == ')') {
- $is_arg_start = array_pop($is_arg_stack);
- if ($is_arg_start != 0) {
- if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
- $is_arg_start--;
- }
- }
- } else
- $is_arg_start = $i-1;
- /* Construct the argument for 'is' expression, so it knows
- what to operate on. */
- $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
-
- /* Pass all tokens from next one until the end to the
- 'is' expression parsing function. The function will
- return modified tokens, where the first one is the result
- of the 'is' expression and the rest are the tokens it
- didn't touch. */
- $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
-
- /* Replace the old tokens with the new ones. */
- array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
-
- /* Adjust argument start so that it won't change from the
- current position for the next iteration. */
- $i = $is_arg_start;
- break;
-
- default:
- if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
- // function call
- if($this->security &&
- !in_array($token, $this->security_settings['IF_FUNCS'])) {
- $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
- }
- } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
- // variable function call
- $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
- } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
- // object or variable
- $token = $this->_parse_var_props($token);
- } elseif(is_numeric($token)) {
- // number, skip it
- } else {
- $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
- }
- break;
- }
- }
-
- if ($elseif)
- return '<?php elseif ('.implode(' ', $tokens).'): ?>';
- else
- return '<?php if ('.implode(' ', $tokens).'): ?>';
- }
-
-
- function _compile_arg_list($type, $name, $attrs, &$cache_code) {
- $arg_list = array();
-
- if (isset($type) && isset($name)
- && isset($this->_plugins[$type])
- && isset($this->_plugins[$type][$name])
- && empty($this->_plugins[$type][$name][4])
- && is_array($this->_plugins[$type][$name][5])
- ) {
- /* we have a list of parameters that should be cached */
- $_cache_attrs = $this->_plugins[$type][$name][5];
- $_count = $this->_cache_attrs_count++;
- $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
-
- } else {
- /* no parameters are cached */
- $_cache_attrs = null;
- }
-
- foreach ($attrs as $arg_name => $arg_value) {
- if (is_bool($arg_value))
- $arg_value = $arg_value ? 'true' : 'false';
- if (is_null($arg_value))
- $arg_value = 'null';
- if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
- $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
- } else {
- $arg_list[] = "'$arg_name' => $arg_value";
- }
- }
- return $arg_list;
- }
-
- /**
- * Parse is expression
- *
- * @param string $is_arg
- * @param array $tokens
- * @return array
- */
- function _parse_is_expr($is_arg, $tokens)
- {
- $expr_end = 0;
- $negate_expr = false;
-
- if (($first_token = array_shift($tokens)) == 'not') {
- $negate_expr = true;
- $expr_type = array_shift($tokens);
- } else
- $expr_type = $first_token;
-
- switch ($expr_type) {
- case 'even':
- if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
- } else
- $expr = "!(1 & $is_arg)";
- break;
-
- case 'odd':
- if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
- } else
- $expr = "(1 & $is_arg)";
- break;
-
- case 'div':
- if (@$tokens[$expr_end] == 'by') {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
- } else {
- $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
- }
- break;
-
- default:
- $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
-
- if ($negate_expr) {
- $expr = "!($expr)";
- }
-
- array_splice($tokens, 0, $expr_end, $expr);
-
- return $tokens;
- }
-
-
- /**
- * Parse attribute string
- *
- * @param string $tag_args
- * @return array
- */
- function _parse_attrs($tag_args)
- {
-
- /* Tokenize tag attributes. */
- preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
- )+ |
- [=]
- ~x', $tag_args, $match);
- $tokens = $match[0];
-
- $attrs = array();
- /* Parse state:
- 0 - expecting attribute name
- 1 - expecting '='
- 2 - expecting attribute value (not '=') */
- $state = 0;
-
- foreach ($tokens as $token) {
- switch ($state) {
- case 0:
- /* If the token is a valid identifier, we set attribute name
- and go to state 1. */
- if (preg_match('~^\w+$~', $token)) {
- $attr_name = $token;
- $state = 1;
- } else
- $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
- break;
-
- case 1:
- /* If the token is '=', then we go to state 2. */
- if ($token == '=') {
- $state = 2;
- } else
- $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
- break;
-
- case 2:
- /* If token is not '=', we set the attribute value and go to
- state 0. */
- if ($token != '=') {
- /* We booleanize the token if it's a non-quoted possible
- boolean value. */
- if (preg_match('~^(on|yes|true)$~', $token)) {
- $token = 'true';
- } else if (preg_match('~^(off|no|false)$~', $token)) {
- $token = 'false';
- } else if ($token == 'null') {
- $token = 'null';
- } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
- /* treat integer literally */
- } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
- /* treat as a string, double-quote it escaping quotes */
- $token = '"'.addslashes($token).'"';
- }
-
- $attrs[$attr_name] = $token;
- $state = 0;
- } else
- $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
- $last_token = $token;
- }
-
- if($state != 0) {
- if($state == 1) {
- $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
- } else {
- $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
- }
- }
-
- $this->_parse_vars_props($attrs);
-
- return $attrs;
- }
-
- /**
- * compile multiple variables and section properties tokens into
- * PHP code
- *
- * @param array $tokens
- */
- function _parse_vars_props(&$tokens)
- {
- foreach($tokens as $key => $val) {
- $tokens[$key] = $this->_parse_var_props($val);
- }
- }
-
- /**
- * compile single variable and section properties token into
- * PHP code
- *
- * @param string $val
- * @param string $tag_attrs
- * @return string
- */
- function _parse_var_props($val)
- {
- $val = trim($val);
-
- if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
- // $ variable or object
- $return = $this->_parse_var($match[1]);
- $modifiers = $match[2];
- if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
- $_default_mod_string = implode('|',(array)$this->default_modifiers);
- $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
- }
- $this->_parse_modifiers($return, $modifiers);
- return $return;
- } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // double quoted text
- preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
- $return = $this->_expand_quoted_text($match[1]);
- if($match[2] != '') {
- $this->_parse_modifiers($return, $match[2]);
- }
- return $return;
- }
- elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // numerical constant
- preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
- if($match[2] != '') {
- $this->_parse_modifiers($match[1], $match[2]);
- return $match[1];
- }
- }
- elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // single quoted text
- preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
- if($match[2] != '') {
- $this->_parse_modifiers($match[1], $match[2]);
- return $match[1];
- }
- }
- elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // config var
- return $this->_parse_conf_var($val);
- }
- elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
- // section var
- return $this->_parse_section_prop($val);
- }
- elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
- // literal string
- return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
- }
- return $val;
- }
-
- /**
- * expand quoted text with embedded variables
- *
- * @param string $var_expr
- * @return string
- */
- function _expand_quoted_text($var_expr)
- {
- // if contains unescaped $, expand it
- if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
- $_match = $_match[0];
- $_replace = array();
- foreach($_match as $_var) {
- $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
- }
- $var_expr = strtr($var_expr, $_replace);
- $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
- } else {
- $_return = $var_expr;
- }
- // replace double quoted literal string with single quotes
- $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
- return $_return;
- }
-
- /**
- * parse variable expression into PHP code
- *
- * @param string $var_expr
- * @param string $output
- * @return string
- */
- function _parse_var($var_expr)
- {
- $_has_math = false;
- $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
-
- if(count($_math_vars) > 1) {
- $_first_var = "";
- $_complete_var = "";
- $_output = "";
- // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
- foreach($_math_vars as $_k => $_math_var) {
- $_math_var = $_math_vars[$_k];
-
- if(!empty($_math_var) || is_numeric($_math_var)) {
- // hit a math operator, so process the stuff which came before it
- if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
- $_has_math = true;
- if(!empty($_complete_var) || is_numeric($_complete_var)) {
- $_output .= $this->_parse_var($_complete_var);
- }
-
- // just output the math operator to php
- $_output .= $_math_var;
-
- if(empty($_first_var))
- $_first_var = $_complete_var;
-
- $_complete_var = "";
- } else {
- $_complete_var .= $_math_var;
- }
- }
- }
- if($_has_math) {
- if(!empty($_complete_var) || is_numeric($_complete_var))
- $_output .= $this->_parse_var($_complete_var);
-
- // get the modifiers working (only the last var from math + modifier is left)
- $var_expr = $_complete_var;
- }
- }
-
- // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
- if(is_numeric(substr($var_expr, 0, 1)))
- $_var_ref = $var_expr;
- else
- $_var_ref = substr($var_expr, 1);
-
- if(!$_has_math) {
-
- // get [foo] and .foo and ->foo and (...) pieces
- preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
-
- $_indexes = $match[0];
- $_var_name = array_shift($_indexes);
-
- /* Handle $smarty.* variable references as a special case. */
- if ($_var_name == 'smarty') {
- /*
- * If the reference could be compiled, use the compiled output;
- * otherwise, fall back on the $smarty variable generated at
- * run-time.
- */
- if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
- $_output = $smarty_ref;
- } else {
- $_var_name = substr(array_shift($_indexes), 1);
- $_output = "\$this->_smarty_vars['$_var_name']";
- }
- } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
- // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
- if(count($_indexes) > 0)
- {
- $_var_name .= implode("", $_indexes);
- $_indexes = array();
- }
- $_output = $_var_name;
- } else {
- $_output = "\$this->_tpl_vars['$_var_name']";
- }
-
- foreach ($_indexes as $_index) {
- if (substr($_index, 0, 1) == '[') {
- $_index = substr($_index, 1, -1);
- if (is_numeric($_index)) {
- $_output .= "[$_index]";
- } elseif (substr($_index, 0, 1) == '$') {
- if (strpos($_index, '.') !== false) {
- $_output .= '[' . $this->_parse_var($_index) . ']';
- } else {
- $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
- }
- } else {
- $_var_parts = explode('.', $_index);
- $_var_section = $_var_parts[0];
- $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
- $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
- }
- } else if (substr($_index, 0, 1) == '.') {
- if (substr($_index, 1, 1) == '$')
- $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
- else
- $_output .= "['" . substr($_index, 1) . "']";
- } else if (substr($_index,0,2) == '->') {
- if(substr($_index,2,2) == '__') {
- $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
- } elseif($this->security && substr($_index, 2, 1) == '_') {
- $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
- } elseif (substr($_index, 2, 1) == '$') {
- if ($this->security) {
- $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
- } else {
- $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
- }
- } else {
- $_output .= $_index;
- }
- } elseif (substr($_index, 0, 1) == '(') {
- $_index = $this->_parse_parenth_args($_index);
- $_output .= $_index;
- } else {
- $_output .= $_index;
- }
- }
- }
-
- return $_output;
- }
-
- /**
- * parse arguments in function call parenthesis
- *
- * @param string $parenth_args
- * @return string
- */
- function _parse_parenth_args($parenth_args)
- {
- preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
- $orig_vals = $match = $match[0];
- $this->_parse_vars_props($match);
- $replace = array();
- for ($i = 0, $count = count($match); $i < $count; $i++) {
- $replace[$orig_vals[$i]] = $match[$i];
- }
- return strtr($parenth_args, $replace);
- }
-
- /**
- * parse configuration variable expression into PHP code
- *
- * @param string $conf_var_expr
- */
- function _parse_conf_var($conf_var_expr)
- {
- $parts = explode('|', $conf_var_expr, 2);
- $var_ref = $parts[0];
- $modifiers = isset($parts[1]) ? $parts[1] : '';
-
- $var_name = substr($var_ref, 1, -1);
-
- $output = "\$this->_config[0]['vars']['$var_name']";
-
- $this->_parse_modifiers($output, $modifiers);
-
- return $output;
- }
-
- /**
- * parse section property expression into PHP code
- *
- * @param string $section_prop_expr
- * @return string
- */
- function _parse_section_prop($section_prop_expr)
- {
- $parts = explode('|', $section_prop_expr, 2);
- $var_ref = $parts[0];
- $modifiers = isset($parts[1]) ? $parts[1] : '';
-
- preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
- $section_name = $match[1];
- $prop_name = $match[2];
-
- $output = "\$this->_sections['$section_name']['$prop_name']";
-
- $this->_parse_modifiers($output, $modifiers);
-
- return $output;
- }
-
-
- /**
- * parse modifier chain into PHP code
- *
- * sets $output to parsed modified chain
- * @param string $output
- * @param string $modifier_string
- */
- function _parse_modifiers(&$output, $modifier_string)
- {
- preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
- list(, $_modifiers, $modifier_arg_strings) = $_match;
-
- for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
- $_modifier_name = $_modifiers[$_i];
-
- if($_modifier_name == 'smarty') {
- // skip smarty modifier
- continue;
- }
-
- preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
- $_modifier_args = $_match[1];
-
- if (substr($_modifier_name, 0, 1) == '@') {
- $_map_array = false;
- $_modifier_name = substr($_modifier_name, 1);
- } else {
- $_map_array = true;
- }
-
- if (empty($this->_plugins['modifier'][$_modifier_name])
- && !$this->_get_plugin_filepath('modifier', $_modifier_name)
- && function_exists($_modifier_name)) {
- if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
- $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
- } else {
- $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false);
- }
- }
- $this->_add_plugin('modifier', $_modifier_name);
-
- $this->_parse_vars_props($_modifier_args);
-
- if($_modifier_name == 'default') {
- // supress notifications of default modifier vars and args
- if(substr($output, 0, 1) == '$') {
- $output = '@' . $output;
- }
- if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
- $_modifier_args[0] = '@' . $_modifier_args[0];
- }
- }
- if (count($_modifier_args) > 0)
- $_modifier_args = ', '.implode(', ', $_modifier_args);
- else
- $_modifier_args = '';
-
- if ($_map_array) {
- $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
-
- } else {
-
- $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
-
- }
- }
- }
-
-
- /**
- * add plugin
- *
- * @param string $type
- * @param string $name
- * @param boolean? $delayed_loading
- */
- function _add_plugin($type, $name, $delayed_loading = null)
- {
- if (!isset($this->_plugin_info[$type])) {
- $this->_plugin_info[$type] = array();
- }
- if (!isset($this->_plugin_info[$type][$name])) {
- $this->_plugin_info[$type][$name] = array($this->_current_file,
- $this->_current_line_no,
- $delayed_loading);
- }
- }
-
-
- /**
- * Compiles references of type $smarty.foo
- *
- * @param string $indexes
- * @return string
- */
- function _compile_smarty_ref(&$indexes)
- {
- /* Extract the reference name. */
- $_ref = substr($indexes[0], 1);
- foreach($indexes as $_index_no=>$_index) {
- if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
- $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
- }
- }
-
- switch ($_ref) {
- case 'now':
- $compiled_ref = 'time()';
- $_max_index = 1;
- break;
-
- case 'foreach':
- array_shift($indexes);
- $_var = $this->_parse_var_props(substr($indexes[0], 1));
- $_propname = substr($indexes[1], 1);
- $_max_index = 1;
- switch ($_propname) {
- case 'index':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
- break;
-
- case 'first':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
- break;
-
- case 'last':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
- break;
-
- case 'show':
- array_shift($indexes);
- $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
- break;
-
- default:
- unset($_max_index);
- $compiled_ref = "\$this->_foreach[$_var]";
- }
- break;
-
- case 'section':
- array_shift($indexes);
- $_var = $this->_parse_var_props(substr($indexes[0], 1));
- $compiled_ref = "\$this->_sections[$_var]";
- break;
-
- case 'get':
- if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
- $this->_syntax_error("(secure mode) super global access not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- $compiled_ref = "\$_GET";
- break;
-
- case 'post':
- if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
- $this->_syntax_error("(secure mode) super global access not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- $compiled_ref = "\$_POST";
- break;
-
- case 'cookies':
- if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
- $this->_syntax_error("(secure mode) super global access not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- $compiled_ref = "\$_COOKIE";
- break;
-
- case 'env':
- if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
- $this->_syntax_error("(secure mode) super global access not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- $compiled_ref = "\$_ENV";
- break;
-
- case 'server':
- if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
- $this->_syntax_error("(secure mode) super global access not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- $compiled_ref = "\$_SERVER";
- break;
-
- case 'session':
- if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
- $this->_syntax_error("(secure mode) super global access not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- $compiled_ref = "\$_SESSION";
- break;
-
- /*
- * These cases are handled either at run-time or elsewhere in the
- * compiler.
- */
- case 'request':
- if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
- $this->_syntax_error("(secure mode) super global access not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- if ($this->request_use_auto_globals) {
- $compiled_ref = "\$_REQUEST";
- break;
- } else {
- $this->_init_smarty_vars = true;
- }
- return null;
-
- case 'capture':
- return null;
-
- case 'template':
- $compiled_ref = "'$this->_current_file'";
- $_max_index = 1;
- break;
-
- case 'version':
- $compiled_ref = "'$this->_version'";
- $_max_index = 1;
- break;
-
- case 'const':
- if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
- $this->_syntax_error("(secure mode) constants not permitted",
- E_USER_WARNING, __FILE__, __LINE__);
- return;
- }
- array_shift($indexes);
- if (preg_match('!^\.\w+$!', $indexes[0])) {
- $compiled_ref = '@' . substr($indexes[0], 1);
- } else {
- $_val = $this->_parse_var_props(substr($indexes[0], 1));
- $compiled_ref = '@constant(' . $_val . ')';
- }
- $_max_index = 1;
- break;
-
- case 'config':
- $compiled_ref = "\$this->_config[0]['vars']";
- $_max_index = 3;
- break;
-
- case 'ldelim':
- $compiled_ref = "'$this->left_delimiter'";
- break;
-
- case 'rdelim':
- $compiled_ref = "'$this->right_delimiter'";
- break;
-
- default:
- $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
- break;
- }
-
- if (isset($_max_index) && count($indexes) > $_max_index) {
- $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
- }
-
- array_shift($indexes);
- return $compiled_ref;
- }
-
- /**
- * compiles call to plugin of type $type with name $name
- * returns a string containing the function-name or method call
- * without the paramter-list that would have follow to make the
- * call valid php-syntax
- *
- * @param string $type
- * @param string $name
- * @return string
- */
- function _compile_plugin_call($type, $name) {
- if (isset($this->_plugins[$type][$name])) {
- /* plugin loaded */
- if (is_array($this->_plugins[$type][$name][0])) {
- return ((is_object($this->_plugins[$type][$name][0][0])) ?
- "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */
- : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */
- ). $this->_plugins[$type][$name][0][1];
-
- } else {
- /* function callback */
- return $this->_plugins[$type][$name][0];
-
- }
- } else {
- /* plugin not loaded -> auto-loadable-plugin */
- return 'smarty_'.$type.'_'.$name;
-
- }
- }
-
- /**
- * load pre- and post-filters
- */
- function _load_filters()
- {
- if (count($this->_plugins['prefilter']) > 0) {
- foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
- if ($prefilter === false) {
- unset($this->_plugins['prefilter'][$filter_name]);
- $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- }
- }
- }
- if (count($this->_plugins['postfilter']) > 0) {
- foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
- if ($postfilter === false) {
- unset($this->_plugins['postfilter'][$filter_name]);
- $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
- require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
- smarty_core_load_plugins($_params, $this);
- }
- }
- }
- }
-
-
- /**
- * Quote subpattern references
- *
- * @param string $string
- * @return string
- */
- function _quote_replace($string)
- {
- return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
- }
-
- /**
- * display Smarty syntax error
- *
- * @param string $error_msg
- * @param integer $error_type
- * @param string $file
- * @param integer $line
- */
- function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
- {
- $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
- }
-
-
- /**
- * check if the compilation changes from cacheable to
- * non-cacheable state with the beginning of the current
- * plugin. return php-code to reflect the transition.
- * @return string
- */
- function _push_cacheable_state($type, $name) {
- $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
- if ($_cacheable
- || 0<$this->_cacheable_state++) return '';
- if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
- $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
- . $this->_cache_serial . '#' . $this->_nocache_count
- . '}\'; endif;';
- return $_ret;
- }
-
-
- /**
- * check if the compilation changes from non-cacheable to
- * cacheable state with the end of the current plugin return
- * php-code to reflect the transition.
- * @return string
- */
- function _pop_cacheable_state($type, $name) {
- $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
- if ($_cacheable
- || --$this->_cacheable_state>0) return '';
- return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
- . $this->_cache_serial . '#' . ($this->_nocache_count++)
- . '}\'; endif;';
- }
-
-
- /**
- * push opening tag-name, file-name and line-number on the tag-stack
- * @param string the opening tag's name
- */
- function _push_tag($open_tag)
- {
- array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
- }
-
- /**
- * pop closing tag-name
- * raise an error if this stack-top doesn't match with the closing tag
- * @param string the closing tag's name
- * @return string the opening tag's name
- */
- function _pop_tag($close_tag)
- {
- $message = '';
- if (count($this->_tag_stack)>0) {
- list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
- if ($close_tag == $_open_tag) {
- return $_open_tag;
- }
- if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
- return $this->_pop_tag($close_tag);
- }
- if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
- $this->_pop_tag($close_tag);
- return $_open_tag;
- }
- if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
- $this->_pop_tag($close_tag);
- return $_open_tag;
- }
- if ($_open_tag == 'else' || $_open_tag == 'elseif') {
- $_open_tag = 'if';
- } elseif ($_open_tag == 'sectionelse') {
- $_open_tag = 'section';
- } elseif ($_open_tag == 'foreachelse') {
- $_open_tag = 'foreach';
- }
- $message = " expected {/$_open_tag} (opened line $_line_no).";
- }
- $this->_syntax_error("mismatched tag {/$close_tag}.$message",
- E_USER_ERROR, __FILE__, __LINE__);
- }
-
-}
-
-/**
- * compare to values by their string length
- *
- * @access private
- * @param string $a
- * @param string $b
- * @return 0|-1|1
- */
-function _smarty_sort_length($a, $b)
-{
- if($a == $b)
- return 0;
-
- if(strlen($a) == strlen($b))
- return ($a > $b) ? -1 : 1;
-
- return (strlen($a) > strlen($b)) ? -1 : 1;
-}
-
-
-/* vim: set et: */
-
-?>
+++ /dev/null
-{* Smarty *}
-{* debug.tpl, last updated version 2.1.0 *}
-{assign_debug_info}
-{capture assign=debug_output}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
- <title>Smarty Debug Console</title>
-{literal}
-<style type="text/css">
-/* <![CDATA[ */
-body, h1, h2, td, th, p {
- font-family: sans-serif;
- font-weight: normal;
- font-size: 0.9em;
- margin: 1px;
- padding: 0;
-}
-
-h1 {
- margin: 0;
- text-align: left;
- padding: 2px;
- background-color: #f0c040;
- color: black;
- font-weight: bold;
- font-size: 1.2em;
- }
-
-h2 {
- background-color: #9B410E;
- color: white;
- text-align: left;
- font-weight: bold;
- padding: 2px;
- border-top: 1px solid black;
-}
-
-body {
- background: black;
-}
-
-p, table, div {
- background: #f0ead8;
-}
-
-p {
- margin: 0;
- font-style: italic;
- text-align: center;
-}
-
-table {
- width: 100%;
-}
-
-th, td {
- font-family: monospace;
- vertical-align: top;
- text-align: left;
- width: 50%;
-}
-
-td {
- color: green;
-}
-
-.odd {
- background-color: #eeeeee;
-}
-
-.even {
- background-color: #fafafa;
-}
-
-.exectime {
- font-size: 0.8em;
- font-style: italic;
-}
-
-#table_assigned_vars th {
- color: blue;
-}
-
-#table_config_vars th {
- color: maroon;
-}
-/* ]]> */
-</style>
-{/literal}
-</head>
-<body>
-
-<h1>Smarty Debug Console</h1>
-
-<h2>included templates & config files (load time in seconds)</h2>
-
-<div>
-{section name=templates loop=$_debug_tpls}
- {section name=indent loop=$_debug_tpls[templates].depth} {/section}
- <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
- {$_debug_tpls[templates].filename|escape:html}</font>
- {if isset($_debug_tpls[templates].exec_time)}
- <span class="exectime">
- ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
- {if %templates.index% eq 0}(total){/if}
- </span>
- {/if}
- <br />
-{sectionelse}
- <p>no templates included</p>
-{/section}
-</div>
-
-<h2>assigned template variables</h2>
-
-<table id="table_assigned_vars">
- {section name=vars loop=$_debug_keys}
- <tr class="{cycle values="odd,even"}">
- <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
- <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
- {sectionelse}
- <tr><td><p>no template variables assigned</p></td></tr>
- {/section}
-</table>
-
-<h2>assigned config file variables (outer template scope)</h2>
-
-<table id="table_config_vars">
- {section name=config_vars loop=$_debug_config_keys}
- <tr class="{cycle values="odd,even"}">
- <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
- <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
- {sectionelse}
- <tr><td><p>no config vars assigned</p></td></tr>
- {/section}
-</table>
-</body>
-</html>
-{/capture}
-{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
- {$debug_output}
-{else}
-<script type="text/javascript">
-// <![CDATA[
- if ( self.name == '' ) {ldelim}
- var title = 'Console';
- {rdelim}
- else {ldelim}
- var title = 'Console_' + self.name;
- {rdelim}
- _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
- _smarty_console.document.write('{$debug_output|escape:'javascript'}');
- _smarty_console.document.close();
-// ]]>
-</script>
-{/if}
\ No newline at end of file
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * assemble filepath of requested plugin
- *
- * @param string $type
- * @param string $name
- * @return string|false
- */
-function smarty_core_assemble_plugin_filepath($params, &$smarty)
-{
- static $_filepaths_cache = array();
-
- $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
- if (isset($_filepaths_cache[$_plugin_filename])) {
- return $_filepaths_cache[$_plugin_filename];
- }
- $_return = false;
-
- foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
-
- $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
-
- // see if path is relative
- if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
- $_relative_paths[] = $_plugin_dir;
- // relative path, see if it is in the SMARTY_DIR
- if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
- $_return = SMARTY_DIR . $_plugin_filepath;
- break;
- }
- }
- // try relative to cwd (or absolute)
- if (@is_readable($_plugin_filepath)) {
- $_return = $_plugin_filepath;
- break;
- }
- }
-
- if($_return === false) {
- // still not found, try PHP include_path
- if(isset($_relative_paths)) {
- foreach ((array)$_relative_paths as $_plugin_dir) {
-
- $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
-
- $_params = array('file_path' => $_plugin_filepath);
- require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
- if(smarty_core_get_include_path($_params, $smarty)) {
- $_return = $_params['new_file_path'];
- break;
- }
- }
- }
- }
- $_filepaths_cache[$_plugin_filename] = $_return;
- return $_return;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty assign_smarty_interface core plugin
- *
- * Type: core<br>
- * Name: assign_smarty_interface<br>
- * Purpose: assign the $smarty interface variable
- * @param array Format: null
- * @param Smarty
- */
-function smarty_core_assign_smarty_interface($params, &$smarty)
-{
- if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
- return;
- }
-
- $_globals_map = array('g' => 'HTTP_GET_VARS',
- 'p' => 'HTTP_POST_VARS',
- 'c' => 'HTTP_COOKIE_VARS',
- 's' => 'HTTP_SERVER_VARS',
- 'e' => 'HTTP_ENV_VARS');
-
- $_smarty_vars_request = array();
-
- foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
- if (isset($_globals_map[$_c])) {
- $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
- }
- }
- $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
-
- $smarty->_smarty_vars['request'] = $_smarty_vars_request;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * create full directory structure
- *
- * @param string $dir
- */
-
-// $dir
-
-function smarty_core_create_dir_structure($params, &$smarty)
-{
- if (!file_exists($params['dir'])) {
- $_open_basedir_ini = ini_get('open_basedir');
-
- if (DIRECTORY_SEPARATOR=='/') {
- /* unix-style paths */
- $_dir = $params['dir'];
- $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
- $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
- if($_use_open_basedir = !empty($_open_basedir_ini)) {
- $_open_basedirs = explode(':', $_open_basedir_ini);
- }
-
- } else {
- /* other-style paths */
- $_dir = str_replace('\\','/', $params['dir']);
- $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
- if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
- /* leading "//" for network volume, or "[letter]:/" for full path */
- $_new_dir = $_root_dir[1];
- /* remove drive-letter from _dir_parts */
- if (isset($_root_dir[3])) array_shift($_dir_parts);
-
- } else {
- $_new_dir = str_replace('\\', '/', getcwd()).'/';
-
- }
-
- if($_use_open_basedir = !empty($_open_basedir_ini)) {
- $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
- }
-
- }
-
- /* all paths use "/" only from here */
- foreach ($_dir_parts as $_dir_part) {
- $_new_dir .= $_dir_part;
-
- if ($_use_open_basedir) {
- // do not attempt to test or make directories outside of open_basedir
- $_make_new_dir = false;
- foreach ($_open_basedirs as $_open_basedir) {
- if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
- $_make_new_dir = true;
- break;
- }
- }
- } else {
- $_make_new_dir = true;
- }
-
- if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
- $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
- return false;
- }
- $_new_dir .= '/';
- }
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty debug_console function plugin
- *
- * Type: core<br>
- * Name: display_debug_console<br>
- * Purpose: display the javascript debug console window
- * @param array Format: null
- * @param Smarty
- */
-function smarty_core_display_debug_console($params, &$smarty)
-{
- // we must force compile the debug template in case the environment
- // changed between separate applications.
-
- if(empty($smarty->debug_tpl)) {
- // set path to debug template from SMARTY_DIR
- $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
- if($smarty->security && is_file($smarty->debug_tpl)) {
- $smarty->secure_dir[] = realpath($smarty->debug_tpl);
- }
- $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
- }
-
- $_ldelim_orig = $smarty->left_delimiter;
- $_rdelim_orig = $smarty->right_delimiter;
-
- $smarty->left_delimiter = '{';
- $smarty->right_delimiter = '}';
-
- $_compile_id_orig = $smarty->_compile_id;
- $smarty->_compile_id = null;
-
- $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
- if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
- {
- ob_start();
- $smarty->_include($_compile_path);
- $_results = ob_get_contents();
- ob_end_clean();
- } else {
- $_results = '';
- }
-
- $smarty->_compile_id = $_compile_id_orig;
-
- $smarty->left_delimiter = $_ldelim_orig;
- $smarty->right_delimiter = $_rdelim_orig;
-
- return $_results;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Get path to file from include_path
- *
- * @param string $file_path
- * @param string $new_file_path
- * @return boolean
- * @staticvar array|null
- */
-
-// $file_path, &$new_file_path
-
-function smarty_core_get_include_path(&$params, &$smarty)
-{
- static $_path_array = null;
-
- if(!isset($_path_array)) {
- $_ini_include_path = ini_get('include_path');
-
- if(strstr($_ini_include_path,';')) {
- // windows pathnames
- $_path_array = explode(';',$_ini_include_path);
- } else {
- $_path_array = explode(':',$_ini_include_path);
- }
- }
- foreach ($_path_array as $_include_path) {
- if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
- $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
- return true;
- }
- }
- return false;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Get seconds and microseconds
- * @return double
- */
-function smarty_core_get_microtime($params, &$smarty)
-{
- $mtime = microtime();
- $mtime = explode(" ", $mtime);
- $mtime = (double)($mtime[1]) + (double)($mtime[0]);
- return ($mtime);
-}
-
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Retrieves PHP script resource
- *
- * sets $php_resource to the returned resource
- * @param string $resource
- * @param string $resource_type
- * @param $php_resource
- * @return boolean
- */
-
-function smarty_core_get_php_resource(&$params, &$smarty)
-{
-
- $params['resource_base_path'] = $smarty->trusted_dir;
- $smarty->_parse_resource_name($params, $smarty);
-
- /*
- * Find out if the resource exists.
- */
-
- if ($params['resource_type'] == 'file') {
- $_readable = false;
- if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
- $_readable = true;
- } else {
- // test for file in include_path
- $_params = array('file_path' => $params['resource_name']);
- require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
- if(smarty_core_get_include_path($_params, $smarty)) {
- $_include_path = $_params['new_file_path'];
- $_readable = true;
- }
- }
- } else if ($params['resource_type'] != 'file') {
- $_template_source = null;
- $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
- && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
- array($params['resource_name'], &$_template_source, &$smarty));
- }
-
- /*
- * Set the error function, depending on which class calls us.
- */
- if (method_exists($smarty, '_syntax_error')) {
- $_error_funcc = '_syntax_error';
- } else {
- $_error_funcc = 'trigger_error';
- }
-
- if ($_readable) {
- if ($smarty->security) {
- require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
- if (!smarty_core_is_trusted($params, $smarty)) {
- $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
- return false;
- }
- }
- } else {
- $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
- return false;
- }
-
- if ($params['resource_type'] == 'file') {
- $params['php_resource'] = $params['resource_name'];
- } else {
- $params['php_resource'] = $_template_source;
- }
- return true;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * determines if a resource is secure or not.
- *
- * @param string $resource_type
- * @param string $resource_name
- * @return boolean
- */
-
-// $resource_type, $resource_name
-
-function smarty_core_is_secure($params, &$smarty)
-{
- if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
- return true;
- }
-
- if ($params['resource_type'] == 'file') {
- $_rp = realpath($params['resource_name']);
- if (isset($params['resource_base_path'])) {
- foreach ((array)$params['resource_base_path'] as $curr_dir) {
- if ( ($_cd = realpath($curr_dir)) !== false &&
- strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
- substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
- return true;
- }
- }
- }
- if (!empty($smarty->secure_dir)) {
- foreach ((array)$smarty->secure_dir as $curr_dir) {
- if ( ($_cd = realpath($curr_dir)) !== false) {
- if($_cd == $_rp) {
- return true;
- } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
- substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
- return true;
- }
- }
- }
- }
- } else {
- // resource is not on local file system
- return call_user_func_array(
- $smarty->_plugins['resource'][$params['resource_type']][0][2],
- array($params['resource_name'], &$smarty));
- }
-
- return false;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * determines if a resource is trusted or not
- *
- * @param string $resource_type
- * @param string $resource_name
- * @return boolean
- */
-
- // $resource_type, $resource_name
-
-function smarty_core_is_trusted($params, &$smarty)
-{
- $_smarty_trusted = false;
- if ($params['resource_type'] == 'file') {
- if (!empty($smarty->trusted_dir)) {
- $_rp = realpath($params['resource_name']);
- foreach ((array)$smarty->trusted_dir as $curr_dir) {
- if (!empty($curr_dir) && is_readable ($curr_dir)) {
- $_cd = realpath($curr_dir);
- if (strncmp($_rp, $_cd, strlen($_cd)) == 0
- && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
- $_smarty_trusted = true;
- break;
- }
- }
- }
- }
-
- } else {
- // resource is not on local file system
- $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
- array($params['resource_name'], $smarty));
- }
-
- return $_smarty_trusted;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Load requested plugins
- *
- * @param array $plugins
- */
-
-// $plugins
-
-function smarty_core_load_plugins($params, &$smarty)
-{
-
- foreach ($params['plugins'] as $_plugin_info) {
- list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
- $_plugin = &$smarty->_plugins[$_type][$_name];
-
- /*
- * We do not load plugin more than once for each instance of Smarty.
- * The following code checks for that. The plugin can also be
- * registered dynamically at runtime, in which case template file
- * and line number will be unknown, so we fill them in.
- *
- * The final element of the info array is a flag that indicates
- * whether the dynamically registered plugin function has been
- * checked for existence yet or not.
- */
- if (isset($_plugin)) {
- if (empty($_plugin[3])) {
- if (!is_callable($_plugin[0])) {
- $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
- } else {
- $_plugin[1] = $_tpl_file;
- $_plugin[2] = $_tpl_line;
- $_plugin[3] = true;
- if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
- }
- }
- continue;
- } else if ($_type == 'insert') {
- /*
- * For backwards compatibility, we check for insert functions in
- * the symbol table before trying to load them as a plugin.
- */
- $_plugin_func = 'insert_' . $_name;
- if (function_exists($_plugin_func)) {
- $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
- continue;
- }
- }
-
- $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
-
- if (! $_found = ($_plugin_file != false)) {
- $_message = "could not load plugin file '$_type.$_name.php'\n";
- }
-
- /*
- * If plugin file is found, it -must- provide the properly named
- * plugin function. In case it doesn't, simply output the error and
- * do not fall back on any other method.
- */
- if ($_found) {
- include_once $_plugin_file;
-
- $_plugin_func = 'smarty_' . $_type . '_' . $_name;
- if (!function_exists($_plugin_func)) {
- $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
- continue;
- }
- }
- /*
- * In case of insert plugins, their code may be loaded later via
- * 'script' attribute.
- */
- else if ($_type == 'insert' && $_delayed_loading) {
- $_plugin_func = 'smarty_' . $_type . '_' . $_name;
- $_found = true;
- }
-
- /*
- * Plugin specific processing and error checking.
- */
- if (!$_found) {
- if ($_type == 'modifier') {
- /*
- * In case modifier falls back on using PHP functions
- * directly, we only allow those specified in the security
- * context.
- */
- if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
- $_message = "(secure mode) modifier '$_name' is not allowed";
- } else {
- if (!function_exists($_name)) {
- $_message = "modifier '$_name' is not implemented";
- } else {
- $_plugin_func = $_name;
- $_found = true;
- }
- }
- } else if ($_type == 'function') {
- /*
- * This is a catch-all situation.
- */
- $_message = "unknown tag - '$_name'";
- }
- }
-
- if ($_found) {
- $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
- } else {
- // output error
- $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
- }
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * load a resource plugin
- *
- * @param string $type
- */
-
-// $type
-
-function smarty_core_load_resource_plugin($params, &$smarty)
-{
- /*
- * Resource plugins are not quite like the other ones, so they are
- * handled differently. The first element of plugin info is the array of
- * functions provided by the plugin, the second one indicates whether
- * all of them exist or not.
- */
-
- $_plugin = &$smarty->_plugins['resource'][$params['type']];
- if (isset($_plugin)) {
- if (!$_plugin[1] && count($_plugin[0])) {
- $_plugin[1] = true;
- foreach ($_plugin[0] as $_plugin_func) {
- if (!is_callable($_plugin_func)) {
- $_plugin[1] = false;
- break;
- }
- }
- }
-
- if (!$_plugin[1]) {
- $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
- }
-
- return;
- }
-
- $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
- $_found = ($_plugin_file != false);
-
- if ($_found) { /*
- * If the plugin file is found, it -must- provide the properly named
- * plugin functions.
- */
- include_once($_plugin_file);
-
- /*
- * Locate functions that we require the plugin to provide.
- */
- $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
- $_resource_funcs = array();
- foreach ($_resource_ops as $_op) {
- $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
- if (!function_exists($_plugin_func)) {
- $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
- return;
- } else {
- $_resource_funcs[] = $_plugin_func;
- }
- }
-
- $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Replace cached inserts with the actual results
- *
- * @param string $results
- * @return string
- */
-function smarty_core_process_cached_inserts($params, &$smarty)
-{
- preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
- $params['results'], $match);
- list($cached_inserts, $insert_args) = $match;
-
- for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
- if ($smarty->debugging) {
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $debug_start_time = smarty_core_get_microtime($_params, $smarty);
- }
-
- $args = unserialize($insert_args[$i]);
- $name = $args['name'];
-
- if (isset($args['script'])) {
- $_params = array('resource_name' => $smarty->_dequote($args['script']));
- require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
- if(!smarty_core_get_php_resource($_params, $smarty)) {
- return false;
- }
- $resource_type = $_params['resource_type'];
- $php_resource = $_params['php_resource'];
-
-
- if ($resource_type == 'file') {
- $smarty->_include($php_resource, true);
- } else {
- $smarty->_eval($php_resource);
- }
- }
-
- $function_name = $smarty->_plugins['insert'][$name][0];
- if (empty($args['assign'])) {
- $replace = $function_name($args, $smarty);
- } else {
- $smarty->assign($args['assign'], $function_name($args, $smarty));
- $replace = '';
- }
-
- $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
- if ($smarty->debugging) {
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $smarty->_smarty_debug_info[] = array('type' => 'insert',
- 'filename' => 'insert_'.$name,
- 'depth' => $smarty->_inclusion_depth,
- 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
- }
- }
-
- return $params['results'];
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Replace nocache-tags by results of the corresponding non-cacheable
- * functions and return it
- *
- * @param string $compiled_tpl
- * @param string $cached_source
- * @return string
- */
-
-function smarty_core_process_compiled_include($params, &$smarty)
-{
- $_cache_including = $smarty->_cache_including;
- $smarty->_cache_including = true;
-
- $_return = $params['results'];
-
- foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
- $smarty->_include($_include_file_path, true);
- }
-
- foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
- $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
- array(&$smarty, '_process_compiled_include_callback'),
- $_return);
- }
- $smarty->_cache_including = $_cache_including;
- return $_return;
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * read a cache file, determine if it needs to be
- * regenerated or not
- *
- * @param string $tpl_file
- * @param string $cache_id
- * @param string $compile_id
- * @param string $results
- * @return boolean
- */
-
-// $tpl_file, $cache_id, $compile_id, &$results
-
-function smarty_core_read_cache_file(&$params, &$smarty)
-{
- static $content_cache = array();
-
- if ($smarty->force_compile) {
- // force compile enabled, always regenerate
- return false;
- }
-
- if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
- list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
- return true;
- }
-
- if (!empty($smarty->cache_handler_func)) {
- // use cache_handler function
- call_user_func_array($smarty->cache_handler_func,
- array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
- } else {
- // use local cache file
- $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
- $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
- $params['results'] = $smarty->_read_file($_cache_file);
- }
-
- if (empty($params['results'])) {
- // nothing to parse (error?), regenerate cache
- return false;
- }
-
- $_contents = $params['results'];
- $_info_start = strpos($_contents, "\n") + 1;
- $_info_len = (int)substr($_contents, 0, $_info_start - 1);
- $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
- $params['results'] = substr($_contents, $_info_start + $_info_len);
-
- if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
- // caching by expiration time
- if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
- // cache expired, regenerate
- return false;
- }
- } else {
- // caching by lifetime
- if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
- // cache expired, regenerate
- return false;
- }
- }
-
- if ($smarty->compile_check) {
- $_params = array('get_source' => false, 'quiet'=>true);
- foreach (array_keys($_cache_info['template']) as $_template_dep) {
- $_params['resource_name'] = $_template_dep;
- if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
- // template file has changed, regenerate cache
- return false;
- }
- }
-
- if (isset($_cache_info['config'])) {
- $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
- foreach (array_keys($_cache_info['config']) as $_config_dep) {
- $_params['resource_name'] = $_config_dep;
- if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
- // config file has changed, regenerate cache
- return false;
- }
- }
- }
- }
-
- $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
-
- $smarty->_cache_info = $_cache_info;
- return true;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * delete an automagically created file by name and id
- *
- * @param string $auto_base
- * @param string $auto_source
- * @param string $auto_id
- * @param integer $exp_time
- * @return boolean
- */
-
-// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
-
-function smarty_core_rm_auto($params, &$smarty)
-{
- if (!@is_dir($params['auto_base']))
- return false;
-
- if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
- $_params = array(
- 'dirname' => $params['auto_base'],
- 'level' => 0,
- 'exp_time' => $params['exp_time']
- );
- require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
- $_res = smarty_core_rmdir($_params, $smarty);
- } else {
- $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
-
- if(isset($params['auto_source'])) {
- if (isset($params['extensions'])) {
- $_res = false;
- foreach ((array)$params['extensions'] as $_extension)
- $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
- } else {
- $_res = $smarty->_unlink($_tname, $params['exp_time']);
- }
- } elseif ($smarty->use_sub_dirs) {
- $_params = array(
- 'dirname' => $_tname,
- 'level' => 1,
- 'exp_time' => $params['exp_time']
- );
- require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
- $_res = smarty_core_rmdir($_params, $smarty);
- } else {
- // remove matching file names
- $_handle = opendir($params['auto_base']);
- $_res = true;
- while (false !== ($_filename = readdir($_handle))) {
- if($_filename == '.' || $_filename == '..') {
- continue;
- } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
- $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
- }
- }
- }
- }
-
- return $_res;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * delete a dir recursively (level=0 -> keep root)
- * WARNING: no tests, it will try to remove what you tell it!
- *
- * @param string $dirname
- * @param integer $level
- * @param integer $exp_time
- * @return boolean
- */
-
-// $dirname, $level = 1, $exp_time = null
-
-function smarty_core_rmdir($params, &$smarty)
-{
- if(!isset($params['level'])) { $params['level'] = 1; }
- if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
-
- if($_handle = @opendir($params['dirname'])) {
-
- while (false !== ($_entry = readdir($_handle))) {
- if ($_entry != '.' && $_entry != '..') {
- if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
- $_params = array(
- 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
- 'level' => $params['level'] + 1,
- 'exp_time' => $params['exp_time']
- );
- smarty_core_rmdir($_params, $smarty);
- }
- else {
- $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
- }
- }
- }
- closedir($_handle);
- }
-
- if ($params['level']) {
- return @rmdir($params['dirname']);
- }
- return (bool)$_handle;
-
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Handle insert tags
- *
- * @param array $args
- * @return string
- */
-function smarty_core_run_insert_handler($params, &$smarty)
-{
-
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- if ($smarty->debugging) {
- $_params = array();
- $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
- }
-
- if ($smarty->caching) {
- $_arg_string = serialize($params['args']);
- $_name = $params['args']['name'];
- if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
- $smarty->_cache_info['insert_tags'][$_name] = array('insert',
- $_name,
- $smarty->_plugins['insert'][$_name][1],
- $smarty->_plugins['insert'][$_name][2],
- !empty($params['args']['script']) ? true : false);
- }
- return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
- } else {
- if (isset($params['args']['script'])) {
- $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
- require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
- if(!smarty_core_get_php_resource($_params, $smarty)) {
- return false;
- }
-
- if ($_params['resource_type'] == 'file') {
- $smarty->_include($_params['php_resource'], true);
- } else {
- $smarty->_eval($_params['php_resource']);
- }
- unset($params['args']['script']);
- }
-
- $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
- $_content = $_funcname($params['args'], $smarty);
- if ($smarty->debugging) {
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $smarty->_smarty_debug_info[] = array('type' => 'insert',
- 'filename' => 'insert_'.$params['args']['name'],
- 'depth' => $smarty->_inclusion_depth,
- 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
- }
-
- if (!empty($params['args']["assign"])) {
- $smarty->assign($params['args']["assign"], $_content);
- } else {
- return $_content;
- }
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * called for included php files within templates
- *
- * @param string $smarty_file
- * @param string $smarty_assign variable to assign the included template's
- * output into
- * @param boolean $smarty_once uses include_once if this is true
- * @param array $smarty_include_vars associative array of vars from
- * {include file="blah" var=$var}
- */
-
-// $file, $assign, $once, $_smarty_include_vars
-
-function smarty_core_smarty_include_php($params, &$smarty)
-{
- $_params = array('resource_name' => $params['smarty_file']);
- require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
- smarty_core_get_php_resource($_params, $smarty);
- $_smarty_resource_type = $_params['resource_type'];
- $_smarty_php_resource = $_params['php_resource'];
-
- if (!empty($params['smarty_assign'])) {
- ob_start();
- if ($_smarty_resource_type == 'file') {
- $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
- } else {
- $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
- }
- $smarty->assign($params['smarty_assign'], ob_get_contents());
- ob_end_clean();
- } else {
- if ($_smarty_resource_type == 'file') {
- $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
- } else {
- $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
- }
- }
-}
-
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Prepend the cache information to the cache file
- * and write it
- *
- * @param string $tpl_file
- * @param string $cache_id
- * @param string $compile_id
- * @param string $results
- * @return true|null
- */
-
- // $tpl_file, $cache_id, $compile_id, $results
-
-function smarty_core_write_cache_file($params, &$smarty)
-{
-
- // put timestamp in cache header
- $smarty->_cache_info['timestamp'] = time();
- if ($smarty->cache_lifetime > -1){
- // expiration set
- $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
- } else {
- // cache will never expire
- $smarty->_cache_info['expires'] = -1;
- }
-
- // collapse nocache.../nocache-tags
- if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
- // remove everything between every pair of outermost noache.../nocache-tags
- // and replace it by a single nocache-tag
- // this new nocache-tag will be replaced by dynamic contents in
- // smarty_core_process_compiled_includes() on a cache-read
-
- $match_count = count($match[0]);
- $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
-
- $level = 0;
- $j = 0;
- for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
- if ($results[$i] == $match[0][$j]) {
- // nocache tag
- if ($match[1][$j]) { // closing tag
- $level--;
- unset($results[$i]);
- } else { // opening tag
- if ($level++ > 0) unset($results[$i]);
- }
- $j++;
- } elseif ($level > 0) {
- unset($results[$i]);
- }
- }
- $params['results'] = implode('', $results);
- }
- $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
-
- // prepend the cache header info into cache file
- $_cache_info = serialize($smarty->_cache_info);
- $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
-
- if (!empty($smarty->cache_handler_func)) {
- // use cache_handler function
- call_user_func_array($smarty->cache_handler_func,
- array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
- } else {
- // use local cache file
-
- if(!@is_writable($smarty->cache_dir)) {
- // cache_dir not writable, see if it exists
- if(!@is_dir($smarty->cache_dir)) {
- $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
- return false;
- }
- $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
- return false;
- }
-
- $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
- $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
- $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
- require_once(SMARTY_CORE_DIR . 'core.write_file.php');
- smarty_core_write_file($_params, $smarty);
- return true;
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Extract non-cacheable parts out of compiled template and write it
- *
- * @param string $compile_path
- * @param string $template_compiled
- * @return boolean
- */
-
-function smarty_core_write_compiled_include($params, &$smarty)
-{
- $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
- $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
-
- preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
- $params['compiled_content'], $_match_source, PREG_SET_ORDER);
-
- // no nocache-parts found: done
- if (count($_match_source)==0) return;
-
- // convert the matched php-code to functions
- $_include_compiled = "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
- $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
-
- $_compile_path = $params['include_file_path'];
-
- $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
- $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
-
- $_include_compiled .= $params['plugins_code'];
- $_include_compiled .= "<?php";
-
- $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
- for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
- $_match =& $_match_source[$_i];
- $source = $_match[4];
- if ($this_varname == '_smarty') {
- /* rename $this to $_smarty in the sourcecode */
- $tokens = token_get_all('<?php ' . $_match[4]);
-
- /* remove trailing <?php */
- $open_tag = '';
- while ($tokens) {
- $token = array_shift($tokens);
- if (is_array($token)) {
- $open_tag .= $token[1];
- } else {
- $open_tag .= $token;
- }
- if ($open_tag == '<?php ') break;
- }
-
- for ($i=0, $count = count($tokens); $i < $count; $i++) {
- if (is_array($tokens[$i])) {
- if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
- $tokens[$i] = '$' . $this_varname;
- } else {
- $tokens[$i] = $tokens[$i][1];
- }
- }
- }
- $source = implode('', $tokens);
- }
-
- /* add function to compiled include */
- $_include_compiled .= "
-function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
-{
-$source
-}
-
-";
- }
- $_include_compiled .= "\n\n?>\n";
-
- $_params = array('filename' => $_compile_path,
- 'contents' => $_include_compiled, 'create_dirs' => true);
-
- require_once(SMARTY_CORE_DIR . 'core.write_file.php');
- smarty_core_write_file($_params, $smarty);
- return true;
-}
-
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * write the compiled resource
- *
- * @param string $compile_path
- * @param string $compiled_content
- * @return true
- */
-function smarty_core_write_compiled_resource($params, &$smarty)
-{
- if(!@is_writable($smarty->compile_dir)) {
- // compile_dir not writable, see if it exists
- if(!@is_dir($smarty->compile_dir)) {
- $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
- return false;
- }
- $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
- return false;
- }
-
- $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
- require_once(SMARTY_CORE_DIR . 'core.write_file.php');
- smarty_core_write_file($_params, $smarty);
- return true;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * write out a file to disk
- *
- * @param string $filename
- * @param string $contents
- * @param boolean $create_dirs
- * @return boolean
- */
-function smarty_core_write_file($params, &$smarty)
-{
- $_dirname = dirname($params['filename']);
-
- if ($params['create_dirs']) {
- $_params = array('dir' => $_dirname);
- require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
- smarty_core_create_dir_structure($_params, $smarty);
- }
-
- // write to tmp file, then rename it to avoid file locking race condition
- $_tmp_file = tempnam($_dirname, 'wrt');
-
- if (!($fd = @fopen($_tmp_file, 'wb'))) {
- $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
- if (!($fd = @fopen($_tmp_file, 'wb'))) {
- $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
- return false;
- }
- }
-
- fwrite($fd, $params['contents']);
- fclose($fd);
-
- if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
- // On platforms and filesystems that cannot overwrite with rename()
- // delete the file before renaming it -- because windows always suffers
- // this, it is short-circuited to avoid the initial rename() attempt
- @unlink($params['filename']);
- @rename($_tmp_file, $params['filename']);
- }
- @chmod($params['filename'], $smarty->_file_perms);
-
- return true;
-}
-
-/* vim: set expandtab: */
-
-?>
\ No newline at end of file
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty {textformat}{/textformat} block plugin
- *
- * Type: block function<br>
- * Name: textformat<br>
- * Purpose: format text a certain way with preset styles
- * or custom wrap/indent settings<br>
- * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
- * (Smarty online manual)
- * @param array
- * <pre>
- * Params: style: string (email)
- * indent: integer (0)
- * wrap: integer (80)
- * wrap_char string ("\n")
- * indent_char: string (" ")
- * wrap_boundary: boolean (true)
- * </pre>
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string contents of the block
- * @param Smarty clever simulation of a method
- * @return string string $content re-formatted
- */
-function smarty_block_textformat($params, $content, &$smarty)
-{
- if (is_null($content)) {
- return;
- }
-
- $style = null;
- $indent = 0;
- $indent_first = 0;
- $indent_char = ' ';
- $wrap = 80;
- $wrap_char = "\n";
- $wrap_cut = false;
- $assign = null;
-
- foreach ($params as $_key => $_val) {
- switch ($_key) {
- case 'style':
- case 'indent_char':
- case 'wrap_char':
- case 'assign':
- $$_key = (string)$_val;
- break;
-
- case 'indent':
- case 'indent_first':
- case 'wrap':
- $$_key = (int)$_val;
- break;
-
- case 'wrap_cut':
- $$_key = (bool)$_val;
- break;
-
- default:
- $smarty->trigger_error("textformat: unknown attribute '$_key'");
- }
- }
-
- if ($style == 'email') {
- $wrap = 72;
- }
-
- // split into paragraphs
- $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
- $_output = '';
-
- for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
- if ($_paragraphs[$_x] == '') {
- continue;
- }
- // convert mult. spaces & special chars to single space
- $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
- // indent first line
- if($indent_first > 0) {
- $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
- }
- // wordwrap sentences
- $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
- // indent lines
- if($indent > 0) {
- $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
- }
- }
- $_output = implode($wrap_char . $wrap_char, $_paragraphs);
-
- return $assign ? $smarty->assign($assign, $_output) : $_output;
-
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty {assign} compiler function plugin
- *
- * Type: compiler function<br>
- * Name: assign<br>
- * Purpose: assign a value to a template variable
- * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com> (initial author)
- * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
- * @param string containing var-attribute and value-attribute
- * @param Smarty_Compiler
- */
-function smarty_compiler_assign($tag_attrs, &$compiler)
-{
- $_params = $compiler->_parse_attrs($tag_attrs);
-
- if (!isset($_params['var'])) {
- $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
- return;
- }
-
- if (!isset($_params['value'])) {
- $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
- return;
- }
-
- return "\$this->assign({$_params['var']}, {$_params['value']});";
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty {assign_debug_info} function plugin
- *
- * Type: function<br>
- * Name: assign_debug_info<br>
- * Purpose: assign debug info to the template<br>
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
- * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
- * @param Smarty
- */
-function smarty_function_assign_debug_info($params, &$smarty)
-{
- $assigned_vars = $smarty->_tpl_vars;
- ksort($assigned_vars);
- if (@is_array($smarty->_config[0])) {
- $config_vars = $smarty->_config[0];
- ksort($config_vars);
- $smarty->assign("_debug_config_keys", array_keys($config_vars));
- $smarty->assign("_debug_config_vals", array_values($config_vars));
- }
-
- $included_templates = $smarty->_smarty_debug_info;
-
- $smarty->assign("_debug_keys", array_keys($assigned_vars));
- $smarty->assign("_debug_vals", array_values($assigned_vars));
-
- $smarty->assign("_debug_tpls", $included_templates);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty {config_load} function plugin
- *
- * Type: function<br>
- * Name: config_load<br>
- * Purpose: load config file vars
- * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
- * @param array Format:
- * <pre>
- * array('file' => required config file name,
- * 'section' => optional config file section to load
- * 'scope' => local/parent/global
- * 'global' => overrides scope, setting to parent if true)
- * </pre>
- * @param Smarty
- */
-function smarty_function_config_load($params, &$smarty)
-{
- if ($smarty->debugging) {
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
- }
-
- $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
- $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
- $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
- $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
-
- if (!isset($_file) || strlen($_file) == 0) {
- $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
- }
-
- if (isset($_scope)) {
- if ($_scope != 'local' &&
- $_scope != 'parent' &&
- $_scope != 'global') {
- $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
- }
- } else {
- if ($_global) {
- $_scope = 'parent';
- } else {
- $_scope = 'local';
- }
- }
-
- $_params = array('resource_name' => $_file,
- 'resource_base_path' => $smarty->config_dir,
- 'get_source' => false);
- $smarty->_parse_resource_name($_params);
- $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
- if (isset($_section))
- $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
- else
- $_compile_file = $smarty->_get_compile_path($_file_path);
-
- if($smarty->force_compile || !file_exists($_compile_file)) {
- $_compile = true;
- } elseif ($smarty->compile_check) {
- $_params = array('resource_name' => $_file,
- 'resource_base_path' => $smarty->config_dir,
- 'get_source' => false);
- $_compile = $smarty->_fetch_resource_info($_params) &&
- $_params['resource_timestamp'] > filemtime($_compile_file);
- } else {
- $_compile = false;
- }
-
- if($_compile) {
- // compile config file
- if(!is_object($smarty->_conf_obj)) {
- require_once SMARTY_DIR . $smarty->config_class . '.class.php';
- $smarty->_conf_obj = new $smarty->config_class();
- $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
- $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
- $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
- $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
- }
-
- $_params = array('resource_name' => $_file,
- 'resource_base_path' => $smarty->config_dir,
- $_params['get_source'] = true);
- if (!$smarty->_fetch_resource_info($_params)) {
- return;
- }
- $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
- $_config_vars = array_merge($smarty->_conf_obj->get($_file),
- $smarty->_conf_obj->get($_file, $_section));
- if(function_exists('var_export')) {
- $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
- } else {
- $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
- }
- $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
- require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
- smarty_core_write_compiled_resource($_params, $smarty);
- } else {
- include($_compile_file);
- }
-
- if ($smarty->caching) {
- $smarty->_cache_info['config'][$_file] = true;
- }
-
- $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
- $smarty->_config[0]['files'][$_file] = true;
-
- if ($_scope == 'parent') {
- $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
- $smarty->_config[1]['files'][$_file] = true;
- } else if ($_scope == 'global') {
- for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
- $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
- $smarty->_config[$i]['files'][$_file] = true;
- }
- }
-
- if ($smarty->debugging) {
- $_params = array();
- require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
- $smarty->_smarty_debug_info[] = array('type' => 'config',
- 'filename' => $_file.' ['.$_section.'] '.$_scope,
- 'depth' => $smarty->_inclusion_depth,
- 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
- }
-
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {counter} function plugin
- *
- * Type: function<br>
- * Name: counter<br>
- * Purpose: print out a counter value
- * @author Monte Ohrt <monte at ohrt dot com>
- * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
- * (Smarty online manual)
- * @param array parameters
- * @param Smarty
- * @return string|null
- */
-function smarty_function_counter($params, &$smarty)
-{
- static $counters = array();
-
- $name = (isset($params['name'])) ? $params['name'] : 'default';
- if (!isset($counters[$name])) {
- $counters[$name] = array(
- 'start'=>1,
- 'skip'=>1,
- 'direction'=>'up',
- 'count'=>1
- );
- }
- $counter =& $counters[$name];
-
- if (isset($params['start'])) {
- $counter['start'] = $counter['count'] = (int)$params['start'];
- }
-
- if (!empty($params['assign'])) {
- $counter['assign'] = $params['assign'];
- }
-
- if (isset($counter['assign'])) {
- $smarty->assign($counter['assign'], $counter['count']);
- }
-
- if (isset($params['print'])) {
- $print = (bool)$params['print'];
- } else {
- $print = empty($counter['assign']);
- }
-
- if ($print) {
- $retval = $counter['count'];
- } else {
- $retval = null;
- }
-
- if (isset($params['skip'])) {
- $counter['skip'] = $params['skip'];
- }
-
- if (isset($params['direction'])) {
- $counter['direction'] = $params['direction'];
- }
-
- if ($counter['direction'] == "down")
- $counter['count'] -= $counter['skip'];
- else
- $counter['count'] += $counter['skip'];
-
- return $retval;
-
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty {cycle} function plugin
- *
- * Type: function<br>
- * Name: cycle<br>
- * Date: May 3, 2002<br>
- * Purpose: cycle through given values<br>
- * Input:
- * - name = name of cycle (optional)
- * - values = comma separated list of values to cycle,
- * or an array of values to cycle
- * (this can be left out for subsequent calls)
- * - reset = boolean - resets given var to true
- * - print = boolean - print var or not. default is true
- * - advance = boolean - whether or not to advance the cycle
- * - delimiter = the value delimiter, default is ","
- * - assign = boolean, assigns to template var instead of
- * printed.
- *
- * Examples:<br>
- * <pre>
- * {cycle values="#eeeeee,#d0d0d0d"}
- * {cycle name=row values="one,two,three" reset=true}
- * {cycle name=row}
- * </pre>
- * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author credit to Mark Priatel <mpriatel@rogers.com>
- * @author credit to Gerard <gerard@interfold.com>
- * @author credit to Jason Sweat <jsweat_php@yahoo.com>
- * @version 1.3
- * @param array
- * @param Smarty
- * @return string|null
- */
-function smarty_function_cycle($params, &$smarty)
-{
- static $cycle_vars;
-
- $name = (empty($params['name'])) ? 'default' : $params['name'];
- $print = (isset($params['print'])) ? (bool)$params['print'] : true;
- $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
- $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
-
- if (!in_array('values', array_keys($params))) {
- if(!isset($cycle_vars[$name]['values'])) {
- $smarty->trigger_error("cycle: missing 'values' parameter");
- return;
- }
- } else {
- if(isset($cycle_vars[$name]['values'])
- && $cycle_vars[$name]['values'] != $params['values'] ) {
- $cycle_vars[$name]['index'] = 0;
- }
- $cycle_vars[$name]['values'] = $params['values'];
- }
-
- $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
-
- if(is_array($cycle_vars[$name]['values'])) {
- $cycle_array = $cycle_vars[$name]['values'];
- } else {
- $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
- }
-
- if(!isset($cycle_vars[$name]['index']) || $reset ) {
- $cycle_vars[$name]['index'] = 0;
- }
-
- if (isset($params['assign'])) {
- $print = false;
- $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
- }
-
- if($print) {
- $retval = $cycle_array[$cycle_vars[$name]['index']];
- } else {
- $retval = null;
- }
-
- if($advance) {
- if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
- $cycle_vars[$name]['index'] = 0;
- } else {
- $cycle_vars[$name]['index']++;
- }
- }
-
- return $retval;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {debug} function plugin
- *
- * Type: function<br>
- * Name: debug<br>
- * Date: July 1, 2002<br>
- * Purpose: popup debug window
- * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @version 1.0
- * @param array
- * @param Smarty
- * @return string output from {@link Smarty::_generate_debug_output()}
- */
-function smarty_function_debug($params, &$smarty)
-{
- if (isset($params['output'])) {
- $smarty->assign('_smarty_debug_output', $params['output']);
- }
- require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
- return smarty_core_display_debug_console(null, $smarty);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {eval} function plugin
- *
- * Type: function<br>
- * Name: eval<br>
- * Purpose: evaluate a template variable as a template<br>
- * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array
- * @param Smarty
- */
-function smarty_function_eval($params, &$smarty)
-{
-
- if (!isset($params['var'])) {
- $smarty->trigger_error("eval: missing 'var' parameter");
- return;
- }
-
- if($params['var'] == '') {
- return;
- }
-
- $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
-
- ob_start();
- $smarty->_eval('?>' . $_var_compiled);
- $_contents = ob_get_contents();
- ob_end_clean();
-
- if (!empty($params['assign'])) {
- $smarty->assign($params['assign'], $_contents);
- } else {
- return $_contents;
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {fetch} plugin
- *
- * Type: function<br>
- * Name: fetch<br>
- * Purpose: fetch file, web or ftp data and display results
- * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array
- * @param Smarty
- * @return string|null if the assign parameter is passed, Smarty assigns the
- * result to a template variable
- */
-function smarty_function_fetch($params, &$smarty)
-{
- if (empty($params['file'])) {
- $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
- return;
- }
-
- $content = '';
- if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
- $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
- require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
- if(!smarty_core_is_secure($_params, $smarty)) {
- $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
- return;
- }
-
- // fetch the file
- if($fp = @fopen($params['file'],'r')) {
- while(!feof($fp)) {
- $content .= fgets ($fp,4096);
- }
- fclose($fp);
- } else {
- $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
- return;
- }
- } else {
- // not a local file
- if(preg_match('!^http://!i',$params['file'])) {
- // http fetch
- if($uri_parts = parse_url($params['file'])) {
- // set defaults
- $host = $server_name = $uri_parts['host'];
- $timeout = 30;
- $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
- $agent = "Smarty Template Engine ".$smarty->_version;
- $referer = "";
- $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
- $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
- $_is_proxy = false;
- if(empty($uri_parts['port'])) {
- $port = 80;
- } else {
- $port = $uri_parts['port'];
- }
- if(!empty($uri_parts['user'])) {
- $user = $uri_parts['user'];
- }
- if(!empty($uri_parts['pass'])) {
- $pass = $uri_parts['pass'];
- }
- // loop through parameters, setup headers
- foreach($params as $param_key => $param_value) {
- switch($param_key) {
- case "file":
- case "assign":
- case "assign_headers":
- break;
- case "user":
- if(!empty($param_value)) {
- $user = $param_value;
- }
- break;
- case "pass":
- if(!empty($param_value)) {
- $pass = $param_value;
- }
- break;
- case "accept":
- if(!empty($param_value)) {
- $accept = $param_value;
- }
- break;
- case "header":
- if(!empty($param_value)) {
- if(!preg_match('![\w\d-]+: .+!',$param_value)) {
- $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
- return;
- } else {
- $extra_headers[] = $param_value;
- }
- }
- break;
- case "proxy_host":
- if(!empty($param_value)) {
- $proxy_host = $param_value;
- }
- break;
- case "proxy_port":
- if(!preg_match('!\D!', $param_value)) {
- $proxy_port = (int) $param_value;
- } else {
- $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
- return;
- }
- break;
- case "agent":
- if(!empty($param_value)) {
- $agent = $param_value;
- }
- break;
- case "referer":
- if(!empty($param_value)) {
- $referer = $param_value;
- }
- break;
- case "timeout":
- if(!preg_match('!\D!', $param_value)) {
- $timeout = (int) $param_value;
- } else {
- $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
- return;
- }
- break;
- default:
- $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
- return;
- }
- }
- if(!empty($proxy_host) && !empty($proxy_port)) {
- $_is_proxy = true;
- $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
- } else {
- $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
- }
-
- if(!$fp) {
- $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
- return;
- } else {
- if($_is_proxy) {
- fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
- } else {
- fputs($fp, "GET $uri HTTP/1.0\r\n");
- }
- if(!empty($host)) {
- fputs($fp, "Host: $host\r\n");
- }
- if(!empty($accept)) {
- fputs($fp, "Accept: $accept\r\n");
- }
- if(!empty($agent)) {
- fputs($fp, "User-Agent: $agent\r\n");
- }
- if(!empty($referer)) {
- fputs($fp, "Referer: $referer\r\n");
- }
- if(isset($extra_headers) && is_array($extra_headers)) {
- foreach($extra_headers as $curr_header) {
- fputs($fp, $curr_header."\r\n");
- }
- }
- if(!empty($user) && !empty($pass)) {
- fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
- }
-
- fputs($fp, "\r\n");
- while(!feof($fp)) {
- $content .= fgets($fp,4096);
- }
- fclose($fp);
- $csplit = split("\r\n\r\n",$content,2);
-
- $content = $csplit[1];
-
- if(!empty($params['assign_headers'])) {
- $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
- }
- }
- } else {
- $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
- return;
- }
- } else {
- // ftp fetch
- if($fp = @fopen($params['file'],'r')) {
- while(!feof($fp)) {
- $content .= fgets ($fp,4096);
- }
- fclose($fp);
- } else {
- $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
- return;
- }
- }
-
- }
-
-
- if (!empty($params['assign'])) {
- $smarty->assign($params['assign'],$content);
- } else {
- return $content;
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {html_checkboxes} function plugin
- *
- * File: function.html_checkboxes.php<br>
- * Type: function<br>
- * Name: html_checkboxes<br>
- * Date: 24.Feb.2003<br>
- * Purpose: Prints out a list of checkbox input types<br>
- * Input:<br>
- * - name (optional) - string default "checkbox"
- * - values (required) - array
- * - options (optional) - associative array
- * - checked (optional) - array default not set
- * - separator (optional) - ie <br> or
- * - output (optional) - the output next to each checkbox
- * - assign (optional) - assign the output as an array to this variable
- * Examples:
- * <pre>
- * {html_checkboxes values=$ids output=$names}
- * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
- * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
- * </pre>
- * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
- * (Smarty online manual)
- * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
- * @author credits to Monte Ohrt <monte at ohrt dot com>
- * @version 1.0
- * @param array
- * @param Smarty
- * @return string
- * @uses smarty_function_escape_special_chars()
- */
-function smarty_function_html_checkboxes($params, &$smarty)
-{
- require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
-
- $name = 'checkbox';
- $values = null;
- $options = null;
- $selected = null;
- $separator = '';
- $labels = true;
- $output = null;
-
- $extra = '';
-
- foreach($params as $_key => $_val) {
- switch($_key) {
- case 'name':
- case 'separator':
- $$_key = $_val;
- break;
-
- case 'labels':
- $$_key = (bool)$_val;
- break;
-
- case 'options':
- $$_key = (array)$_val;
- break;
-
- case 'values':
- case 'output':
- $$_key = array_values((array)$_val);
- break;
-
- case 'checked':
- case 'selected':
- $selected = array_map('strval', array_values((array)$_val));
- break;
-
- case 'checkboxes':
- $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
- $options = (array)$_val;
- break;
-
- case 'assign':
- break;
-
- default:
- if(!is_array($_val)) {
- $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
- } else {
- $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
- }
- break;
- }
- }
-
- if (!isset($options) && !isset($values))
- return ''; /* raise error here? */
-
- settype($selected, 'array');
- $_html_result = array();
-
- if (isset($options)) {
-
- foreach ($options as $_key=>$_val)
- $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
-
-
- } else {
- foreach ($values as $_i=>$_key) {
- $_val = isset($output[$_i]) ? $output[$_i] : '';
- $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
- }
-
- }
-
- if(!empty($params['assign'])) {
- $smarty->assign($params['assign'], $_html_result);
- } else {
- return implode("\n",$_html_result);
- }
-
-}
-
-function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
- $_output = '';
- if ($labels) $_output .= '<label>';
- $_output .= '<input type="checkbox" name="'
- . smarty_function_escape_special_chars($name) . '[]" value="'
- . smarty_function_escape_special_chars($value) . '"';
-
- if (in_array((string)$value, $selected)) {
- $_output .= ' checked="checked"';
- }
- $_output .= $extra . ' />' . $output;
- if ($labels) $_output .= '</label>';
- $_output .= $separator;
-
- return $_output;
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {html_image} function plugin
- *
- * Type: function<br>
- * Name: html_image<br>
- * Date: Feb 24, 2003<br>
- * Purpose: format HTML tags for the image<br>
- * Input:<br>
- * - file = file (and path) of image (required)
- * - height = image height (optional, default actual height)
- * - width = image width (optional, default actual width)
- * - basedir = base directory for absolute paths, default
- * is environment variable DOCUMENT_ROOT
- * - path_prefix = prefix for path output (optional, default empty)
- *
- * Examples: {html_image file="/images/masthead.gif"}
- * Output: <img src="/images/masthead.gif" width=400 height=23>
- * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author credits to Duda <duda@big.hu> - wrote first image function
- * in repository, helped with lots of functionality
- * @version 1.0
- * @param array
- * @param Smarty
- * @return string
- * @uses smarty_function_escape_special_chars()
- */
-function smarty_function_html_image($params, &$smarty)
-{
- require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
-
- $alt = '';
- $file = '';
- $height = '';
- $width = '';
- $extra = '';
- $prefix = '';
- $suffix = '';
- $path_prefix = '';
- $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
- $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
- foreach($params as $_key => $_val) {
- switch($_key) {
- case 'file':
- case 'height':
- case 'width':
- case 'dpi':
- case 'path_prefix':
- case 'basedir':
- $$_key = $_val;
- break;
-
- case 'alt':
- if(!is_array($_val)) {
- $$_key = smarty_function_escape_special_chars($_val);
- } else {
- $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
- }
- break;
-
- case 'link':
- case 'href':
- $prefix = '<a href="' . $_val . '">';
- $suffix = '</a>';
- break;
-
- default:
- if(!is_array($_val)) {
- $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
- } else {
- $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
- }
- break;
- }
- }
-
- if (empty($file)) {
- $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
- return;
- }
-
- if (substr($file,0,1) == '/') {
- $_image_path = $basedir . $file;
- } else {
- $_image_path = $file;
- }
-
- if(!isset($params['width']) || !isset($params['height'])) {
- if(!$_image_data = @getimagesize($_image_path)) {
- if(!file_exists($_image_path)) {
- $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
- return;
- } else if(!is_readable($_image_path)) {
- $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
- return;
- } else {
- $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
- return;
- }
- }
- if ($smarty->security &&
- ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
- (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
- (!smarty_core_is_secure($_params, $smarty)) ) {
- $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
- }
-
- if(!isset($params['width'])) {
- $width = $_image_data[0];
- }
- if(!isset($params['height'])) {
- $height = $_image_data[1];
- }
-
- }
-
- if(isset($params['dpi'])) {
- if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
- $dpi_default = 72;
- } else {
- $dpi_default = 96;
- }
- $_resize = $dpi_default/$params['dpi'];
- $width = round($width * $_resize);
- $height = round($height * $_resize);
- }
-
- return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {html_options} function plugin
- *
- * Type: function<br>
- * Name: html_options<br>
- * Input:<br>
- * - name (optional) - string default "select"
- * - values (required if no options supplied) - array
- * - options (required if no values supplied) - associative array
- * - selected (optional) - string default not set
- * - output (required if not options supplied) - array
- * Purpose: Prints the list of <option> tags generated from
- * the passed parameters
- * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array
- * @param Smarty
- * @return string
- * @uses smarty_function_escape_special_chars()
- */
-function smarty_function_html_options($params, &$smarty)
-{
- require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
-
- $name = null;
- $values = null;
- $options = null;
- $selected = array();
- $output = null;
-
- $extra = '';
-
- foreach($params as $_key => $_val) {
- switch($_key) {
- case 'name':
- $$_key = (string)$_val;
- break;
-
- case 'options':
- $$_key = (array)$_val;
- break;
-
- case 'values':
- case 'output':
- $$_key = array_values((array)$_val);
- break;
-
- case 'selected':
- $$_key = array_map('strval', array_values((array)$_val));
- break;
-
- default:
- if(!is_array($_val)) {
- $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
- } else {
- $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
- }
- break;
- }
- }
-
- if (!isset($options) && !isset($values))
- return ''; /* raise error here? */
-
- $_html_result = '';
-
- if (isset($options)) {
-
- foreach ($options as $_key=>$_val)
- $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
-
- } else {
-
- foreach ($values as $_i=>$_key) {
- $_val = isset($output[$_i]) ? $output[$_i] : '';
- $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
- }
-
- }
-
- if(!empty($name)) {
- $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
- }
-
- return $_html_result;
-
-}
-
-function smarty_function_html_options_optoutput($key, $value, $selected) {
- if(!is_array($value)) {
- $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
- smarty_function_escape_special_chars($key) . '"';
- if (in_array((string)$key, $selected))
- $_html_result .= ' selected="selected"';
- $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
- } else {
- $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
- }
- return $_html_result;
-}
-
-function smarty_function_html_options_optgroup($key, $values, $selected) {
- $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
- foreach ($values as $key => $value) {
- $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
- }
- $optgroup_html .= "</optgroup>\n";
- return $optgroup_html;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {html_radios} function plugin
- *
- * File: function.html_radios.php<br>
- * Type: function<br>
- * Name: html_radios<br>
- * Date: 24.Feb.2003<br>
- * Purpose: Prints out a list of radio input types<br>
- * Input:<br>
- * - name (optional) - string default "radio"
- * - values (required) - array
- * - options (optional) - associative array
- * - checked (optional) - array default not set
- * - separator (optional) - ie <br> or
- * - output (optional) - the output next to each radio button
- * - assign (optional) - assign the output as an array to this variable
- * Examples:
- * <pre>
- * {html_radios values=$ids output=$names}
- * {html_radios values=$ids name='box' separator='<br>' output=$names}
- * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
- * </pre>
- * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
- * (Smarty online manual)
- * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
- * @author credits to Monte Ohrt <monte at ohrt dot com>
- * @version 1.0
- * @param array
- * @param Smarty
- * @return string
- * @uses smarty_function_escape_special_chars()
- */
-function smarty_function_html_radios($params, &$smarty)
-{
- require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
-
- $name = 'radio';
- $values = null;
- $options = null;
- $selected = null;
- $separator = '';
- $labels = true;
- $label_ids = false;
- $output = null;
- $extra = '';
-
- foreach($params as $_key => $_val) {
- switch($_key) {
- case 'name':
- case 'separator':
- $$_key = (string)$_val;
- break;
-
- case 'checked':
- case 'selected':
- if(is_array($_val)) {
- $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
- } else {
- $selected = (string)$_val;
- }
- break;
-
- case 'labels':
- case 'label_ids':
- $$_key = (bool)$_val;
- break;
-
- case 'options':
- $$_key = (array)$_val;
- break;
-
- case 'values':
- case 'output':
- $$_key = array_values((array)$_val);
- break;
-
- case 'radios':
- $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
- $options = (array)$_val;
- break;
-
- case 'assign':
- break;
-
- default:
- if(!is_array($_val)) {
- $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
- } else {
- $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
- }
- break;
- }
- }
-
- if (!isset($options) && !isset($values))
- return ''; /* raise error here? */
-
- $_html_result = array();
-
- if (isset($options)) {
-
- foreach ($options as $_key=>$_val)
- $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
-
- } else {
-
- foreach ($values as $_i=>$_key) {
- $_val = isset($output[$_i]) ? $output[$_i] : '';
- $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
- }
-
- }
-
- if(!empty($params['assign'])) {
- $smarty->assign($params['assign'], $_html_result);
- } else {
- return implode("\n",$_html_result);
- }
-
-}
-
-function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
- $_output = '';
- if ($labels) {
- if($label_ids) {
- $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
- $_output .= '<label for="' . $_id . '">';
- } else {
- $_output .= '<label>';
- }
- }
- $_output .= '<input type="radio" name="'
- . smarty_function_escape_special_chars($name) . '" value="'
- . smarty_function_escape_special_chars($value) . '"';
-
- if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
-
- if ((string)$value==$selected) {
- $_output .= ' checked="checked"';
- }
- $_output .= $extra . ' />' . $output;
- if ($labels) $_output .= '</label>';
- $_output .= $separator;
-
- return $_output;
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty {html_select_date} plugin
- *
- * Type: function<br>
- * Name: html_select_date<br>
- * Purpose: Prints the dropdowns for date selection.
- *
- * ChangeLog:<br>
- * - 1.0 initial release
- * - 1.1 added support for +/- N syntax for begin
- * and end year values. (Monte)
- * - 1.2 added support for yyyy-mm-dd syntax for
- * time value. (Jan Rosier)
- * - 1.3 added support for choosing format for
- * month values (Gary Loescher)
- * - 1.3.1 added support for choosing format for
- * day values (Marcus Bointon)
- * - 1.3.2 support negative timestamps, force year
- * dropdown to include given date unless explicitly set (Monte)
- * - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
- * of 0000-00-00 dates (cybot, boots)
- * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
- * (Smarty online manual)
- * @version 1.3.4
- * @author Andrei Zmievski
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array
- * @param Smarty
- * @return string
- */
-function smarty_function_html_select_date($params, &$smarty)
-{
- require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
- require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
- require_once $smarty->_get_plugin_filepath('function','html_options');
- /* Default values. */
- $prefix = "Date_";
- $start_year = strftime("%Y");
- $end_year = $start_year;
- $display_days = true;
- $display_months = true;
- $display_years = true;
- $month_format = "%B";
- /* Write months as numbers by default GL */
- $month_value_format = "%m";
- $day_format = "%02d";
- /* Write day values using this format MB */
- $day_value_format = "%d";
- $year_as_text = false;
- /* Display years in reverse order? Ie. 2000,1999,.... */
- $reverse_years = false;
- /* Should the select boxes be part of an array when returned from PHP?
- e.g. setting it to "birthday", would create "birthday[Day]",
- "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
- $field_array = null;
- /* <select size>'s of the different <select> tags.
- If not set, uses default dropdown. */
- $day_size = null;
- $month_size = null;
- $year_size = null;
- /* Unparsed attributes common to *ALL* the <select>/<input> tags.
- An example might be in the template: all_extra ='class ="foo"'. */
- $all_extra = null;
- /* Separate attributes for the tags. */
- $day_extra = null;
- $month_extra = null;
- $year_extra = null;
- /* Order in which to display the fields.
- "D" -> day, "M" -> month, "Y" -> year. */
- $field_order = 'MDY';
- /* String printed between the different fields. */
- $field_separator = "\n";
- $time = time();
- $all_empty = null;
- $day_empty = null;
- $month_empty = null;
- $year_empty = null;
- $extra_attrs = '';
-
- foreach ($params as $_key=>$_value) {
- switch ($_key) {
- case 'prefix':
- case 'time':
- case 'start_year':
- case 'end_year':
- case 'month_format':
- case 'day_format':
- case 'day_value_format':
- case 'field_array':
- case 'day_size':
- case 'month_size':
- case 'year_size':
- case 'all_extra':
- case 'day_extra':
- case 'month_extra':
- case 'year_extra':
- case 'field_order':
- case 'field_separator':
- case 'month_value_format':
- case 'month_empty':
- case 'day_empty':
- case 'year_empty':
- $$_key = (string)$_value;
- break;
-
- case 'all_empty':
- $$_key = (string)$_value;
- $day_empty = $month_empty = $year_empty = $all_empty;
- break;
-
- case 'display_days':
- case 'display_months':
- case 'display_years':
- case 'year_as_text':
- case 'reverse_years':
- $$_key = (bool)$_value;
- break;
-
- default:
- if(!is_array($_value)) {
- $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
- } else {
- $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
- }
- break;
- }
- }
-
- if (preg_match('!^-\d+$!', $time)) {
- // negative timestamp, use date()
- $time = date('Y-m-d', $time);
- }
- // If $time is not in format yyyy-mm-dd
- if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
- $time = $found[1];
- } else {
- // use smarty_make_timestamp to get an unix timestamp and
- // strftime to make yyyy-mm-dd
- $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
- }
- // Now split this in pieces, which later can be used to set the select
- $time = explode("-", $time);
-
- // make syntax "+N" or "-N" work with start_year and end_year
- if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
- if ($match[1] == '+') {
- $end_year = strftime('%Y') + $match[2];
- } else {
- $end_year = strftime('%Y') - $match[2];
- }
- }
- if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
- if ($match[1] == '+') {
- $start_year = strftime('%Y') + $match[2];
- } else {
- $start_year = strftime('%Y') - $match[2];
- }
- }
- if (strlen($time[0]) > 0) {
- if ($start_year > $time[0] && !isset($params['start_year'])) {
- // force start year to include given date if not explicitly set
- $start_year = $time[0];
- }
- if($end_year < $time[0] && !isset($params['end_year'])) {
- // force end year to include given date if not explicitly set
- $end_year = $time[0];
- }
- }
-
- $field_order = strtoupper($field_order);
-
- $html_result = $month_result = $day_result = $year_result = "";
-
- $field_separator_count = -1;
- if ($display_months) {
- $field_separator_count++;
- $month_names = array();
- $month_values = array();
- if(isset($month_empty)) {
- $month_names[''] = $month_empty;
- $month_values[''] = '';
- }
- for ($i = 1; $i <= 12; $i++) {
- $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
- $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
- }
-
- $month_result .= '<select name=';
- if (null !== $field_array){
- $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
- } else {
- $month_result .= '"' . $prefix . 'Month"';
- }
- if (null !== $month_size){
- $month_result .= ' size="' . $month_size . '"';
- }
- if (null !== $month_extra){
- $month_result .= ' ' . $month_extra;
- }
- if (null !== $all_extra){
- $month_result .= ' ' . $all_extra;
- }
- $month_result .= $extra_attrs . '>'."\n";
-
- $month_result .= smarty_function_html_options(array('output' => $month_names,
- 'values' => $month_values,
- 'selected' => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
- 'print_result' => false),
- $smarty);
- $month_result .= '</select>';
- }
-
- if ($display_days) {
- $field_separator_count++;
- $days = array();
- if (isset($day_empty)) {
- $days[''] = $day_empty;
- $day_values[''] = '';
- }
- for ($i = 1; $i <= 31; $i++) {
- $days[] = sprintf($day_format, $i);
- $day_values[] = sprintf($day_value_format, $i);
- }
-
- $day_result .= '<select name=';
- if (null !== $field_array){
- $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
- } else {
- $day_result .= '"' . $prefix . 'Day"';
- }
- if (null !== $day_size){
- $day_result .= ' size="' . $day_size . '"';
- }
- if (null !== $all_extra){
- $day_result .= ' ' . $all_extra;
- }
- if (null !== $day_extra){
- $day_result .= ' ' . $day_extra;
- }
- $day_result .= $extra_attrs . '>'."\n";
- $day_result .= smarty_function_html_options(array('output' => $days,
- 'values' => $day_values,
- 'selected' => $time[2],
- 'print_result' => false),
- $smarty);
- $day_result .= '</select>';
- }
-
- if ($display_years) {
- $field_separator_count++;
- if (null !== $field_array){
- $year_name = $field_array . '[' . $prefix . 'Year]';
- } else {
- $year_name = $prefix . 'Year';
- }
- if ($year_as_text) {
- $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
- if (null !== $all_extra){
- $year_result .= ' ' . $all_extra;
- }
- if (null !== $year_extra){
- $year_result .= ' ' . $year_extra;
- }
- $year_result .= ' />';
- } else {
- $years = range((int)$start_year, (int)$end_year);
- if ($reverse_years) {
- rsort($years, SORT_NUMERIC);
- } else {
- sort($years, SORT_NUMERIC);
- }
- $yearvals = $years;
- if(isset($year_empty)) {
- array_unshift($years, $year_empty);
- array_unshift($yearvals, '');
- }
- $year_result .= '<select name="' . $year_name . '"';
- if (null !== $year_size){
- $year_result .= ' size="' . $year_size . '"';
- }
- if (null !== $all_extra){
- $year_result .= ' ' . $all_extra;
- }
- if (null !== $year_extra){
- $year_result .= ' ' . $year_extra;
- }
- $year_result .= $extra_attrs . '>'."\n";
- $year_result .= smarty_function_html_options(array('output' => $years,
- 'values' => $yearvals,
- 'selected' => $time[0],
- 'print_result' => false),
- $smarty);
- $year_result .= '</select>';
- }
- }
-
- // Loop thru the field_order field
- for ($i = 0; $i <= 2; $i++){
- $c = substr($field_order, $i, 1);
- switch ($c){
- case 'D':
- $html_result .= $day_result;
- break;
-
- case 'M':
- $html_result .= $month_result;
- break;
-
- case 'Y':
- $html_result .= $year_result;
- break;
- }
- // Add the field seperator
- if($i < $field_separator_count) {
- $html_result .= $field_separator;
- }
- }
-
- return $html_result;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {html_select_time} function plugin
- *
- * Type: function<br>
- * Name: html_select_time<br>
- * Purpose: Prints the dropdowns for time selection
- * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
- * (Smarty online manual)
- * @author Roberto Berto <roberto@berto.net>
- * @credits Monte Ohrt <monte AT ohrt DOT com>
- * @param array
- * @param Smarty
- * @return string
- * @uses smarty_make_timestamp()
- */
-function smarty_function_html_select_time($params, &$smarty)
-{
- require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
- require_once $smarty->_get_plugin_filepath('function','html_options');
- /* Default values. */
- $prefix = "Time_";
- $time = time();
- $display_hours = true;
- $display_minutes = true;
- $display_seconds = true;
- $display_meridian = true;
- $use_24_hours = true;
- $minute_interval = 1;
- $second_interval = 1;
- /* Should the select boxes be part of an array when returned from PHP?
- e.g. setting it to "birthday", would create "birthday[Hour]",
- "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
- Can be combined with prefix. */
- $field_array = null;
- $all_extra = null;
- $hour_extra = null;
- $minute_extra = null;
- $second_extra = null;
- $meridian_extra = null;
-
- foreach ($params as $_key=>$_value) {
- switch ($_key) {
- case 'prefix':
- case 'time':
- case 'field_array':
- case 'all_extra':
- case 'hour_extra':
- case 'minute_extra':
- case 'second_extra':
- case 'meridian_extra':
- $$_key = (string)$_value;
- break;
-
- case 'display_hours':
- case 'display_minutes':
- case 'display_seconds':
- case 'display_meridian':
- case 'use_24_hours':
- $$_key = (bool)$_value;
- break;
-
- case 'minute_interval':
- case 'second_interval':
- $$_key = (int)$_value;
- break;
-
- default:
- $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
- }
- }
-
- $time = smarty_make_timestamp($time);
-
- $html_result = '';
-
- if ($display_hours) {
- $hours = $use_24_hours ? range(0, 23) : range(1, 12);
- $hour_fmt = $use_24_hours ? '%H' : '%I';
- for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
- $hours[$i] = sprintf('%02d', $hours[$i]);
- $html_result .= '<select name=';
- if (null !== $field_array) {
- $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
- } else {
- $html_result .= '"' . $prefix . 'Hour"';
- }
- if (null !== $hour_extra){
- $html_result .= ' ' . $hour_extra;
- }
- if (null !== $all_extra){
- $html_result .= ' ' . $all_extra;
- }
- $html_result .= '>'."\n";
- $html_result .= smarty_function_html_options(array('output' => $hours,
- 'values' => $hours,
- 'selected' => strftime($hour_fmt, $time),
- 'print_result' => false),
- $smarty);
- $html_result .= "</select>\n";
- }
-
- if ($display_minutes) {
- $all_minutes = range(0, 59);
- for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
- $minutes[] = sprintf('%02d', $all_minutes[$i]);
- $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
- $html_result .= '<select name=';
- if (null !== $field_array) {
- $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
- } else {
- $html_result .= '"' . $prefix . 'Minute"';
- }
- if (null !== $minute_extra){
- $html_result .= ' ' . $minute_extra;
- }
- if (null !== $all_extra){
- $html_result .= ' ' . $all_extra;
- }
- $html_result .= '>'."\n";
-
- $html_result .= smarty_function_html_options(array('output' => $minutes,
- 'values' => $minutes,
- 'selected' => $selected,
- 'print_result' => false),
- $smarty);
- $html_result .= "</select>\n";
- }
-
- if ($display_seconds) {
- $all_seconds = range(0, 59);
- for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
- $seconds[] = sprintf('%02d', $all_seconds[$i]);
- $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
- $html_result .= '<select name=';
- if (null !== $field_array) {
- $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
- } else {
- $html_result .= '"' . $prefix . 'Second"';
- }
-
- if (null !== $second_extra){
- $html_result .= ' ' . $second_extra;
- }
- if (null !== $all_extra){
- $html_result .= ' ' . $all_extra;
- }
- $html_result .= '>'."\n";
-
- $html_result .= smarty_function_html_options(array('output' => $seconds,
- 'values' => $seconds,
- 'selected' => $selected,
- 'print_result' => false),
- $smarty);
- $html_result .= "</select>\n";
- }
-
- if ($display_meridian && !$use_24_hours) {
- $html_result .= '<select name=';
- if (null !== $field_array) {
- $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
- } else {
- $html_result .= '"' . $prefix . 'Meridian"';
- }
-
- if (null !== $meridian_extra){
- $html_result .= ' ' . $meridian_extra;
- }
- if (null !== $all_extra){
- $html_result .= ' ' . $all_extra;
- }
- $html_result .= '>'."\n";
-
- $html_result .= smarty_function_html_options(array('output' => array('AM', 'PM'),
- 'values' => array('am', 'pm'),
- 'selected' => strtolower(strftime('%p', $time)),
- 'print_result' => false),
- $smarty);
- $html_result .= "</select>\n";
- }
-
- return $html_result;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {html_table} function plugin
- *
- * Type: function<br>
- * Name: html_table<br>
- * Date: Feb 17, 2003<br>
- * Purpose: make an html table from an array of data<br>
- * Input:<br>
- * - loop = array to loop through
- * - cols = number of columns, comma separated list of column names
- * or array of column names
- * - rows = number of rows
- * - table_attr = table attributes
- * - th_attr = table heading attributes (arrays are cycled)
- * - tr_attr = table row attributes (arrays are cycled)
- * - td_attr = table cell attributes (arrays are cycled)
- * - trailpad = value to pad trailing cells with
- * - caption = text for caption element
- * - vdir = vertical direction (default: "down", means top-to-bottom)
- * - hdir = horizontal direction (default: "right", means left-to-right)
- * - inner = inner loop (default "cols": print $loop line by line,
- * $loop will be printed column by column otherwise)
- *
- *
- * Examples:
- * <pre>
- * {table loop=$data}
- * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
- * {table loop=$data cols="first,second,third" tr_attr=$colors}
- * </pre>
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
- * @author credit to boots <boots dot smarty at yahoo dot com>
- * @version 1.1
- * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
- * (Smarty online manual)
- * @param array
- * @param Smarty
- * @return string
- */
-function smarty_function_html_table($params, &$smarty)
-{
- $table_attr = 'border="1"';
- $tr_attr = '';
- $th_attr = '';
- $td_attr = '';
- $cols = $cols_count = 3;
- $rows = 3;
- $trailpad = ' ';
- $vdir = 'down';
- $hdir = 'right';
- $inner = 'cols';
- $caption = '';
-
- if (!isset($params['loop'])) {
- $smarty->trigger_error("html_table: missing 'loop' parameter");
- return;
- }
-
- foreach ($params as $_key=>$_value) {
- switch ($_key) {
- case 'loop':
- $$_key = (array)$_value;
- break;
-
- case 'cols':
- if (is_array($_value) && !empty($_value)) {
- $cols = $_value;
- $cols_count = count($_value);
- } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
- $cols = explode(',', $_value);
- $cols_count = count($cols);
- } elseif (!empty($_value)) {
- $cols_count = (int)$_value;
- } else {
- $cols_count = $cols;
- }
- break;
-
- case 'rows':
- $$_key = (int)$_value;
- break;
-
- case 'table_attr':
- case 'trailpad':
- case 'hdir':
- case 'vdir':
- case 'inner':
- case 'caption':
- $$_key = (string)$_value;
- break;
-
- case 'tr_attr':
- case 'td_attr':
- case 'th_attr':
- $$_key = $_value;
- break;
- }
- }
-
- $loop_count = count($loop);
- if (empty($params['rows'])) {
- /* no rows specified */
- $rows = ceil($loop_count/$cols_count);
- } elseif (empty($params['cols'])) {
- if (!empty($params['rows'])) {
- /* no cols specified, but rows */
- $cols_count = ceil($loop_count/$rows);
- }
- }
-
- $output = "<table $table_attr>\n";
-
- if (!empty($caption)) {
- $output .= '<caption>' . $caption . "</caption>\n";
- }
-
- if (is_array($cols)) {
- $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
- $output .= "<thead><tr>\n";
-
- for ($r=0; $r<$cols_count; $r++) {
- $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
- $output .= $cols[$r];
- $output .= "</th>\n";
- }
- $output .= "</tr></thead>\n";
- }
-
- $output .= "<tbody>\n";
- for ($r=0; $r<$rows; $r++) {
- $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
- $rx = ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
-
- for ($c=0; $c<$cols_count; $c++) {
- $x = ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
- if ($inner!='cols') {
- /* shuffle x to loop over rows*/
- $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
- }
-
- if ($x<$loop_count) {
- $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
- } else {
- $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
- }
- }
- $output .= "</tr>\n";
- }
- $output .= "</tbody>\n";
- $output .= "</table>\n";
-
- return $output;
-}
-
-function smarty_function_html_table_cycle($name, $var, $no) {
- if(!is_array($var)) {
- $ret = $var;
- } else {
- $ret = $var[$no % count($var)];
- }
-
- return ($ret) ? ' '.$ret : '';
-}
-
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {mailto} function plugin
- *
- * Type: function<br>
- * Name: mailto<br>
- * Date: May 21, 2002
- * Purpose: automate mailto address link creation, and optionally
- * encode them.<br>
- * Input:<br>
- * - address = e-mail address
- * - text = (optional) text to display, default is address
- * - encode = (optional) can be one of:
- * * none : no encoding (default)
- * * javascript : encode with javascript
- * * javascript_charcode : encode with javascript charcode
- * * hex : encode with hexidecimal (no javascript)
- * - cc = (optional) address(es) to carbon copy
- * - bcc = (optional) address(es) to blind carbon copy
- * - subject = (optional) e-mail subject
- * - newsgroups = (optional) newsgroup(s) to post to
- * - followupto = (optional) address(es) to follow up to
- * - extra = (optional) extra tags for the href link
- *
- * Examples:
- * <pre>
- * {mailto address="me@domain.com"}
- * {mailto address="me@domain.com" encode="javascript"}
- * {mailto address="me@domain.com" encode="hex"}
- * {mailto address="me@domain.com" subject="Hello to you!"}
- * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
- * {mailto address="me@domain.com" extra='class="mailto"'}
- * </pre>
- * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
- * (Smarty online manual)
- * @version 1.2
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author credits to Jason Sweat (added cc, bcc and subject functionality)
- * @param array
- * @param Smarty
- * @return string
- */
-function smarty_function_mailto($params, &$smarty)
-{
- $extra = '';
-
- if (empty($params['address'])) {
- $smarty->trigger_error("mailto: missing 'address' parameter");
- return;
- } else {
- $address = $params['address'];
- }
-
- $text = $address;
-
- // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
- // so, don't encode it.
- $search = array('%40', '%2C');
- $replace = array('@', ',');
- $mail_parms = array();
- foreach ($params as $var=>$value) {
- switch ($var) {
- case 'cc':
- case 'bcc':
- case 'followupto':
- if (!empty($value))
- $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
- break;
-
- case 'subject':
- case 'newsgroups':
- $mail_parms[] = $var.'='.rawurlencode($value);
- break;
-
- case 'extra':
- case 'text':
- $$var = $value;
-
- default:
- }
- }
-
- $mail_parm_vals = '';
- for ($i=0; $i<count($mail_parms); $i++) {
- $mail_parm_vals .= (0==$i) ? '?' : '&';
- $mail_parm_vals .= $mail_parms[$i];
- }
- $address .= $mail_parm_vals;
-
- $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
- if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
- $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
- return;
- }
-
- if ($encode == 'javascript' ) {
- $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
-
- $js_encode = '';
- for ($x=0; $x < strlen($string); $x++) {
- $js_encode .= '%' . bin2hex($string[$x]);
- }
-
- return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
-
- } elseif ($encode == 'javascript_charcode' ) {
- $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
-
- for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
- $ord[] = ord($string[$x]);
- }
-
- $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
- $_ret .= "<!--\n";
- $_ret .= "{document.write(String.fromCharCode(";
- $_ret .= implode(',',$ord);
- $_ret .= "))";
- $_ret .= "}\n";
- $_ret .= "//-->\n";
- $_ret .= "</script>\n";
-
- return $_ret;
-
-
- } elseif ($encode == 'hex') {
-
- preg_match('!^(.*)(\?.*)$!',$address,$match);
- if(!empty($match[2])) {
- $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
- return;
- }
- $address_encode = '';
- for ($x=0; $x < strlen($address); $x++) {
- if(preg_match('!\w!',$address[$x])) {
- $address_encode .= '%' . bin2hex($address[$x]);
- } else {
- $address_encode .= $address[$x];
- }
- }
- $text_encode = '';
- for ($x=0; $x < strlen($text); $x++) {
- $text_encode .= '&#x' . bin2hex($text[$x]).';';
- }
-
- $mailto = "mailto:";
- return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
-
- } else {
- // no encoding
- return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
-
- }
-
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {math} function plugin
- *
- * Type: function<br>
- * Name: math<br>
- * Purpose: handle math computations in template<br>
- * @link http://smarty.php.net/manual/en/language.function.math.php {math}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array
- * @param Smarty
- * @return string
- */
-function smarty_function_math($params, &$smarty)
-{
- // be sure equation parameter is present
- if (empty($params['equation'])) {
- $smarty->trigger_error("math: missing equation parameter");
- return;
- }
-
- // strip out backticks, not necessary for math
- $equation = str_replace('`','',$params['equation']);
-
- // make sure parenthesis are balanced
- if (substr_count($equation,"(") != substr_count($equation,")")) {
- $smarty->trigger_error("math: unbalanced parenthesis");
- return;
- }
-
- // match all vars in equation, make sure all are passed
- preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
- $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
- 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
-
- foreach($match[1] as $curr_var) {
- if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
- $smarty->trigger_error("math: function call $curr_var not allowed");
- return;
- }
- }
-
- foreach($params as $key => $val) {
- if ($key != "equation" && $key != "format" && $key != "assign") {
- // make sure value is not empty
- if (strlen($val)==0) {
- $smarty->trigger_error("math: parameter $key is empty");
- return;
- }
- if (!is_numeric($val)) {
- $smarty->trigger_error("math: parameter $key: is not numeric");
- return;
- }
- $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
- }
- }
-
- eval("\$smarty_math_result = ".$equation.";");
-
- if (empty($params['format'])) {
- if (empty($params['assign'])) {
- return $smarty_math_result;
- } else {
- $smarty->assign($params['assign'],$smarty_math_result);
- }
- } else {
- if (empty($params['assign'])){
- printf($params['format'],$smarty_math_result);
- } else {
- $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
- }
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {popup} function plugin
- *
- * Type: function<br>
- * Name: popup<br>
- * Purpose: make text pop up in windows via overlib
- * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array
- * @param Smarty
- * @return string
- */
-function smarty_function_popup($params, &$smarty)
-{
- $append = '';
- foreach ($params as $_key=>$_value) {
- switch ($_key) {
- case 'text':
- case 'trigger':
- case 'function':
- case 'inarray':
- $$_key = (string)$_value;
- if ($_key == 'function' || $_key == 'inarray')
- $append .= ',' . strtoupper($_key) . ",'$_value'";
- break;
-
- case 'caption':
- case 'closetext':
- case 'status':
- $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
- break;
-
- case 'fgcolor':
- case 'bgcolor':
- case 'textcolor':
- case 'capcolor':
- case 'closecolor':
- case 'textfont':
- case 'captionfont':
- case 'closefont':
- case 'fgbackground':
- case 'bgbackground':
- case 'caparray':
- case 'capicon':
- case 'background':
- case 'frame':
- $append .= ',' . strtoupper($_key) . ",'$_value'";
- break;
-
- case 'textsize':
- case 'captionsize':
- case 'closesize':
- case 'width':
- case 'height':
- case 'border':
- case 'offsetx':
- case 'offsety':
- case 'snapx':
- case 'snapy':
- case 'fixx':
- case 'fixy':
- case 'padx':
- case 'pady':
- case 'timeout':
- case 'delay':
- $append .= ',' . strtoupper($_key) . ",$_value";
- break;
-
- case 'sticky':
- case 'left':
- case 'right':
- case 'center':
- case 'above':
- case 'below':
- case 'noclose':
- case 'autostatus':
- case 'autostatuscap':
- case 'fullhtml':
- case 'hauto':
- case 'vauto':
- case 'mouseoff':
- case 'followmouse':
- case 'closeclick':
- if ($_value) $append .= ',' . strtoupper($_key);
- break;
-
- default:
- $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
- }
- }
-
- if (empty($text) && !isset($inarray) && empty($function)) {
- $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
- return false;
- }
-
- if (empty($trigger)) { $trigger = "onmouseover"; }
-
- $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
- $retval .= $append . ');"';
- if ($trigger == 'onmouseover')
- $retval .= ' onmouseout="nd();"';
-
-
- return $retval;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty {popup_init} function plugin
- *
- * Type: function<br>
- * Name: popup_init<br>
- * Purpose: initialize overlib
- * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array
- * @param Smarty
- * @return string
- */
-function smarty_function_popup_init($params, &$smarty)
-{
- $zindex = 1000;
-
- if (!empty($params['zindex'])) {
- $zindex = $params['zindex'];
- }
-
- if (!empty($params['src'])) {
- return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
- . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
- } else {
- $smarty->trigger_error("popup_init: missing src parameter");
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty capitalize modifier plugin
- *
- * Type: modifier<br>
- * Name: capitalize<br>
- * Purpose: capitalize words in the string
- * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
- * capitalize (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return string
- */
-function smarty_modifier_capitalize($string, $uc_digits = false)
-{
- smarty_modifier_capitalize_ucfirst(null, $uc_digits);
- return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
-}
-
-function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
-{
- static $_uc_digits = false;
-
- if(isset($uc_digits)) {
- $_uc_digits = $uc_digits;
- return;
- }
-
- if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
- return ucfirst($string[0]);
- else
- return $string[0];
-}
-
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty cat modifier plugin
- *
- * Type: modifier<br>
- * Name: cat<br>
- * Date: Feb 24, 2003
- * Purpose: catenate a value to a variable
- * Input: string to catenate
- * Example: {$var|cat:"foo"}
- * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
- * (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @version 1.0
- * @param string
- * @param string
- * @return string
- */
-function smarty_modifier_cat($string, $cat)
-{
- return $string . $cat;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty count_characters modifier plugin
- *
- * Type: modifier<br>
- * Name: count_characteres<br>
- * Purpose: count the number of characters in a text
- * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
- * count_characters (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param boolean include whitespace in the character count
- * @return integer
- */
-function smarty_modifier_count_characters($string, $include_spaces = false)
-{
- if ($include_spaces)
- return(strlen($string));
-
- return preg_match_all("/[^\s]/",$string, $match);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty count_paragraphs modifier plugin
- *
- * Type: modifier<br>
- * Name: count_paragraphs<br>
- * Purpose: count the number of paragraphs in a text
- * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
- * count_paragraphs (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return integer
- */
-function smarty_modifier_count_paragraphs($string)
-{
- // count \r or \n characters
- return count(preg_split('/[\r\n]+/', $string));
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty count_sentences modifier plugin
- *
- * Type: modifier<br>
- * Name: count_sentences
- * Purpose: count the number of sentences in a text
- * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
- * count_sentences (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return integer
- */
-function smarty_modifier_count_sentences($string)
-{
- // find periods with a word before but not after.
- return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty count_words modifier plugin
- *
- * Type: modifier<br>
- * Name: count_words<br>
- * Purpose: count the number of words in a text
- * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
- * count_words (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return integer
- */
-function smarty_modifier_count_words($string)
-{
- // split text by ' ',\r,\n,\f,\t
- $split_array = preg_split('/\s+/',$string);
- // count matches that contain alphanumerics
- $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
-
- return count($word_count);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Include the {@link shared.make_timestamp.php} plugin
- */
-require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
-/**
- * Smarty date_format modifier plugin
- *
- * Type: modifier<br>
- * Name: date_format<br>
- * Purpose: format datestamps via strftime<br>
- * Input:<br>
- * - string: input date string
- * - format: strftime format for output
- * - default_date: default date if $string is empty
- * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
- * date_format (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param string
- * @param string
- * @return string|void
- * @uses smarty_make_timestamp()
- */
-function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
-{
- if ($string != '') {
- $timestamp = smarty_make_timestamp($string);
- } elseif ($default_date != '') {
- $timestamp = smarty_make_timestamp($default_date);
- } else {
- return;
- }
- if (DIRECTORY_SEPARATOR == '\\') {
- $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
- $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
- if (strpos($format, '%e') !== false) {
- $_win_from[] = '%e';
- $_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
- }
- if (strpos($format, '%l') !== false) {
- $_win_from[] = '%l';
- $_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
- }
- $format = str_replace($_win_from, $_win_to, $format);
- }
- return strftime($format, $timestamp);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty debug_print_var modifier plugin
- *
- * Type: modifier<br>
- * Name: debug_print_var<br>
- * Purpose: formats variable contents for display in the console
- * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
- * debug_print_var (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param array|object
- * @param integer
- * @param integer
- * @return string
- */
-function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
-{
- $_replace = array(
- "\n" => '<i>\n</i>',
- "\r" => '<i>\r</i>',
- "\t" => '<i>\t</i>'
- );
-
- switch (gettype($var)) {
- case 'array' :
- $results = '<b>Array (' . count($var) . ')</b>';
- foreach ($var as $curr_key => $curr_val) {
- $results .= '<br>' . str_repeat(' ', $depth * 2)
- . '<b>' . strtr($curr_key, $_replace) . '</b> => '
- . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
- $depth--;
- }
- break;
- case 'object' :
- $object_vars = get_object_vars($var);
- $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
- foreach ($object_vars as $curr_key => $curr_val) {
- $results .= '<br>' . str_repeat(' ', $depth * 2)
- . '<b> ->' . strtr($curr_key, $_replace) . '</b> = '
- . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
- $depth--;
- }
- break;
- case 'boolean' :
- case 'NULL' :
- case 'resource' :
- if (true === $var) {
- $results = 'true';
- } elseif (false === $var) {
- $results = 'false';
- } elseif (null === $var) {
- $results = 'null';
- } else {
- $results = htmlspecialchars((string) $var);
- }
- $results = '<i>' . $results . '</i>';
- break;
- case 'integer' :
- case 'float' :
- $results = htmlspecialchars((string) $var);
- break;
- case 'string' :
- $results = strtr($var, $_replace);
- if (strlen($var) > $length ) {
- $results = substr($var, 0, $length - 3) . '...';
- }
- $results = htmlspecialchars('"' . $results . '"');
- break;
- case 'unknown type' :
- default :
- $results = strtr((string) $var, $_replace);
- if (strlen($results) > $length ) {
- $results = substr($results, 0, $length - 3) . '...';
- }
- $results = htmlspecialchars($results);
- }
-
- return $results;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty default modifier plugin
- *
- * Type: modifier<br>
- * Name: default<br>
- * Purpose: designate default value for empty variables
- * @link http://smarty.php.net/manual/en/language.modifier.default.php
- * default (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param string
- * @return string
- */
-function smarty_modifier_default($string, $default = '')
-{
- if (!isset($string) || $string === '')
- return $default;
- else
- return $string;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty escape modifier plugin
- *
- * Type: modifier<br>
- * Name: escape<br>
- * Purpose: Escape the string according to escapement type
- * @link http://smarty.php.net/manual/en/language.modifier.escape.php
- * escape (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param html|htmlall|url|quotes|hex|hexentity|javascript
- * @return string
- */
-function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
-{
- switch ($esc_type) {
- case 'html':
- return htmlspecialchars($string, ENT_QUOTES, $char_set);
-
- case 'htmlall':
- return htmlentities($string, ENT_QUOTES, $char_set);
-
- case 'url':
- return rawurlencode($string);
-
- case 'urlpathinfo':
- return str_replace('%2F','/',rawurlencode($string));
-
- case 'quotes':
- // escape unescaped single quotes
- return preg_replace("%(?<!\\\\)'%", "\\'", $string);
-
- case 'hex':
- // escape every character into hex
- $return = '';
- for ($x=0; $x < strlen($string); $x++) {
- $return .= '%' . bin2hex($string[$x]);
- }
- return $return;
-
- case 'hexentity':
- $return = '';
- for ($x=0; $x < strlen($string); $x++) {
- $return .= '&#x' . bin2hex($string[$x]) . ';';
- }
- return $return;
-
- case 'decentity':
- $return = '';
- for ($x=0; $x < strlen($string); $x++) {
- $return .= '&#' . ord($string[$x]) . ';';
- }
- return $return;
-
- case 'javascript':
- // escape quotes and backslashes, newlines, etc.
- return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
-
- case 'mail':
- // safe way to display e-mail address on a web page
- return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
-
- case 'nonstd':
- // escape non-standard chars, such as ms document quotes
- $_res = '';
- for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
- $_ord = ord(substr($string, $_i, 1));
- // non-standard char, escape it
- if($_ord >= 126){
- $_res .= '&#' . $_ord . ';';
- }
- else {
- $_res .= substr($string, $_i, 1);
- }
- }
- return $_res;
-
- default:
- return $string;
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty indent modifier plugin
- *
- * Type: modifier<br>
- * Name: indent<br>
- * Purpose: indent lines of text
- * @link http://smarty.php.net/manual/en/language.modifier.indent.php
- * indent (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param integer
- * @param string
- * @return string
- */
-function smarty_modifier_indent($string,$chars=4,$char=" ")
-{
- return preg_replace('!^!m',str_repeat($char,$chars),$string);
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty lower modifier plugin
- *
- * Type: modifier<br>
- * Name: lower<br>
- * Purpose: convert string to lowercase
- * @link http://smarty.php.net/manual/en/language.modifier.lower.php
- * lower (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return string
- */
-function smarty_modifier_lower($string)
-{
- return strtolower($string);
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty plugin
- *
- * Type: modifier<br>
- * Name: nl2br<br>
- * Date: Feb 26, 2003
- * Purpose: convert \r\n, \r or \n to <<br>>
- * Input:<br>
- * - contents = contents to replace
- * - preceed_test = if true, includes preceeding break tags
- * in replacement
- * Example: {$text|nl2br}
- * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
- * nl2br (Smarty online manual)
- * @version 1.0
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return string
- */
-function smarty_modifier_nl2br($string)
-{
- return nl2br($string);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty regex_replace modifier plugin
- *
- * Type: modifier<br>
- * Name: regex_replace<br>
- * Purpose: regular expression search/replace
- * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
- * regex_replace (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param string|array
- * @param string|array
- * @return string
- */
-function smarty_modifier_regex_replace($string, $search, $replace)
-{
- if(is_array($search)) {
- foreach($search as $idx => $s)
- $search[$idx] = _smarty_regex_replace_check($s);
- } else {
- $search = _smarty_regex_replace_check($search);
- }
-
- return preg_replace($search, $replace, $string);
-}
-
-function _smarty_regex_replace_check($search)
-{
- if (($pos = strpos($search,"\0")) !== false)
- $search = substr($search,0,$pos);
- if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
- /* remove eval-modifier from $search */
- $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
- }
- return $search;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty replace modifier plugin
- *
- * Type: modifier<br>
- * Name: replace<br>
- * Purpose: simple search/replace
- * @link http://smarty.php.net/manual/en/language.modifier.replace.php
- * replace (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param string
- * @param string
- * @return string
- */
-function smarty_modifier_replace($string, $search, $replace)
-{
- return str_replace($search, $replace, $string);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty spacify modifier plugin
- *
- * Type: modifier<br>
- * Name: spacify<br>
- * Purpose: add spaces between characters in a string
- * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
- * spacify (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param string
- * @return string
- */
-function smarty_modifier_spacify($string, $spacify_char = ' ')
-{
- return implode($spacify_char,
- preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty string_format modifier plugin
- *
- * Type: modifier<br>
- * Name: string_format<br>
- * Purpose: format strings via sprintf
- * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
- * string_format (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param string
- * @return string
- */
-function smarty_modifier_string_format($string, $format)
-{
- return sprintf($format, $string);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty strip modifier plugin
- *
- * Type: modifier<br>
- * Name: strip<br>
- * Purpose: Replace all repeated spaces, newlines, tabs
- * with a single space or supplied replacement string.<br>
- * Example: {$var|strip} {$var|strip:" "}
- * Date: September 25th, 2002
- * @link http://smarty.php.net/manual/en/language.modifier.strip.php
- * strip (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @version 1.0
- * @param string
- * @param string
- * @return string
- */
-function smarty_modifier_strip($text, $replace = ' ')
-{
- return preg_replace('!\s+!', $replace, $text);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty strip_tags modifier plugin
- *
- * Type: modifier<br>
- * Name: strip_tags<br>
- * Purpose: strip html tags from text
- * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
- * strip_tags (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param boolean
- * @return string
- */
-function smarty_modifier_strip_tags($string, $replace_with_space = true)
-{
- if ($replace_with_space)
- return preg_replace('!<[^>]*?>!', ' ', $string);
- else
- return strip_tags($string);
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty truncate modifier plugin
- *
- * Type: modifier<br>
- * Name: truncate<br>
- * Purpose: Truncate a string to a certain length if necessary,
- * optionally splitting in the middle of a word, and
- * appending the $etc string or inserting $etc into the middle.
- * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
- * truncate (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param integer
- * @param string
- * @param boolean
- * @param boolean
- * @return string
- */
-function smarty_modifier_truncate($string, $length = 80, $etc = '...',
- $break_words = false, $middle = false)
-{
- if ($length == 0)
- return '';
-
- if (strlen($string) > $length) {
- $length -= min($length, strlen($etc));
- if (!$break_words && !$middle) {
- $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
- }
- if(!$middle) {
- return substr($string, 0, $length) . $etc;
- } else {
- return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
- }
- } else {
- return $string;
- }
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty upper modifier plugin
- *
- * Type: modifier<br>
- * Name: upper<br>
- * Purpose: convert string to uppercase
- * @link http://smarty.php.net/manual/en/language.modifier.upper.php
- * upper (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return string
- */
-function smarty_modifier_upper($string)
-{
- return strtoupper($string);
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Smarty wordwrap modifier plugin
- *
- * Type: modifier<br>
- * Name: wordwrap<br>
- * Purpose: wrap a string of text at a given length
- * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
- * wordwrap (Smarty online manual)
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @param integer
- * @param string
- * @param boolean
- * @return string
- */
-function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
-{
- return wordwrap($string,$length,$break,$cut);
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-/**
- * Smarty trimwhitespace outputfilter plugin
- *
- * File: outputfilter.trimwhitespace.php<br>
- * Type: outputfilter<br>
- * Name: trimwhitespace<br>
- * Date: Jan 25, 2003<br>
- * Purpose: trim leading white space and blank lines from
- * template source after it gets interpreted, cleaning
- * up code and saving bandwidth. Does not affect
- * <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
- * Install: Drop into the plugin directory, call
- * <code>$smarty->load_filter('output','trimwhitespace');</code>
- * from application.
- * @author Monte Ohrt <monte at ohrt dot com>
- * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
- * @version 1.3
- * @param string
- * @param Smarty
- */
-function smarty_outputfilter_trimwhitespace($source, &$smarty)
-{
- // Pull out the script blocks
- preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
- $_script_blocks = $match[0];
- $source = preg_replace("!<script[^>]*?>.*?</script>!is",
- '@@@SMARTY:TRIM:SCRIPT@@@', $source);
-
- // Pull out the pre blocks
- preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
- $_pre_blocks = $match[0];
- $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
- '@@@SMARTY:TRIM:PRE@@@', $source);
-
- // Pull out the textarea blocks
- preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
- $_textarea_blocks = $match[0];
- $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
- '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
-
- // remove all leading spaces, tabs and carriage returns NOT
- // preceeded by a php close tag.
- $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
-
- // replace textarea blocks
- smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
-
- // replace pre blocks
- smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
-
- // replace script blocks
- smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
-
- return $source;
-}
-
-function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
- $_len = strlen($search_str);
- $_pos = 0;
- for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
- if (($_pos=strpos($subject, $search_str, $_pos))!==false)
- $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
- else
- break;
-
-}
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty shared plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * escape_special_chars common function
- *
- * Function: smarty_function_escape_special_chars<br>
- * Purpose: used by other smarty functions to escape
- * special chars except for already escaped ones
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return string
- */
-function smarty_function_escape_special_chars($string)
-{
- if(!is_array($string)) {
- $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
- $string = htmlspecialchars($string);
- $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
- }
- return $string;
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
-<?php
-/**
- * Smarty shared plugin
- * @package Smarty
- * @subpackage plugins
- */
-
-
-/**
- * Function: smarty_make_timestamp<br>
- * Purpose: used by other smarty functions to make a timestamp
- * from a string.
- * @author Monte Ohrt <monte at ohrt dot com>
- * @param string
- * @return string
- */
-function smarty_make_timestamp($string)
-{
- if(empty($string)) {
- // use "now":
- $time = time();
-
- } elseif (preg_match('/^\d{14}$/', $string)) {
- // it is mysql timestamp format of YYYYMMDDHHMMSS?
- $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
- substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
-
- } elseif (is_numeric($string)) {
- // it is a numeric string, we handle it as timestamp
- $time = (int)$string;
-
- } else {
- // strtotime should handle it
- $time = strtotime($string);
- if ($time == -1 || $time === false) {
- // strtotime() was not able to parse $string, use "now":
- $time = time();
- }
- }
- return $time;
-
-}
-
-/* vim: set expandtab: */
-
-?>
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-\f
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
+++ /dev/null
-2004-03-01 Sagi Bashari <sagi@boom.org.il>
-
- * tsmarty2c.php:
- - added support for directories (originally by Uros Gruber <uros.gruber@vizija.si>)
- - fixed bug that prevented more than 1 block per line (reported by Eneko Lacunza <enlar@euskal.org>)
- - convert new line to \n in output string
-
- * smarty_gettext.php:
- - run nl2br() when escaping html
+++ /dev/null
-Gettext support for Smarty
---------------------------
-
-Author: Sagi Bashari <sagi@boom.org.il>
-URL: http://www.boom.org.il/smarty/gettext/
-Support URL: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=84
-
-This file assumes that you already know what is gettext and how to use it with PHP.
-If you don't, please visit the following websites before trying to use this package:
- - http://www.php.net/gettext
- - http://www.onlamp.com/pub/a/php/2002/06/13/php.html
-
-This package has two parts:
- 1. smarty_gettext.php - The smarty plugin
- 2. tsmarty2c.php - command line utility that rips gettext strings from smarty source files and converts them to C format
-
-The Smarty plugin
------------------
-
-Installation:
-
-1. Copy the smarty_gettext.php file to your include directory.
-2. After initializing the smarty object in your script, register the plugin as a block function.
-
-Example:
-$smarty = new Smarty [...];
-require('smarty_gettext.php');
-$smarty->register_block('t', 'smarty_translate');
-
-This example will register the function as a block function named 't'.
-
-Usage:
-
-The content of the block function is the string that you want to translate. For example, for translating 'Hello World', use: {t}Hello World{/t}.
-
-If you have dynamic parameters that should be set inside the string, pass them to the block function, and they will be replaced with %n, where n is 1 for the 1st parameter and so on. For example, {t name="sagi"}my name is %1{/t} will replace %1 with name.
-
-The parameter name is ignored, unless it is one of the reserved names (see below). Only the parameters order matters.
-
-Example for using multiple parameters:
-{t 1='one' 2='two' 3='three'}The 1st parameter is %1, the 2nd is %2 and the 3nd %3.{/t}
-
-NOTE: I decided to use numeric arguments instead of sprintf(), because it offers greater control over the parameter placement in the translated text. You can also use this in your PHP code, by using the strarg() function, like this: strarg(_('hi %1'), $name [,..]).
-
-By default all the translated strings will be automatically HTML escaped. You may control this by setting the 'escape' parameter. Possible values:
- - 'html' for HTML escaping, this is the default.
- - 'js' for javascript escaping.
- - 'no'/'off'/0 - turns off escaping
-
- Example: {t escape=no url="http://www.php.net/" name="PHP website"}<a href="%1">%2</a>{/t}
-
-Plural support:
-
-The package also provides support for plural forms (see ngettext).
-
-To provide a plural form:
- 1. Set a parameter named 'plural' with the plural version of the string.
- 2. Set a parameter named 'count' with the variable count.
-
-Example:
-{t count=$files|@count plural="%1 files"}%1 file{/t}
-
-
-tsmarty2c.php - the command line utility
-----------------------------------------
-
-This utility will rip the translation strings from the smarty files, and convert them to gettext calls in C, that can later be used with the standard gettext tools.
-
-Usage:
-./tsmarty2c.php <filename or directory> <file2> <..> > smarty.c
-
-If a parameter is a directory, the template files within will be parsed.
-
-Copyright
----------
-
-Copyright (c) 2004 Sagi Bashari
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+++ /dev/null
-<?php
-/**
- * smarty_gettext.php - Gettext support for smarty
- *
- * ------------------------------------------------------------------------- *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to the Free Software *
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * ------------------------------------------------------------------------- *
- *
- * To register as a smarty block function named 't', use:
- * $smarty->register_block('t', 'smarty_translate');
- *
- * @package smarty_gettext
- * @version 0.9
- * @link http://www.boom.org.il/smarty/gettext/
- * @author Sagi Bashari <sagi@boom.org.il>
- * @copyright 2004 Sagi Bashari
- */
-
-/**
- * Replace arguments in a string with their values. Arguments are represented by % followed by their number.
- *
- * @param string Source string
- * @param mixed Arguments, can be passed in an array or through single variables.
- * @returns string Modified string
- */
-function strarg($str)
-{
- $tr = array();
- $p = 0;
-
- for ($i=1; $i < func_num_args(); $i++) {
- $arg = func_get_arg($i);
-
- if (is_array($arg)) {
- foreach ($arg as $aarg) {
- $tr['%'.++$p] = $aarg;
- }
- } else {
- $tr['%'.++$p] = $arg;
- }
- }
-
- return strtr($str, $tr);
-}
-
-/**
- * Smarty block function, provides gettext support for smarty.
- *
- * The block content is the text that should be translated.
- *
- * Any parameter that is sent to the function will be represented as %n in the translation text,
- * where n is 1 for the first parameter. The following parameters are reserved:
- * - escape - sets escape mode:
- * - 'html' for HTML escaping, this is the default.
- * - 'js' for javascript escaping.
- * - 'no'/'off'/0 - turns off escaping
- * - plural - The plural version of the text (2nd parameter of ngettext())
- * - count - The item count for plural mode (3rd parameter of ngettext())
- */
-function smarty_translate($params, $text, &$smarty)
-{
- $text = stripslashes($text);
-
- // set escape mode
- if (isset($params['escape'])) {
- $escape = $params['escape'];
- unset($params['escape']);
- }
-
- // set plural version
- if (isset($params['plural'])) {
- $plural = $params['plural'];
- unset($params['plural']);
-
- // set count
- if (isset($params['count'])) {
- $count = $params['count'];
- unset($params['count']);
- }
- }
-
- // use plural if required parameters are set
- if (isset($count) && isset($plural)) {
- $text = ngettext($text, $plural, $count);
- } else { // use normal
- $text = gettext($text);
- }
-
- // run strarg if there are parameters
- if (count($params)) {
- $text = strarg($text, $params);
- }
-
- if (!isset($escape) || $escape == 'html') { // html escape, default
- $text = nl2br(htmlspecialchars($text));
- } elseif (isset($escape) && ($escape == 'javascript' || $escape == 'js')) { // javascript escape
- $text = str_replace('\'','\\\'',stripslashes($text));
- }
-
- return $text;
-}
-
-?>
+++ /dev/null
-#!/usr/local/bin/php -qn
-<?php
-/**
- * tsmarty2c.php - rips gettext strings from smarty template
- *
- * ------------------------------------------------------------------------- *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to the Free Software *
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * ------------------------------------------------------------------------- *
- *
- * This command line script rips gettext strings from smarty file, and prints them to stdout in C format,
- * that can later be used with the standard gettext tools.
- *
- * Usage:
- * ./tsmarty2c.php <filename or directory> <file2> <..> > smarty.c
- *
- * If a parameter is a directory, the template files within will be parsed.
- *
- * @package smarty_gettext
- * @version 0.9
- * @link http://www.boom.org.il/smarty/gettext/
- * @author Sagi Bashari <sagi@boom.org.il>
- * @copyright 2004 Sagi Bashari
- */
-
-// smarty open tag
-$ldq = preg_quote('{');
-
-// smarty close tag
-$rdq = preg_quote('}');
-
-// smarty command
-$cmd = preg_quote('t');
-
-// extensions of smarty files, used when going through a directory
-$extensions = array('tpl');
-
-// "fix" string - strip slashes, escape and convert new lines to \n
-function fs($str)
-{
- $str = stripslashes($str);
- $str = str_replace('"', '\"', $str);
- $str = str_replace("\n", '\n', $str);
- return $str;
-}
-
-// rips gettext strings from $file and prints them in C format
-function do_file($file)
-{
- $content = @file_get_contents($file);
-
- if (empty($content)) {
- return;
- }
-
- global $ldq, $rdq, $cmd;
-
- preg_match_all("/{$ldq}\s*({$cmd})\s*([^{$rdq}]*){$rdq}([^{$ldq}]*){$ldq}\/\\1{$rdq}/", $content, $matches);
-
- for ($i=0; $i < count($matches[0]); $i++) {
- if (preg_match('/plural\s*=\s*["\']?\s*(.[^\"\']*)\s*["\']?/', $matches[2][$i], $match)) {
- print 'ngettext("'.fs($matches[3][$i]).'","'.fs($match[1]).'",x);'."\n";
- } else {
- print 'gettext("'.fs($matches[3][$i]).'");'."\n";
- }
- }
-}
-
-// go through a directory
-function do_dir($dir)
-{
- $d = dir($dir);
-
- while (false !== ($entry = $d->read())) {
- if ($entry == '.' || $entry == '..') {
- continue;
- }
-
- $entry = $dir.'/'.$entry;
-
- if (is_dir($entry)) { // if a directory, go through it
- do_dir($entry);
- } else { // if file, parse only if extension is matched
- $pi = pathinfo($entry);
-
- if (in_array($pi['extension'], $GLOBALS['extensions'])) {
- do_file($entry);
- }
- }
- }
-
- $d->close();
-}
-
-for ($ac=1; $ac < $_SERVER['argc']; $ac++) {
- if (is_dir($_SERVER['argv'][$ac])) { // go through directory
- do_dir($_SERVER['argv'][$ac]);
- } else { // do file
- do_file($_SERVER['argv'][$ac]);
- }
-}
-
-?>
+++ /dev/null
-<?php
-
-class BGraph{
- private $title;
-
- private $data;
- private $data_type;
- private $type;
-
- private $colors;
- private $shading;
-
- private $width;
- private $height;
- private $output_file;
- private $plot;
-
- function __construct( $filename = "graph.png" )
- {
- $this->output_file = 'templates_c/' . $filename;
- }
-
- public function SetData( $data_in, $type, $data_type, $shading = 5 )
- {
- $this->data = $data_in;
- $this->type = $type;
- $this->data_type = $data_type;
- $this->shadding = $shading;
- }
-
- public function SetGraphSize( $width, $height )
- {
- $this->width = $width;
- $this->height = $height;
- }
-
- public function SetTitle( $title )
- {
- if( !empty($title) )
- $this->title = $title;
- else
- die( "Please provide a non empty title for the graph" );
- }
-
- public function SetColors( $colors )
- {
- if( is_array( $colors ) )
- $this->colors = $colors;
- else
- die( "Please provide a array in BGraph->SetColors()" );
- }
-
- public function Get_Image_file()
- {
- return $this->output_file;
- }
-
- public function Render()
- {
- // Setting the size
- $this->plot = new PHPlot( $this->width, $this->height );
-
- // Render to file instead of screen
- $this->plot->SetOutputFile( $this->output_file );
- $this->plot->SetFileFormat("png");
- $this->plot->SetIsInline( true );
-
-
- $this->plot->SetImageBorderType('plain');
-
- // Data, type and data type
- $this->plot->SetPlotType( $this->type );
- $this->plot->SetDataType( $this->data_type );
- $this->plot->SetDataValues( $this->data );
-
- // Plot colors
- $this->plot->SetDataColors( $this->colors );
-
- // Plot shading
- $this->plot->SetShading( $this->shading );
-
- // Image border
- $this->plot->SetImageBorderType( 'none' );
-
- // Plot area (calculated regarding the width and height of the graph)
- if( $this->type == 'pie' )
- $this->plot->SetPlotAreaPixels( 10, 10, ($this->width / 2), $this->height-10 );
-
- // Legend position (calculated regarding the width and height of the graph)
- $this->plot->SetLegendPixels( ($this->width / 2) + 10, 25 );
-
- // Labels scale position
- if( $this->type == 'pie' )
- $this->plot->SetLabelScalePosition( 0.2 );
-
- // Graph title
- $this->plot->SetTitle( $this->title );
-
- // Setting up legends
- if( $this->type != 'bars' ) {
- $legends = array();
- foreach( $this->data as $key => $legend ) {
- $this->plot->SetLegend( implode(': ',$legend) );
- }
- }
-
- # Turn off X tick labels and ticks because they don't apply here:
- $this->plot->SetXTickLabelPos('none');
- $this->plot->SetXTickPos('none');
- $this->plot->SetPlotAreaWorld(NULL, 0, NULL, NULL);
-
-
- $this->plot->DrawGraph();
- } // end function Render()
-} // end BGraph classe
-
-?>
<?php
define( 'BW_ROOT', getcwd() );
- define( 'BW_OBJ', BW_ROOT . '/classes/' );
+ define( 'BW_OBJ', BW_ROOT . '/includes/' );
define( 'BW_EXTERNAL', BW_OBJ . 'external' );
define( 'BW_PHPLOT', BW_EXTERNAL . '/phplot/' );
--- /dev/null
+<?php
+/*
++-------------------------------------------------------------------------+
+| Copyright (C) 2004-2005 Juan Luis Frances Jiminez |
+| |
+| This program 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 2 |
+| of the License, or (at your option) any later version. |
+| |
+| This program 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. |
++-------------------------------------------------------------------------+
+*/
+require_once "config.inc.php";
+
+class Bweb extends DB {
+
+ var $StartDate;
+ var $EndDate;
+
+ var $driver;
+
+ public $tpl;
+ public $db_link; // Database link
+
+ private $config_file; // Config filename
+ private $config; // Loaded config from bacula.conf
+ private $catalogs = array(); // Catalog array
+ public $catalog_nb;
+ private $bwcfg;
+
+ function __construct()
+ {
+ $this->bwcfg = new BW_Config();
+ $dsn = array();
+
+ // Checking if config file exist and is readable
+ if( !$this->bwcfg->Check_Config_File() )
+ die( "Unable to load configuration file" );
+ else {
+ $this->bwcfg->Load_Config();
+ $this->catalog_nb = $this->bwcfg->Count_Catalogs();
+ }
+
+ // Select which catalog to connect to
+ if( isset( $_POST['catalog_id'] ) )
+ $dsn = $this->bwcfg->Get_Dsn( $_POST['catalog_id'] );
+ else
+ $dsn = $this->bwcfg->Get_Dsn( 0 );
+
+ // Connect to the database
+ $this->db_link = $this->connect( $dsn );
+
+ if (DB::isError($this->db_link)) {
+ die( 'Unable to connect to catalog <br />' . $this->db_link->getMessage());
+ }else {
+ $this->driver = $dsn['phptype'];
+ register_shutdown_function(array(&$this,'close') );
+ }
+
+ // Initialize smarty template classe
+ $this->init_tpl();
+ // Initialize smarty gettext function
+ $this->init_gettext();
+
+ // Catalog selection
+ if( $this->catalog_nb > 1 ) {
+ // Set current catalog in header template
+ if(isset( $_POST['catalog_id'] ) )
+ $this->tpl->assign( 'catalog_current', $_POST['catalog_id'] );
+
+ $this->tpl->assign( 'catalogs', $this->bwcfg->Get_Catalogs() );
+ }else
+ {
+
+ }
+ }
+
+ // Initialize Smarty template classe
+ function init_tpl()
+ {
+ $this->tpl = new Smarty();
+
+ $this->tpl->compile_check = true;
+ $this->tpl->debugging = false;
+ $this->tpl->force_compile = true;
+
+ $this->tpl->template_dir = "./templates";
+ $this->tpl->compile_dir = "./templates_c";
+ $this->tpl->config_dir = "./configs";
+ }
+
+ function init_gettext()
+ {
+ global $smarty_gettext_path;
+
+ if ( function_exists("gettext") ) {
+ require_once( BW_SMARTY_GETTEXT . "smarty_gettext.php" );
+ $this->tpl->register_block('t','smarty_translate');
+
+ $language = $this->bwcfg->Get_Config_Param("lang");
+ $domain = "messages";
+ putenv("LANG=$language");
+ setlocale(LC_ALL, $language);
+ bindtextdomain($domain,"./locale");
+ textdomain($domain);
+ }
+ else {
+ function smarty_translate($params, $text, &$smarty) {
+ return $text;
+ }
+ $smarty->register_block('t','smarty_translate');
+ }
+ }
+
+ function close()
+ {
+ $this->db_link->disconnect();
+ }
+
+ // Return humanized size with default unit of GB
+ // if auto provide for unit argument, automaticaly decide which unit
+ function human_file_size( $size, $decimal = 2, $unit = 'auto' )
+ {
+ $unit_id = 0;
+ $lisible = false;
+ $units = array('B','KB','MB','GB','TB');
+ $hsize = $size;
+
+ switch( $unit )
+ {
+ case 'auto';
+ while( !$lisible ) {
+ if ( $hsize >= 1024 ) {
+ $hsize = $hsize / 1024;
+ $unit_id += 1;
+ }
+ else
+ $lisible = true;
+ } // end while
+ break;
+
+ default:
+ $p = array_search( $unit, $units);
+ $hsize = $hsize / pow(1024,$p);
+ break;
+ } // end switch
+
+ $hsize = sprintf("%." . $decimal . "f", $hsize);
+ $hsize = $hsize . ' ' . $units[$unit_id];
+ return $hsize;
+ } // end function
+
+
+ function GetDbSize()
+ {
+ $database_size = 0;
+ $query = "";
+
+ switch( $this->driver )
+ {
+ case 'mysql':
+ $query = "SELECT table_schema AS 'database', sum( data_length + index_length) AS 'dbsize' ";
+ $query .= "FROM information_schema.TABLES ";
+ $query .= "WHERE table_schema = 'bacula' ";
+ $query .= "GROUP BY table_schema";
+ break;
+ case 'pgsql':
+ $query = "SELECT pg_database_size('bacula') AS dbsize";
+ break;
+ case 'sqlite':
+ // Not yet implemented
+ return "0 MB";
+ break;
+ }
+
+ $result = $this->db_link->query( $query );
+
+ if(! PEAR::isError( $result ) )
+ {
+ $db = $result->fetchRow( DB_FETCHMODE_ASSOC );
+ $database_size =+ $db['dbsize'];
+ }else
+ die( "Unable to get database size<br />" . $result->getMessage() );
+
+ return $this->human_file_size( $database_size );
+ } // end function GetDbSize()
+
+ public function Get_Nb_Clients()
+ {
+ $clients = $this->db_link->query("SELECT COUNT(*) AS nb_client FROM Client");
+ if( PEAR::isError($clients) )
+ die( "Unable to get client number" );
+ else
+ return $clients->fetchRow( DB_FETCHMODE_ASSOC );
+ }
+
+ // Return an array of volumes ordered by poolid and volume name
+ function GetVolumeList() {
+
+ $volumes = array();
+ $query = "";
+ $debug = false;
+
+ // Get the list of pools id
+ $query = "SELECT Pool.poolid, Pool.name FROM Pool ORDER BY Pool.poolid";
+
+ //$this->db_link->setFetchMode(DB_FETCHMODE_ASSOC);
+ $pools = $this->db_link->query( $query );
+
+ if( PEAR::isError( $pools ) )
+ die("Error: Failed to get pool list <br />SQL Query: $query<br />" . $pools->getMessage() );
+
+ while( $pool = $pools->fetchRow( DB_FETCHMODE_ASSOC ) ) {
+ switch( $this->driver )
+ {
+ case 'mysql':
+ $query = "SELECT Media.volumename, Media.volbytes, Media.volstatus, Media.mediatype, Media.lastwritten, Media.volretention
+ FROM Media LEFT JOIN Pool ON Media.poolid = Pool.poolid
+ WHERE Media.poolid = '". $pool['poolid'] . "' ORDER BY Media.volumename";
+ break;
+ case 'pgsql':
+ $query = "SELECT media.volumename, media.volbytes, media.volstatus, media.mediatype, media.lastwritten, media.volretention
+ FROM media LEFT JOIN pool ON media.poolid = pool.poolid
+ WHERE media.poolid = '". $pool['poolid'] . "' ORDER BY media.volumename";
+ break;
+ case 'sqlite':
+ $query = ""; // not yet implemented
+ break;
+ default:
+ break;
+ } // end switch
+
+ $medias = $this->db_link->query( $query );
+
+ if( PEAR::isError( $medias ) ) {
+ die( "Failed to get media list for pool $volume[0] <br /> " . $medias->getMessage() );
+ }else {
+ if( $debug ) echo "Found " . $medias->numRows() . " medias for pool " . $pool['name'] . " <br />";
+
+ // Create array key for each pool
+ if( !array_key_exists( $pool['name'], $volumes) )
+ {
+ $volumes[ $pool['name'] ] = array();
+ }
+ while( $media = $medias->fetchRow( DB_FETCHMODE_ASSOC ) ) {
+ if( $debug ) {
+ var_dump( $media );
+ }
+ // If the pool is empty (no volumes in this pool)
+ if( $medias->numRows() == 0 ) {
+ if( $debug ) echo "No media in pool " . $pool['name'] . "<br />";
+ } else {
+ if( $media['lastwritten'] != "0000-00-00 00:00:00" ) {
+ // Calculate expiration date if the volume is Full
+ if( $media['volstatus'] == 'Full' ) {
+ $expire_date = strtotime($media['lastwritten']) + $media['volretention'];
+ $media['expire'] = strftime("%Y-%m-%d", $expire_date);
+ }else {
+ $media['expire'] = 'N/A';
+ }
+ // Media used bytes in a human format
+ $media['volbytes'] = $this->human_file_size( $media['volbytes'] );
+ } else {
+ $media['lastwritten'] = "N/A";
+ $media['expire'] = "N/A";
+ $media['volbytes'] = "0 KB";
+ }
+
+ // Odd or even row
+ if( count( $volumes[ $pool['name'] ] ) % 2)
+ $media['class'] = 'odd';
+
+ // Add the media in pool array
+ array_push( $volumes[ $pool['name']], $media);
+ }
+ } // end while
+ } // end if else
+ } // end while
+ return $volumes;
+ } // end function GetVolumeList()
+
+ public function CountJobsbyLevel( $delay = LAST_DAY, $level = 'F' )
+ {
+ $end_date = mktime();
+ $start_date = $end_date - $delay;
+
+ $start_date = date( "Y-m-d H:i:s", $start_date );
+ $end_date = date( "Y-m-d H:i:s", $end_date );
+
+ $query = "SELECT COUNT(JobId) as jobs FROM Job ";
+ $query .= "WHERE (EndTime BETWEEN '$start_date' AND '$end_date') AND ";
+ $query .= "Level = '$level' ";
+
+ $result = $this->db_link->query( $query );
+
+ if (PEAR::isError( $result ) ) {
+ die( "Unable to get number of jobs with $level status from catalog <br />" . $result->getMessage() );
+ }else {
+ $jobs = $result->fetchRow( DB_FETCHMODE_ASSOC );
+ return $jobs['jobs'];
+ }
+
+ }
+
+ public function CountJobs( $delay = LAST_DAY, $status = 'any' )
+ {
+ $query = "SELECT COUNT(JobId) AS job_nb FROM Job ";
+ $where_delay = "";
+ $where_status = "";
+
+ // Interval condition for SQL query
+ if( $delay != ALL ) {
+ $end_date = mktime();
+ $start_date = $end_date - $delay;
+
+ $start_date = date( "Y-m-d H:i:s", $start_date );
+ $end_date = date( "Y-m-d H:i:s", $end_date );
+
+ $where_delay = "WHERE EndTime BETWEEN '$start_date' AND '$end_date' ";
+ }
+
+ if( $status != 'any' ) {
+ switch( $status )
+ {
+ case 'completed':
+ $where_status = "JobStatus = 'T' ";
+ break;
+ case 'failed':
+ $where_status = "JobStatus IN ('f','E') ";
+ break;
+ case 'canceled':
+ $where_status = "JobStatus = 'A' ";
+ break;
+ case 'waiting':
+ $where_status = "JobStatus IN ('F','S','M','m','s','j','c','d','t') ";
+ break;
+ } // end switch
+ }
+
+ if( !empty($where_delay) )
+ $query = $query . $where_delay . 'AND ' . $where_status;
+ else {
+ if( !empty($where_status) )
+ $query = $query . 'WHERE ' . $where_status;
+ }
+
+ $jobs = $this->db_link->query( $query );
+
+ if (PEAR::isError( $jobs ) ) {
+ die( "Unable to get last $status jobs number from catalog <br />" . $jobs->getMessage() );
+ }else {
+ $jobs = $jobs->fetchRow( DB_FETCHMODE_ASSOC );
+ return $jobs['job_nb'];
+ }
+ }
+
+ // Return the list of Pools in a array
+ public function Get_Pools_List()
+ {
+ $pool_list = array();
+ $result = "";
+
+ $query = "SELECT Name, PoolId FROM Pool";
+
+ $result = $this->db_link->query ( $query );
+
+ if( PEAR::isError( $result ) ) {
+ die( "Unable to get the pool list from catalog" );
+ }else {
+ while( $pool = $result->fetchRow(DB_FETCHMODE_ASSOC) ) {
+ array_push( $pool_list, array( $pool['Name'] => $pool['PoolId'] ) );
+ }
+ return $pool_list;
+ }
+ }
+
+ public function Get_BackupJob_Names()
+ {
+ $query = "SELECT Name FROM Job GROUP BY Name";
+ $backupjobs = array();
+
+ $result = $this->db_link->query( $query );
+
+ if (PEAR::isError( $result ) ) {
+ die("Unable to get BackupJobs list from catalog" );
+ }else{
+ while( $backupjob = $result->fetchRow( DB_FETCHMODE_ASSOC ) ) {
+ array_push( $backupjobs, $backupjob["Name"] );
+ }
+ return $backupjobs;
+ }
+ }
+
+ // Return elasped time string for a job
+ function Get_ElapsedTime( $start_time, $end_time )
+ {
+ $diff = $end_time - $start_time;
+
+ $daysDiff = sprintf("%02d", floor($diff/60/60/24) );
+ $diff -= $daysDiff*60*60*24;
+
+ $hrsDiff = sprintf("%02d", floor($diff/60/60) );
+ $diff -= $hrsDiff*60*60;
+
+ $minsDiff = sprintf("%02d", floor($diff/60) );
+ $diff -= $minsDiff*60;
+ $secsDiff = sprintf("%02d", $diff );
+
+ if( $daysDiff > 0 )
+ return $daysDiff . 'day(s) ' . $hrsDiff.':' . $minsDiff . ':' . $secsDiff;
+ else
+ return $hrsDiff . ':' . $minsDiff . ':' . $secsDiff;
+ }
+
+ public function Get_ElapsedTime_Job( $delay = LAST_DAY )
+ {
+ $query = "";
+ $total_elapsed = 0;
+
+ // Interval calculation
+ $end_date = mktime();
+ $start_date = $end_date - $delay;
+
+ $start_date = date( "Y-m-d H:i:s", $start_date );
+ $end_date = date( "Y-m-d H:i:s", $end_date );
+
+ switch( $this->driver )
+ {
+ case 'mysql':
+ $query = "SELECT UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime) AS elapsed from Job ";
+ $query .= "WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
+ break;
+ }
+ $result = $this->db_link->query( $query );
+
+ if( PEAR::isError($result) ){
+ die( "Unable to get elapsed time for jobs from catalog<br />query = $query <br />" . $result->getMessage() );
+ }else {
+ while( $time = $result->fetchRow( DB_FETCHMODE_ASSOC ) ) {
+ //echo 'elapsed = ' . $time['elapsed'] . '<br />';
+ $total_elapsed += $time['elapsed'];
+ }
+ // Verify if elapsed time is more than 1 day
+ if ( $total_elapsed > LAST_DAY ) {
+ return date("%d days H:i:s", $total_elapsed );
+ }else {
+ return date("H:i:s", $total_elapsed );
+ }
+ }
+ }
+
+ // Return Jobs statistics for a specific interval such as
+ // - Completed jobs number
+ // - Failed jobs number
+ // - Waiting jobs number
+ // The returned values will be used by a Bgraph classe
+ public function GetJobsStatistics( $type = 'completed', $delay = LAST_DAY )
+ {
+ $query = "";
+ $where = "";
+ $jobs = "";
+ $label = "";
+ $res = "";
+
+ // Interval calculation
+ $end_date = mktime();
+ $start_date = $end_date - $delay;
+
+ $start_date = date( "Y-m-d H:i:s", $start_date );
+ $end_date = date( "Y-m-d H:i:s", $end_date );
+
+ $interval_where = "(EndTime BETWEEN '$start_date' AND '$end_date') AND ";
+
+ // Job status
+ switch( $type )
+ {
+ case 'completed':
+ $where = $interval_where . "JobStatus = 'T' ";
+ $label = "Completed";
+ break;
+ case 'terminated_errors':
+ $where = $interval_where . "JobStatus = 'E' ";
+ $label = "Terminated with errors";
+ break;
+ case 'failed':
+ $where = $interval_where . "JobStatus = 'f' ";
+ $label = "Failed";
+ break;
+ case 'waiting':
+ $where = "JobStatus IN ('F','S','M','m','s','j','c','d','t') ";
+ $label = "Waiting";
+ break;
+ case 'created':
+ $where = "JobStatus = 'C' ";
+ $label = "Created but not running";
+ break;
+ case 'running':
+ $where = "JobStatus = 'R' ";
+ $label = "Running";
+ break;
+ case 'error':
+ $where = $interval_where . "JobStatus IN ('e','f') ";
+ $label = "Errors";
+ break;
+ }
+
+ $query = 'SELECT COUNT(JobId) AS ' . $type . ' ';
+ $query .= 'FROM Job ';
+ $query .= "WHERE $where ";
+
+ //echo 'query = ' . $query . '<br />';
+
+ $jobs = $this->db_link->query( $query );
+
+ if (PEAR::isError( $jobs ) ) {
+ die( "Unable to get last $type jobs status from catalog<br />" . $status->getMessage() );
+ }else {
+ $res = $jobs->fetchRow();
+ return array( $label , current($res) );
+ }
+ } // end function GetJobsStatistics()
+
+ public function GetPoolsStatistics( $pools )
+ {
+ foreach( $pools as $pool_name => $pool ) {
+ //var_dump( $pool );
+ $query = "SELECT COUNT(*) AS nb_vol FROM Media WHERE PoolId = '$pool'";
+ //echo $query . '<br />';
+ //echo 'Pool name ' . $pool_name . '<br />';
+ $result = $this->db_link->query( $query );
+
+ if( PEAR::isError( $result ) ) {
+ die("Unable to get volume number from catalog");
+ }else{
+ $nb_vol = $result->fetchRow(DB_FETCHMODE_ASSOC);
+ return array( $pool_name, $nb_vol['nb_vol'] );
+ }
+ }
+ }
+
+ public function GetStoredFiles( $delay = LAST_DAY )
+ {
+ $totalfiles = 0;
+
+ $query = "SELECT SUM(JobFiles) AS stored_files FROM Job ";
+
+ // Interval calculation
+ $end_date = mktime();
+ $start_date = $end_date - $delay;
+
+ $start_date = date( "Y-m-d H:i:s", $start_date );
+ $end_date = date( "Y-m-d H:i:s", $end_date );
+
+ if( $delay != ALL )
+ $query .= "WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
+
+ $result = $this->db_link->query( $query );
+
+ if( !PEAR::isError($result) ) {
+ $nbfiles = $result->fetchRow(DB_FETCHMODE_ASSOC);
+ $totalfiles = $totalfiles + $nbfiles['stored_files'];
+ }else{
+ die("Unable to get protected files from catalog <br />" . $result->getMessage() );
+ }
+
+ return $totalfiles;
+ }
+
+ public function GetStoredBytes( $delay = LAST_DAY )
+ {
+ $query = "SELECT SUM(JobBytes) as stored_bytes FROM Job ";
+
+ // Interval calculation
+ $end_date = mktime();
+ $start_date = $end_date - $delay;
+
+ $start_date = date( "Y-m-d H:i:s", $start_date );
+ $end_date = date( "Y-m-d H:i:s", $end_date );
+
+ if( $delay != ALL )
+ $query .= "WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
+
+ $result = $this->db_link->query( $query );
+
+ if( PEAR::isError( $result ) ) {
+ die( "Unable to get Job Bytes from catalog" );
+ }else{
+ return $result->fetchRow( DB_FETCHMODE_ASSOC );
+ }
+ }
+
+ public function GetStoredBytesByInterval( $start_date, $end_date )
+ {
+ $query = "SELECT SUM(JobBytes) as stored_bytes, EndTime FROM Job WHERE EndTime BETWEEN '$start_date' AND '$end_date'";
+
+ $result = $this->db_link->query( $query );
+
+ if( PEAR::isError( $result ) ) {
+ die( "Unable to get Job Bytes from catalog" );
+ }else{
+ $stored_bytes = 0;
+ $tmp = $result->fetchRow( DB_FETCHMODE_ASSOC );
+
+ $day = date( "D d", strtotime($end_date) );
+
+ if( isset( $tmp['stored_bytes'] ) ) {
+ $hbytes = $this->human_file_size( $tmp['stored_bytes'], 3, 'GB');
+ $hbytes = explode( " ", $hbytes );
+ $stored_bytes = $hbytes[0];
+ }
+
+ return array( $day, $stored_bytes );
+ }
+ }
+
+ public function GetStoredBytesByJob( $jobname, $start_date, $end_date )
+ {
+ $query = "SELECT SUM(JobBytes) as stored_bytes, EndTime FROM Job ";
+ $query .= "WHERE ( EndTime BETWEEN '$start_date' AND '$end_date' ) AND ";
+ $query .= "Name = '$jobname'";
+
+ $result = $this->db_link->query( $query );
+
+ if( PEAR::isError( $result ) ) {
+ die( "Unable to get Job Bytes from catalog" );
+ }else{
+ $stored_bytes = 0;
+ $tmp = $result->fetchRow( DB_FETCHMODE_ASSOC );
+
+ $day = date( "D d", strtotime($end_date) );
+
+ if( isset( $tmp['stored_bytes'] ) ) {
+ $hbytes = $this->human_file_size( $tmp['stored_bytes'], 3, 'GB');
+ $hbytes = explode( " ", $hbytes );
+ $stored_bytes = $hbytes[0];
+ }
+
+ return array( $day, $stored_bytes );
+ }
+ }
+
+ public function GetStoredFilesByJob( $jobname, $start_date, $end_date )
+ {
+ $query = "SELECT SUM(JobFiles) as stored_files, EndTime FROM Job ";
+ $query .= "WHERE ( EndTime BETWEEN '$start_date' AND '$end_date' ) AND ";
+ $query .= "Name = '$jobname'";
+
+ $result = $this->db_link->query( $query );
+
+ if( PEAR::isError( $result ) ) {
+ die( "Unable to get Job Files from catalog" );
+ }else{
+ $stored_bytes = 0;
+ $tmp = $result->fetchRow( DB_FETCHMODE_ASSOC );
+
+ $day = date( "D d", strtotime($end_date) );
+ $stored_files = $tmp['stored_files'];
+
+ return array( $day, $stored_files );
+ }
+ }
+} // end class Bweb
+?>
--- /dev/null
+<?php
+
+ class BW_Config {
+
+ private $config_params;
+ private $config;
+ private $catalogs = array();
+
+ function __construct()
+ {
+ global $config;
+ $this->config = $config;
+ }
+
+ public function Check_Config_file()
+ {
+ // Check if config file exist and is readable
+ return is_readable( CONFIG_FILE );
+ }
+
+ public function Load_Config()
+ {
+ global $config;
+
+ if( is_array($config) && !empty($config) ) {
+ // Loading database connection information
+ foreach( $config as $parameter => $value )
+ {
+ if( is_array($value) ) // Parsing database section
+ array_push( $this->catalogs, $value );
+ }
+ return true;
+ }else {
+ return false;
+ }
+ }
+
+ public function Get_Config_Param( $param )
+ {
+ if( isset( $config[$param] ) )
+ return $config[$param];
+ }
+
+ public function Get_Catalogs()
+ {
+ $result = array();
+ foreach( $this->catalogs as $db )
+ array_push( $result, $db['label']);
+
+ return $result;
+ }
+
+ public function Count_Catalogs()
+ {
+ return count( $this->catalogs );
+ }
+
+ public function Get_Dsn( $catalog_id )
+ {
+ // Construct a valid dsn
+ $dsn = array();
+ $dsn['hostspec'] = $this->catalogs[$catalog_id]["host"];
+ $dsn['username'] = $this->catalogs[$catalog_id]["login"];
+ $dsn['password'] = $this->catalogs[$catalog_id]["password"];
+ $dsn['database'] = $this->catalogs[$catalog_id]["db_name"];
+ $dsn['phptype'] = $this->catalogs[$catalog_id]["db_type"];
+ return $dsn;
+ }
+
+ function __destruct()
+ {
+
+ }
+
+ } // end classe BW_Config
+
+?>
--- /dev/null
+<?php
+
+?>
--- /dev/null
+<?php
+
+?>
--- /dev/null
+<?php
+
+?>
--- /dev/null
+<?php
+
+?>
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+This is the Change Log for PHPlot.
+The project home page is http://sourceforge.net/projects/phplot/
+-----------------------------------------------------------------------------
+
+2011-01-15 (lbayuk) ===== Released as 5.3.1 =====
+ * phplot.php: Updated version
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+
+2011-01-09
+ * Fixed some style / indent errors, and 1 redundant test.
+
+2011-01-03
+ * For bug 3143586 "Multiple plots per image - fixes & docs":
+ Make sure there is a documented way to reset PHPlot feature
+ settings, especially those for which the default settings result
+ in automatic calculated values. Where possible, calling a Set*()
+ function with no arguments should reset the feature to defaults.
+
+ + Changed SetLegendPixels() arguments to be optional with default
+ NULL meaning reset to automatic positioning.
+
+ + Fixed SetXAxisPosition() and SetYAxisPosition() to accept empty
+ string '' to mean reset to default automatic positioning.
+ Make arguments optional, defaulting to empty string.
+
+ + Changed SetNumXTicks() and SetNumYTicks() arguments to be
+ optional with default empty string '' meaning reset to
+ of automatic calculation.
+
+ * Changed SetPointShapes() to use CheckOptionArray(). This
+ simplifies the function with no change in operation.
+
+ * Extend copyright years to 2011.
+
+2010-12-30
+ * Fix for bug 3147397 "Data colors missing with multiple plots":
+ + Do not truncate the data_colors and related arrays, so the full
+ set of colors will be available for subsequent plots on the image.
+ (Color indexes are still allocated in the image only as needed.)
+ + New internal functions GetColorIndexArray() and
+ GetDarkColorIndexArray(), replacing previous use of array_map().
+ + Removed internal function truncate_array() - no longer used.
+ + Changed SetColorIndexes(), NeedDataDarkColors(), and
+ NeedErrorBarColors() to only allocate the color indexes that will
+ be needed (instead of allocating all colors in the truncated color
+ descriptor arrays).
+
+2010-12-28
+ * Instead of throwing an error, SetLegend(NULL) now clears the legend
+ array. This can be useful with multiple plots on an image. Before
+ this change, only SetLegend(array()) did that (possibly by accident).
+
+2010-12-27
+ * Do not have SetDefaultStyles() call deprecated SetLabelColor().
+
+ * Fixes for bug 3143586 "Multiple plots per image - fixes & docs":
+ + Fix DrawLegend so it doesn't forget that the legend position
+ was specified in world coordinates. This fixes the legend
+ position for plots after the first.
+ + Don't draw the image border more than once (although this would
+ probably have no impact on the resulting image). This parallels
+ the behavior for the main plot title and the image background.
+ Replaced member variables background_done and title_done with a new
+ member array done[] which will track when these elements were done.
+
+2010-12-06
+ * Fix comments above CalcPlotAreaWorld(). Deleted incorrect information
+ from before data-data-yx existed, and before DecodeDataType rewrite.
+
+2010-12-04 (lbayuk) ===== Released as 5.3.0 =====
+ * phplot.php: Updated version
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+
+2010-12-03
+ * Feature request 3127005 "Ability to suppress X/Y axis lines":
+ Added SetDrawXAxis() and SetDrawYAxis() to control flags which
+ will suppress drawing the X or Y axis lines. (These lines were
+ probably the only PHPlot elements that could not be turned off.)
+ Changed DrawXAxis() and DrawYAxis() to conditionally draw the
+ axis lines.
+
+2010-11-28
+ * Feature request 3117873 "Data value labels in more plot types":
+ Implemented Data Value Labels for plot types points, lines,
+ linepoints, and squared. Added 2 class variables which can be
+ set to control the distance and angle of the labels from points.
+ New internal function CheckDataValueLabels() calculates position
+ and text alignment for these labels.
+
+ * Updated comments for Set[XY]DataLabelPos to match the text in
+ the manual, which was rewritten to clarify label types.
+
+2010-11-23
+ * Code cleanup. Moved some functions around to group "plot drawing
+ helpers" separately from "plot drawing". No changes to operation.
+
+2010-11-21
+ * Feature request 3111166 "Control legend colorbox width":
+ Added a class variable legend_colorbox_width which can be changed
+ to make the colorboxes wider or narrower.
+
+2010-11-16
+ * Feature request 3093483 "Investing support chart types":
+ Added 3 new plot types: Basic OHLC (Open/High/Low/Close), Candlesticks,
+ and Filled Candlesticks. Implemented with one new function to handle the
+ 3 new plot types: ohlc, candlesticks, and candlesticks2.
+
+2010-11-11
+ * Moved information about plot types into a new static member array
+ plots[]. (This is an internal change with no impact on usage, but will
+ make it easier to add new plot types.) SetPlotType() no longer needs a
+ list of plot types to check, FindDataLimits() does not need to check for
+ specific plot types to to process the data array, and DrawGraph() uses
+ data from the array rather than knowing about all the plot types.
+
+2010-10-31
+ * Changed internal CalcBarWidths() to take two arguments which indicate
+ how it should calculate bar widths, rather than having it check the
+ plot_type directly. (Taken from another, experimental change. This
+ minimizes places where plot_type is directly used.)
+
+2010-10-03 (lbayuk) ===== Released as 5.2.0 =====
+ * phplot.php: Updated version
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+ * Makefile: Removed HorizontalBars.txt from release. This is now all
+ documented in the reference manual.
+
+2010-10-01
+ * Rewrite color handling. Default and specified colors are now validated,
+ converted to RGBA arrays, and saved. The colors indexes are not
+ allocated until graph drawing time. Unneeded colors are not allocated.
+
+ Fix bug 3045131 "SetTransparentColor problems": Transparency setup is
+ deferred to graph drawing time, after most other colors are allocated.
+ Fixes SetTransparentColor order dependency, and works with data colors.
+
+ Fix bug 3049726 "Optimize color allocation": Colors allocation is
+ deferred to graph drawing time, and colors for most elements are only
+ allocated if needed. In particular, the data colors and dark colors,
+ which used 32 slots, now only get defined as needed.
+
+ Feature request (partial) 3077554 "Finer control over plot element
+ colors": The colors of the main, X, and Y titles can now be controlled
+ separately.
+
+ Change details:
+ New internal functions:
+ GetColorIndex(), GetDarkColorIndex()
+ Allocate pre-parsed colors for elements.
+ SetColorIndexes()
+ Does the deferred color allocation and defaults.
+ NeedDataDarkColors(), NeedErrorBarColors()
+ Called by graph drawing functions if those colors are needed.
+ GetDataColor(), GetDataErrorColors(), GetBarColors()
+ Custom or standard data color assignment for most plot types.
+ truncate_array()
+ Shorten an array. Used to limit data color allocation.
+
+ Removed internal functions:
+ SetIndexColor(), SetIndexDarkColor()
+ Unneeded. Color handling is now in two separate phases.
+
+ Removed internal member variable:
+ data_colors_alpha
+ PHPlot no longer calls SetDataColors before plotting, so this
+ variable is not needed to preserve the default alpha.
+
+ New internal member variables:
+ transparent_color
+ Saves color value from SetTransparentColor. For bug 3045131.
+ x_title_color, y_title_color, ndx_x_title_color, ndx_y_title_color
+ For title colors. DrawXTitle and DrawYTitle use them now.
+
+ Changed internal member variables:
+ i_border, plot_bg_color, bg_color, label_color, text_color, etc.
+ All variables for colors now always hold a parsed 4-component
+ (RGBA) color specification as an array, and are no longer
+ statically initialized to a color name.
+
+ New public functions:
+ SetXTitleColor(), SetYTitleColor()
+ These can be used to make the 3 titles have different colors.
+
+2010-09-26
+ * Don't let SetXDataLabelPos() accept 'xaxis' or 'all' as valid.
+ Don't let SetXTickLabelPos(), SetYTickLabelPos() accept 'all' as valid.
+ These were never implemented and never documented.
+
+
+ * Feature request #3073679 "Stacked bar plots with negative values":
+ Allow stacked bar plots (vertical and horizontal) to work with negative
+ values. Changed FindDataLimits() to not take abs() values for
+ stackedbar when calculating the data range. Changed DrawStackedBars()
+ and DrawHorizStackedBars() to handle negative values, including proper
+ label positions. The first non-zero value in a row sets the direction
+ of the bar. Mixing positive and negative values within a row works but
+ the results are not useful.
+
+ * New internal DrawBar() moves common code from 4 bars and stackedbars
+ drawing functions and makes it easier to deal with shading vs bar
+ direction.
+
+2010-09-24
+ * Fix bug 3074402 "Fix Y axis default for horizontal plots":
+ Make the default axis positions symmetrical for vertical plots
+ (X and Y) and horizontal plots (Y and X). This fixes the problem
+ with horizontal bar/thinbarline plots that have negative data,
+ where the Y axis stayed on the left and the bars went rightward.
+
+2010-09-01
+ * Fix bug 3056991 "Internal methods should be 'protected'":
+ Changed CheckDataArray(), number_format(), FindDataLimits(), and
+ DrawBackground() to be 'protected'. The test suite no longer calls
+ these directly. For SetIndexColor(), SetRGBColor(), DrawText(),
+ SizeText(), xtr(), and ytr(), left these as public with a comment
+ indicating they should be treated as protected.
+
+ * Fix bug 3057000 "Review 'deprecated' methods":
+ + Changed deprecated method SetNewPlotAreaPixels() to just call
+ SetPlotAreaPixels(). It was suspicious as coded, and was found
+ to be equivalent to SetPlotAreaPixels().
+ + Removed SetColor(), which didn't do anything. It was calling
+ SetRGBColor and discarding the result. After reviewing the
+ history of this in all CVS versions, it does not seem to have
+ ever been coded correctly, so there is no harm in removing it.
+ + All other deprecated methods seem OK and are left as is.
+
+2010-08-30 (lbayuk) ===== Released as 5.1.3 =====
+ * phplot.php: Updated version
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+
+2010-08-27
+ * Fix bug 3051832 "Let PHP/GD find the font file":
+ Instead of checking for file existence, PHPlot now uses a non-drawing GD
+ operation to validate a TrueType font in SetFontTTF(). This allows GD to
+ use its internal search path, making it likely that fonts can be found
+ without needing a platform-dependent path in your script. Full paths
+ will still work, so there is no compatibility issue.
+
+ * Fix bug 3051906 "Better choice for default TT font":
+ Removed "benjamingothic.ttf" as the default TT font setting. This has
+ not been included in PHPlot since 2004. Changed SetFontTTF() to call
+ new GetDefaultFontTTF(), which will try a number of sans-serif font
+ names the first time it needs a default TT font. Considering the above
+ fix to finding fonts, this has a good chance of finding a working
+ font. It is known to work on Windows and some Linux distributions.
+
+2010-08-19
+ * Makefile: Removed phplot_data.php from list of files to release.
+ Reference bug report 3048267. This file has not been maintained or
+ tested, and has bugs. It will remain in CVS, but not be included
+ in PHPlot releases.
+
+2010-08-17
+ * Change new DrawLinePoints(). It does not have to check and
+ handle error bar plots, as DrawDots and DrawLines will do that.
+
+2010-08-16
+ * Rewrote DecodeDataType(). Previous implementation was hard to
+ extend and inefficient. Now it uses new class variables (not a
+ returned array) and is only called once, by DrawGraph. Changed all
+ users of data_type to use the new variables.
+
+ In CheckDataArray(), calculate data_columns properly for
+ text-data-single data type (pie chart) too. Simplify DrawPie
+ to use this, and merge 2 of the 3 cases.
+
+ Have a single function handle each plot type, so it can properly
+ check the data type and report a correct error message showing
+ all supported types. For example, DrawBars is now the entry point
+ for both bars and horizontal bars; DrawGraph does not directly
+ call DrawHorizBars. Similar for DrawStackedBars and
+ DrawHorizStackedBars. Lines, Points, and Linepoints also now
+ have a single function each, dispatching to others as needed.
+ (These changes were split off from an upcoming, larger change.)
+
+2010-08-14
+ * Fixes to SetDataValues: need to clear out the 2 arrays before
+ setting values in a loop, else if the function is used more than
+ once then old values will remain.
+ Move records_per_group calculation outside the loop.
+ (These were split off from upcoming, larger changes.)
+
+ * Part 4 of horizontal plots: implement horizontal thinbarline plots.
+ Added new data type 'data-data-yx' (label, Y, X1, X2, ...).
+ DrawThinBarLines() now draws either vertical or horizontal plots, and
+ supports data types text-data, data-data, text-data-yx, data-data-yx.
+
+ Fixed DecodeDataType() to handle text-data-single too, for completeness.
+
+ * Fix for over-padding style and color arrays. These were padded to
+ records_per_group, but that is the maximum data array row size.
+ The number of actual data sets is less, and depends on the data type.
+ Calculate the correct number as data_columns at the top of DrawGraph,
+ and use that to pad the arrays. Also moved early error checking in
+ DrawGraph() into new CheckDataArray().
+
+2010-08-09
+ * Code cleanup. This is a large change to unify the comment and
+ coding stye used in PHPlot. The PEAR style guide is being used
+ as a reference, but PHPlot will never be 100% compliant.
+ This patch introduces no functional changes at all.
+ - Limit line length to 110.
+ - Remove obsolete, partially implemented Doxygen comments.
+ - Add descriptive comment above functions where missing.
+ - Use consistent comment markers and control structure spacing.
+ - Remove ctags-confusing end of function comments.
+ - Rewrote a few if/else blocks for cleaner logic.
+ - Re-order some functions for consistency (X, then Y).
+
+2010-08-04
+ * Implemented horizontal stacked bar plots:
+ Use the same data type introduced for horizontal bars, 'text-data-yx',
+ and the same plot type 'stackedbars', to make a horizontal stacked bar
+ plot. Data value labels, both at the ends of the bars and within the
+ bars ('plotstack' labels) are available with horizontal stacked bars.
+
+ * Internal function DrawDataLabel() is replaced by DrawDataValueLabel(),
+ with different usage. The new function can also check to see if a label
+ fits in the allocated space.
+
+ * Fixed the text size check in stacked bar plots for data value labels
+ within the bars. The check only worked correctly for 0 degree labels. It
+ now works with any text angle. It suppresses the label if it is too high
+ (for vertical stacked bar plots) or too wide (for horizontal stacked bar
+ plots) to fit in the bar segment to which it belongs. Note that it only
+ checks in the bar direction. If the text is too wide (for vertical bars),
+ or too high (for horizontal bars), it will still be plotted, but will
+ cross the sides of the bar.
+
+2010-07-28
+ * Allow callbacks to return a value (to support new data_color callback).
+ * Feature request 3034164 "Extended control of data colors":
+ Define new callback 'data_color' for picking the data color.
+ Changed internal plot drawing functions DrawDots, DrawLines, DrawSquared,
+ DrawBars, DrawStackedBars, DrawDotsError, DrawThinBarLines,
+ DrawLinesError, and DrawHorizBars to use the data_color callback
+ (if defined) to select the data colors.
+ * SetRGBArray code cleanup (no functional changes).
+
+2010-07-27
+ * Fixes for error bars:
+ Code cleanup in DrawYErrorBar(), with no functional change.
+ Suppress duplicate drawing of error bars with 'linepoints' error plots.
+ This was already fixed for data labels. Now error bars will only be
+ drawn by the 'points' part, not the 'lines' part. There should be no
+ visible changes to plots. (This is needed for a future change).
+
+2010-07-26
+ * Horizontal bar charts (still an experimental feature) can now have data
+ value labels.
+ * HorizontalBars.txt: Fix incorrect description of bar direction. Add
+ text explaining the new data value labels.
+
+2010-06-29 (lbayuk) ===== Released as 5.1.2 =====
+ * phplot.php: Updated version
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+
+2010-06-26
+ * Feature request 2885930 "Horizontal Bars":
+ Horizontal bar charts are implemented, as an experimental feature.
+ A new data type 'text-data-yx' was added, which works with
+ 'bars' plot type to produce a horizontal bar chart from a data
+ array with X values for each Y value. Changes were made to
+ FindDataLimits, CalcMargins, CalcPlotAreaWorld, CalcBarWidths,
+ and CalcMaxDataLabelSize to handle the new data type. Other
+ changes were made to handle label position defaults and grid
+ defaults. New drawing functions were added for horizontal bars.
+
+ * HorizontalBars.txt: new documentation file for experimental feature.
+ * Makefile: List new documentation file.
+
+2010-06-25
+ * Each plot-type drawing function now checks that it is getting a data
+ type that it knows how to handle. A new internal function unifies the
+ checking and error message. (This is associated with an upcoming,
+ bigger change.)
+
+ Compatibility: If you were using an invalid data type for a plot type
+ whose function did not check, will now get an error.
+
+ * Removed some dubious code from DrawLines() and DrawSquared() and
+ rewrote comments there. The code initialized lastx[0] and lasty[0],
+ but lasty was mapped using the X (rather than Y) function. This was
+ obviously wrong, but closer inspection showed that the values were
+ never, used so the code was removed.
+
+2010-06-13
+ * Truecolor.txt: removed
+ * Makefile, README.txt: Removed reference to Truecolor.txt. Full
+ documentation for truecolor images is now in the Reference Manual.
+
+2010-06-02
+ * Fix bug 3010116 "Bad rendering of title in multi-plot image
+ when using TTF":
+ Make sure the main title is drawn only once. (If drawn multiple
+ times with TrueType font text, the anti-aliasing effects result
+ in poor quality text.)
+
+2010-05-31
+ * Improvements to truecolor support (from feature request 2947679):
+ Truecolor support is now better integrated. The derived class only
+ has the constructor now, and the base class itself provides the alpha
+ color component support through the internal functions SetIndexColor(),
+ SetIndexDarkColor(), and SetRGBColor(). This means alpha channel
+ works with palette images too (in so far as GD supports this).
+
+ * Truecolor.txt: Updated per changes to truecolor support.
+
+ * Image tiling with mode 'scale' in tile_img(), used with image and
+ plot area backgrounds, now uses imagecopyresampled() rather than
+ imagecopyresized(). They are the same with palette images, but the
+ resampled copy gets better results with truecolor images.
+
+2010-05-29
+ * Feature request 3002606 "Add to plot and image border options":
+ Added options 'right', 'top', and 'bottom' to SetPlotBorderType()
+ (existing options are 'left', 'sides', 'none', and 'full'). This
+ now also accepts an array of the above options, giving complete
+ control over which sides to draw.
+ Added option 'solid' to SetImageBorderType() to use the actual
+ color set with SetImageBorderColor(), rather than the darker
+ shade as type 'plain' does (for some reason).
+ New function SetImageBorderWidth() sets the width of the image
+ border. The image border width is now accounted for in margin
+ calculations, although existing plots will not change.
+
+2010-04-04 (lbayuk) ===== Released as 5.1.1 =====
+ * phplot.php: Updated version
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+
+2010-04-01
+ * Remove & from argument in SetDataValues(). The data array is not
+ modified and does not need to be passed by reference. (There is
+ no performance advantage, either.)
+
+2010-03-29
+ * Feature request 2947679 "Support for alpha blending/Truecolor":
+ Implemented truecolor image support with a new class
+ PHPlot_truecolor, extended color specifications to allow
+ specification of an alpha value, and added a new optional parameter
+ to SetDataColors for a default alpha value for all data colors.
+ This feature is *EXPERIMENTAL* (see next item).
+
+ * Truecolor.txt: New file, documentation for the new truecolor capability.
+ (The Truecolor feature is experimental, which means it is subject to
+ change in incompatible ways and the documentation has not yet been
+ incorporated into the PHPlot Reference Manual.)
+
+ * Makefile: Include new documentation file in release.
+
+2010-03-26
+ Fixed bug 2976735 "Improvements and fixes for 'area' plots":
+ Rewrote DrawArea() function which handles 'area' plot.
+ Part 1: This is related to feature request 2947679, Truecolor support
+ with transparency. The area plot function was filling each area from the X
+ axis up to the Y value, resulting in area overlaps. This wasn't a problem
+ with opaque colors, but with transparency, the overlapping areas resulted
+ in changed colors. The rewritten function fills the area between each line
+ instead of from each line down to the X axis. Plots with opaque colors
+ will not change.
+ Part 2: Area plots now work when the X axis is moved up with
+ SetXAxisPosition().
+ Part 3: Fixed FindDataLimits() for area (and stackedbars too) to
+ take absolute values of Y values. The drawing function was doing this,
+ but not FindDataLimits, resulting in incorrect limits if any Y<0.
+ Part 4: The rewritten DrawArea() also handles a new plot type
+ 'stackedarea'. This is an area plot where the Y values are stacked,
+ similar to 'stackedbars'.
+ Note: As part of the changes, it is now an error to try an area plot
+ with an unequal number of Y points for each X.
+
+2010-03-23
+ * Feature request 2973995 "Add y-Data to Stackedbars":
+ Implemented Y Data Labels for Stacked Bar charts (stackedbars).
+ The labels are enabled with SetYDataLabelPos, same as with bar charts.
+ There are two types of labels: above the stack with the total, and
+ within the bars at each segment. 'plotin' turns on the upper ones, and
+ 'plotstack' turns both on.
+
+ * Other changes:
+ + Removed unimplemented second argument to SetYDataLabelPos.
+ + Fixed questionable logic in SetYDataLabelPos when given an argument
+ that belongs with SetYTickLabelPos.
+ + Fix comments at top of plot-type Draw functions.
+
+ * Fix for bug 2974639 "Stacked bars plot breaks with X axis != 0":
+ Stacked bar plots with non-zero X axis position no longer break apart
+ into segments with gaps. The bars are drawn up from the X axis, and
+ any segments or partial segments below the X axis are not drawn.
+
+2010-03-22
+ * Change related to feature request 2947679 - Fix 'dot' point shape:
+ Use imagefilledellipse(), not imagefilledarc(), when drawing the 'dot'
+ point shape. The fix was needed for future support of truecolor images
+ with transparency, but filled dots from imagefilledellipse() look
+ better (rounder) with regular images and opaque colors.
+ Credit to mvaldez for identifying the problem and providing the fix.
+
+2010-03-04
+ * Fix for bug 2963757 "point_counts undefined error in 5.1.0":
+ Fixed CheckPointParams so it sets point_counts even when the point shape
+ and point size arrays are already the same size and do not need padding.
+
+2010-01-26
+ * Fix for bug 2938219 "Bars go in wrong direction":
+ Fixed CalcAxisPositions() to be consistent in positioning the X axis.
+ When all Y values are <0 and the Y=0 line is not part of the plot range,
+ PHPlot will now default the X axis to the top of the plot, not the
+ bottom. This fixes the problem with bars to negative Y values being
+ drawn downward if Y=0 is visible, but upward if Y=0 is not visible.
+ This also affects thinbarline plots.
+ Credit to lauryn1298 for finding the bug.
+
+2009-12-24 (lbayuk) ===== Released as 5.1.0 =====
+
+2009-12-18
+ * Change for bug 1795971 "Fix default data colors":
+ The default Data Color and Error Bar Color arrays now have 16
+ different colors, no duplicates, and nothing so light that it
+ is invisible.
+ Using '' or False as the argument to SetDataColors, SetErrorBarColors,
+ and SetDataBorderColors now re-initializes the map to the defaults.
+ This was previously undocumented, and in some cases set the map to
+ something different from the default.
+
+2009-12-15
+ * Cleanup: Remove DrawAxisLegend() - empty function marked TODO,
+ not really clear what it was meant to do.
+
+2009-12-14
+ * Fix for bug 2914403 "Pie + X/Y titles: Undefined property error":
+ In DrawGraph(), don't try to draw X or Y titles for pie charts.
+
+ * Feature request 2899921: "allow different format for data and tick
+ labels"; Bug 2906436: "Fixes for X Tick Labels vs X Data Labels",
+ and partial implementation of changes from user 'adoll' regarding
+ tick vs data labels:
+
+ New public functions:
+ + SetXDataLabelType() : Sets formatting for X Data Labels
+ + SetYDataLabelType() : Sets formatting for Y Data Labels (bar charts)
+ + SetXDataLabelAngle() : Sets text angle for X Data Labels
+ + SetYDataLabelAngle() : Sets text angle for Y Data Label (bar charts)
+ The defaults for these are set up to be fully backward compatible
+ with previous releases of PHPlot (except see the next item).
+
+ Re-used function name SetXDataLabelAngle():
+ + This has been deprecated and undocumented since 2003-12-07, and
+ used to just call SetXLabelAngle(). For new behavior, see above.
+
+ Changes to public functions:
+ + SetXDataLabelPos() and SetXTickLabelPos() no longer cancel each
+ other out (set the other control variable to 'none'). Instead,
+ they are both considered before plot drawing.
+
+ Changes to internal functions:
+ + DrawDataLabel() now uses the font, angle, and color arguments as
+ provided, and does not substitute values if they are empty.
+ + SetLabelType() now takes mode='xd' and 'yd' for X Data and Y Data
+ label formatting; 'x' and 'y' are for tick labels only now.
+ + Functions that work on Data labels now call FormatLabel() with the
+ new mode parameter value 'xd' or 'yd, and use the new
+ data_label_angle variables.
+ + New CheckLabels(), used by DrawGraph to process label parameters.
+ + CalcMargins() - Rewritten to handle changes to Tick and Data labels.
+
+ Changes to internal class variables:
+ + New: x_data_label_angle, y_data_label_angle
+ + Do not initialize x_tick_label_pos or x_data_label_pos, so that
+ CheckLabels() can tell if they were set or not and apply defaults.
+ + Initialize y_data_label_pos to 'none', not 'plotleft'.
+ + Add 2 more indexes to label_format[] array: 'xd' and 'yd'.
+
+ * Cleanup:
+ + Delete unused internal class variable: draw_y_data_label_lines
+ + Delete unused function SetDrawYDataLabelLines()
+
+2009-12-07
+ * Fix bug 1795972 "Fix default point shapes":
+ + Added 10 new point shapes to the existing 10 shapes.
+ + Changed the default point shape from all 'diamond' to a
+ selection of up to 10 different shapes.
+ + Fixed bug in the code that tried to set the point shapes
+ and sizes arrays to be the same size. This was not working,
+ resulting in unexpected point sizes.
+ + Changed default point size to 6 for all shapes. It was trying
+ to be "5, 5, 3" but due to several bugs this was not working.
+ + Do not adjust shape sizes to even numbers (was done for only two
+ shapes). Instead, consistently truncate size/2 when needed.
+ NOTE: These may change the look of 'points' and 'linepoints' plots.
+
+ * Changed startup initialization code:
+ + SetDefaultStyles() was doing some odd things using a variable
+ called "session_set", with comments referring to non-existent
+ session support code. This has been removed. There should be
+ no visible changes from this. PHPlot does not use PHP sessions.
+
+2009-12-04
+ * Fix for bug 2908256, errors in pie charts with bad data array:
+ (From a Drupal contrib module report by thekevinday.)
+ With pie charts only, a data array with no valid Y values resulted
+ in PHP error messages. All other plot types handle this by producing
+ an image without a graph.
+ Fixed DrawPieChart to behave this way too. If there are no valid Y
+ values, or if the sum of all Y values is 0, do not error out, but
+ don't draw a pie chart either.
+ Also, pie charts now ignore non-numeric Y values, like other plot types.
+
+2009-11-20 (lbayuk)
+ * Fix for bug 2900914 "Problem with display of 0 on Y axis":
+ Changed how X and Y values are stepped by tick intervals, to avoid
+ cumulative round-off error. This fixes the problem when Y crosses 0 with
+ a tick step such as 0.1 resulting in a long label for a very small but
+ non-zero number. Fixed DrawXTicks, DrawYTicks, and CalcMaxTickLabelSize.
+ (Originally reported by cncnet)
+
+2009-11-19 (lbayuk)
+ * Improve support for using callbacks to annotate plots:
+ Added new callback 'draw_all', called after all drawing.
+ Supply plot_area[] as argument to some drawing callbacks.
+ Added new method GetDeviceXY() to translate from world coordinates.
+ Allow NULL or '' for $font in DrawText() internal method, meaning to
+ use the generic font. If callbacks want to use DrawText, this
+ avoids them having to reference the internal fonts[] array.
+
+2009-11-01 (lbayuk)
+ * Address bug report 2886365 "Declare all functions and variables in
+ PHP5 style"
+ PHP5 deprecates the use of 'var' to declare a class member variable.
+ All initialized class member variables are now declared 'public'.
+ (It was tempting to make most or all 'protected' or 'private', but
+ that would likely break too much, including the PHPlot Test Suite.)
+
+ Most class member functions which are meant for internal use only are
+ now declared 'protected', so they cannot be called from scripts
+ (except in child classes). (Note PHP5 does not deprecate the use of
+ just 'function' to mean public, so public functions were not changed.)
+ Internal functions are those documented in the manual under Developer's
+ Guide, Internal Functions. If your code breaks because you are using
+ a method which is now protected, please post the details on the help
+ forum.
+
+ Some member variables which were set in the constructor are now
+ initialized with the class instead. (No impact.)
+
+ Removed commented-out, FIXME-noted code for interim labels.
+
+2009-10-12 (lbayuk)
+ * Bug report 2839547, allow SetImageBorderType('none') to reset the image
+ border type. Also checked for other cases where there is no reset;
+ found one that exists (Set[XY]LabelType) but needs to be documented.
+
+2009-07-09 (lbayuk)
+ * Added a hook $plot->locale_override which can be set to True to prevent
+ PHPlot from loading locale settings from the environment with
+ setlocale(LC_ALL, ''). This is necessary for testing PHPlot on Windows,
+ where you cannot force a locale with an environment variable. It might
+ also be needed for people who want PHPlot's locale to differ from the
+ web server's locale.
+
+2009-06-12 (lbayuk) ===== Released as 5.0.7 =====
+
+2009-06-11 (lbayuk)
+ * Change PHPlot license to LGPL, per Afan.
+ phplot.php, phplot_data.php - Change license notice.
+ rgb.inc.php - Change top comments and remove bottom marker.
+ COPYING - new file, text of LGPL.
+ LICENSE.* - removed files - old licenses.
+ Makefile - change list of distributed files.
+
+ * Fix for bug 2803900: SetRGBArray('large') does not work. The include
+ file defined a different array name than the main script expected.
+ (This bug seems to have happened over 8 years ago.) Fixed the array
+ names to match. Also removed the ./ prefix from the included filename
+ so it will be found if on the include path but not in the script
+ directory. Also added error check if the rgb.inc.php include file
+ is needed and not found.
+
+2009-05-25 (lbayuk)
+ * Added new feature to allow partial margin or plot area specification.
+ You can omit, or specify as NULL, any of the 4 arguments to
+ SetMarginsPixels() or SetPlotAreaPixels(), and this means PHPlot
+ should use the automatically calculated margin on that side.
+ Credit to adoll for this feature.
+
+2009-05-17 (lbayuk)
+ * Fix for bug 2791502 "Error plots treat missing Y values as 0":
+ Plots with data type data-data-error now support missing Y values,
+ instead of treating them as 0. This works with lines, points,
+ and linepoints plot types, and also honors SetDrawBrokenLines.
+
+
+ * Fix for bug 2792860 "Wrong DataLabelLines with missing Y":
+ Do not draw X Data Label Lines at points with missing Y values.
+
+
+ * Fix for bug 2786350 "Missing Y data results in bad auto-range":
+ Rewrote FindDataLimits to ignore missing Y values, rather than
+ treating them as if 0, for calculating range.
+ Bug report and analysis by mrten.
+
+ * Fix for bug 2786354 "Incorrect auto-range for data-data-error":
+ For data-data-error data type, apply the positive and negative error
+ amounts for each Y point to that point only, rather than applying the
+ largest errors to the overall minimum and maximum Y value for the row.
+
+ Note: The two fixes above can change existing plots which rely on
+ automatic Y range calculation. The first fix affects plots with
+ missing Y values and min(Y)>0. The second fix can affect plots using
+ data-data-error data type and different error values for different
+ points. In both cases the new Y range can be smaller than before.
+
+2009-01-20 (lbayuk) ===== Released as 5.0.6 =====
+
+2009-01-18 (lbayuk)
+ * Fix for bug 1891636 "Misaligned TTF X Labels":
+ PHPlot was using the actual bounding box of each line of text
+ to allocate space and set the text positioning, but was ignoring the
+ fact that the text baseline is not the same as the bottom of the
+ bounding box. This resulted in uneven alignment of the X labels if
+ they had different heights (for example, month names Jul and Aug).
+
+ PHPlot now calculates the size of text for allocation (SizeText) using
+ the descenders on the last line, and calculates the size for drawing
+ (DrawText) only to the baseline. PHPlot also now uses a fixed line
+ spacing for each line of text in a font, rather than the actual text
+ height. This allows separately drawn multi-line labels to align.
+
+ * Changes to line spacing when using multi-line labels:
+ PHPlot was using the class variable line_spacing to mean the
+ number of pixels between lines of multi-line labels. This made the
+ spacing too small for larger fonts, and it was not possible to adjust
+ line spacing for different types of text.
+
+ PHPlot now interprets line_spacing as the number of pixels only
+ for GD text, and as a scale factor for the font's built-in line
+ spacing for TrueType text. In addition, a new optional argument is
+ added to SetFont, SetFontGD, and SetFontTTF to set a line spacing
+ specific to that type of text.
+
+ * Changes had to be made to the legend drawing code to accommodate the
+ changes to font handling.
+
+ Note: The line spacing change results in slightly looser spacing on
+ multi-line TrueType text labels, and slightly taller legends, compared
+ to version 5.0.5.
+
+2008-09-21 (lbayuk)
+ * Interim fix for bug 1932571 "Data-Data Plot fails with same X values".
+ PHPlot will no longer hang when the range of X values is 0 (that is, when
+ x_min == x_max). It will arbitrarily set an X range of 1, so the
+ calculated tick step is not 0. This is a temporary fix. Work on a smarter
+ X and Y range calculation is in progress, which will handle edge cases
+ like this better, but it isn't ready and this bug has been open too long.
+ Credit to andyl for finding the bug.
+
+ * Fix font path: Use DIRECTORY_SEPARATOR constant not '/'.
+
+ Extended the label formatting capabilities, adding 'printf' and 'custom'
+ types, added a prefix and suffix for 'data' type, and allow format controls
+ to be included in SetXLabelType and SetYLabelType.
+
+ External changes:
+ * Added 'printf' label type. The caller specifies the print format as the
+ 2nd argument to SetXLabelType or SetYLabelType (default '%e').
+ $plot->SetXLabelType('printf', '%5.2f');
+
+ * Added 'custom' label type. The caller supplies a callback (typically a
+ function name) and optional pass-through argument as the 2nd and 3rd
+ arguments to Set[XY]LabelType. The function is called as $f($value, $arg)
+ to return the formatted $value.
+ $plot->SetXLabelType('custom', 'myfunction', $arg_value);
+
+ * In addition to Set[XY]TimeFormat, the format string for type 'time' can
+ now be set as the 2nd argument to Set[XY]LabelType.
+ $plot->SetXLabelType('time', '%H:%M');
+
+ * In addition to SetPrecision[XY], the precision for type 'data' can now be
+ set as the 2nd argument to Set[XY]LabelType. A 3rd and 4th argument
+ can supply a prefix and suffix for 'data' formatting. (All optional)
+ $plot->SetXLabelType('data', 2, '$', 'US');
+
+ Internal changes:
+ * Class variables x_precision, y_precision, x_label_type, y_label_type,
+ x_time_format, and y_time_format have been removed.
+
+ * New class array variable label_format[], with elements 'x' and 'y' which
+ are arrays for label formatting. Elements in the sub-arrays are not
+ initialized until needed.
+
+ * New function SetLabelType, which implements Set[XY]LabelType now.
+
+ * FormatLabel() was rewritten to support the new label formatting.
+
+ Compatibility:
+ * Any code that directly references class variables related to label
+ formatting will break, except for data_units_text. Use the documented
+ function methods instead. Setting data_units_text as a suffix is
+ deprecated but still works.
+
+ * The 'data' type precision for 'Y' is still used for pie chart labels.
+
+2008-07-12 (lbayuk)
+ Multiple comment spelling error fixes. No functional changes.
+
+2008-07-06 (lbayuk)
+ Changes to allow mixing GD fixed-font text and TrueType Font (TTF) text
+ on the same plot.
+ (This change came from work done trying to fix TTF text positioning,
+ where it looks like additional information needs to be stored for TrueType
+ fonts. The old font data structure was awkward to extend, and allowing
+ mixed GD/TTF text was on the to-do list anyway.)
+
+ External changes:
+ * SetFontGD(), SetFontTTF(): New functions to set a font, with type.
+ * SetFont(): Now calls SetFontGD or SetFontTTF depending on $use_ttf.
+ These changes should be fully compatible with existing programs.
+
+ Internal changes:
+ * Updated comments explaining SetUseTTF() now sets the default type
+ (not the only type) of text used.
+ * Put all the font data into a class array. (Replaces $this->generic_font
+ with $this->fonts['generic'], etc.)
+ * ProcessTextGD() and ProcessTextTTF() now take the font array as one
+ argument, rather than separate arguments for font path and size.
+
+2008-01-13 (lbayuk) ===== Released as 5.0.5 =====
+ * phplot.php: Updated version
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+ * Makefile: Remove 'Callbacks' from release target, as this material is
+ now in the reference manual.
+
+2008-01-07 (lbayuk)
+ Copyright updated to 2008 and PHP4 no longer listed as supported.
+
+ Major rewrite of the margin calculation functions to address multiple
+ problems. Fixes for bugs 1856207 "Margin error with 'xaxis'/'yaxis'
+ position, 1843012 "Make margins, drawing consistent", and 945439
+ "x_tick_label_height not set correctly".
+
+ Note: These changes are inter-dependent and cannot be split up.
+
+ * Defer all calculations to DrawGraph time, to eliminate order dependencies.
+ These functions now just store their arguments in the object, and all
+ calculations happen later:
+ + SetXAxisPosition, SetYAxisPosition
+ + SetMarginsPixels
+ + SetPlotAreaPixels (Stores margins, not area, now.)
+ + SetPlotAreaWorld
+ + SetXTickIncrement, SetYTickIncrement
+
+ * A new callback 'debug_scale' was added to trace the margin and scale
+ calculations.
+
+ * CalcMargins was rewritten. Actual sizes of tick and data labels are now
+ used, rather than guesses like "use size of biggest Y value". A minimum
+ value (3 x safe_margin, or 15 pixels) applies to each margin.
+
+ * FindDataLimits no longer needs to find the longest data label, since
+ CalcMargins now does that more precisely.
+
+ * DrawXTitle and DrawYTitle now use position offsets calculated by
+ CalcMargins. Note: These titles are now offset from the plot area,
+ not the image area. The titles will move if you had set the plot area
+ or margins.
+
+ * DrawYTick, DrawXTick rewritten to use pre-calculated offsets, and common
+ code moved to new CalcTicks().
+
+ * DrawXDataLabel: Use pre-calculated offsets for text.
+
+ * DrawGraph: Rewrote top section (before drawing anything) to do the
+ calculations in the proper order, unconditionally.
+
+ * Class variables removed:
+ x_label_inc, y_label_inc, _x_label_cnt : These were never used.
+ title_height, x_title_height, y_title_width : Now internal to CalcMargins.
+ data_limits_done : No more need to remember if FindDataLimits called.
+
+ * New class variables added:
+ plot_margins_set : Keeps track of user-set plot area or automatic.
+ x_label_top_offset, x_label_bot_offset, x_offset_axis_offset,
+ y_label_left_offset, y_label_right_offset, y_label_axis_offset,
+ x_title_top_offset, x_title_bot_offset,
+ y_title_left_offset, y_title_left_offset : Label offsets
+
+ * New internal functions:
+ CalcPlotAreaPixels : Deferred calculations taken out of SetPlotAreaPixels
+ and SetMarginsPixels.
+ CalcPlotAreaWorld : Deferred calculations taken out of SetPlotAreaWorld.
+ CalcAxisPositions : Calculate axis positions, moved from CalcTranslation.
+ CalcTicks : Calculate X and Y tick interval. This still uses the
+ same simple method (basically range/10), but now we could drop in a new
+ algorithm much more easily. This is now also used by CalcMargins.
+ Code taken out of DrawXTicks and DrawYTicks.
+ CalcMaxTickLabelSize : So CalcMargins can use the exact tick label sizes.
+ CalcMaxDataLabelSize : So CalcMargins can use the exact data label sizes.
+ DrawXTick : Code split out from DrawXTicks for symmetry with DrawYTick.
+
+
+2007-12-13 (lbayuk)
+ * Changed ProcessTextTTF() so SizeText() will return integers. It rounds
+ the calculated values up, so the bounding box really contains the text.
+ This also prevents unneeded float calculations in derived values.
+
+2007-12-09 (lbayuk)
+ Major rewrite of the text drawing functions to address multiple problems.
+ Note: These changes are inter-dependent and cannot be split up.
+
+ * Fixed bug 1813070 "Bad position for multi-line TrueType text":
+ TTF text is now drawn line-by-line, not as a block, for proper
+ alignment and positioning.
+
+ * Fixed bug 1813071 "Wrong title height for multi-line TTF text":
+ Corrected miscalculation of overall height of multi-line TTF titles.
+ This bug resulted in over-sized margins.
+ The height is now computed line-by-line, including the inter-line spacing.
+
+ * Fixed bug 1813474 "DrawText alignment arguments wrong":
+ Corrected meaning of 'top' vs 'bottom' alignment. PHPlot now follows
+ the usual conventions: 'top' alignment means top of text to reference.
+ DrawText default for vertical alignment is still 'bottom', but the
+ meaning was corrected. All callers of DrawText were fixed.
+
+ * Fixed bug 1816844 "Fix order dependency for setting titles":
+ Defer processing titles strings until DrawGraph(), so there is no
+ more order dependency (no need to set font before setting title strings).
+
+ * Fixed bug 1819668 "Horiz. align multi-line text: GD vs TTF":
+ The new text routines draw TTF text line-by-line and correctly do
+ right-, center-, and left- alignment of each line within a text block.
+
+ * Fixed bug 1826513 "FIXME in DrawLegend: Max label length":
+ Use actual width of widest legend line to calculate legend box size.
+
+ * Partial fix for bug 945439 "x_tick_label_height not set correctly":
+ In FindDataLimits(), save the longest data label, not just its length,
+ and use the actual rendered size of that string in CalcMargins() for
+ the margin calculations.
+ Also take into account which of the tick or data labels are visible.
+ This is not a complete fix, but is a significant improvement.
+
+ The following changes were made related to the above fixes:
+
+ + Replaced internal function TTFBBoxSize(), which didn't work right, with
+ SizeText(). It returns the orthogonal bounding box of a block of text,
+ and works with both GD and TTF text.
+
+ + DrawText() and SizeText() call a single function ProcessText(), which is
+ the only place GD text and TTF text are distinguished. (So eventually
+ we will be able to mix GD and TTF text on a plot.)
+
+ + New internal functions ProcessTextGD() and ProcessTextTTF() draw (or size)
+ GD and TTF text respectively. These are only called by ProcessText().
+ These are re-implementations which properly position and align text.
+
+ + Removed class variables title_angle, x_title_angle, and y_title_angle. The
+ titles only work at their fixed angles anyway (0, 0, and 90 respectively).
+
+ + Line spacing set with SetLineSpacing() now affects TTF text as well as
+ GD text. Previously, it only affected GD text. The default line spacing
+ happens to be usable for TTF text.
+
+ + Added new callback hook 'debug_textbox' for developing, testing, and
+ documenting. It provides access to the text area bounding box.
+
+ + Removed unneeded class variables x_tick_label_height, y_tick_label_width,
+ x_tot_margin, y_tot_margin.
+
+2007-11-25
+ * Improve error handling:
+ Internal functions PrintError() and DrawError() are now the same. Both
+ will draw the error message into the image and output it, and then
+ trigger a user-level error. If no error handler has been set, it will
+ exit, as before. But now the error message should also get logged, or
+ written to the standard error stream, depending on the SAPI in use.
+ You can now establish an error handler to catch most PHPlot errors and
+ do some cleanup before exit.
+
+ This fix also covers bug #1823774 "Default Font Path and Error Message
+ Output".
+
+ Fixed the return value of most PHPlot functions, to return False on
+ error, else True. Since uncaught errors are fatal anyway, this only
+ affects code with an error handler that returns, which is not
+ recommended and unsupported at this time. These changes are for
+ possible future error handling options.
+
+2007-11-22
+ * Fix bug 1836528 "Insufficient checking of parameter values":
+ Rewrote CheckOption to correctly validate option choices.
+ (It previously accepted substrings and other incorrect values.)
+ PHPlot methods that use CheckOption now must be called with valid option
+ values. Empty strings are also no longer accepted.
+
+2007-11-17 (lbayuk)
+ * Change to callbacks to support extra arguments.
+ The PHPlot class can now pass extra arguments to a callback function.
+ Callback functions now take the following form:
+ my_callback($img, $passthru_arg, ...)
+ Where '...' is zero or more additional arguments supplied by PHPlot to
+ the callback. Each implemented callback reason will define any
+ additional arguments it uses. The existing defined callbacks have not
+ changed and do not currently pass any extra arguments.
+
+2007-11-10 (lbayuk)
+ * Fix bug 1827263 "Spoiled up pie-chart if $val is close to zero":
+ Skip pie slices which would result in an integer angle of zero
+ degrees, because the GD arc filling function will draw a complete
+ circle for that case.
+ Credit to Viacheslav <webdeveloper.ua at gmail.com> for finding this.
+
+ * Removed 8 of the functions (class methods) marked 'deprecated'. Only
+ deprecated functions which seem to have been for internal use have
+ been removed. Even old scripts shouldn't be using them, and they are
+ becoming a problem to maintain.
+ Removed: SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights()
+ CalcYWidths() DrawLabels() InitImage() DrawDashedLine().
+
+2007-10-20 (lbayuk) ===== Released as 5.0.4 =====
+ * phplot.php: Updated copyright, version, and authors comments at top.
+ * README.txt: Updated for new release
+ * NEWS.txt: Add text for new release
+
+2007-10-18 (lbayuk)
+ * Add callbacks - experimental feature:
+ New functions SetCallback, GetCallback, RemoveCallback.
+ New internal function DoCallback.
+ Added callback hooks to DrawGraph.
+
+ Re-arranged code in DrawGraph to bring pie chart drawing into the main
+ switch on plot type, rather than a special case in its own block. This
+ makes it easier to follow and easier to add callback hooks.
+
+ * Callbacks: New file, documentation for the new callbacks feature.
+ (This won't be in the manual while it is an experimental feature.)
+
+2007-10-15 (lbayuk)
+ * Fix for bug 1813021: Miss-positioned right-justified vertical GD text.
+ Fixed DrawText() to correctly position 90 degree right-justified text
+ drawn in a fixed GD font. This could be seen with 90 degree Y tick
+ labels. (Found by accident while working on TrueType text problems.)
+ Also some code cleanup in DrawText: use elseif where appropriate.
+
+2007-10-09 (lbayuk)
+ * Code cleanup: Simplify SetIndexColor() and SetIndexDarkColor().
+ There is no need to first try ImageColorExact, then ImageColorResolve
+ if that fails. ImageColorResolve does all that for us.
+
+ Code cleanup: Rewrite SetRGBColor(). It now detects if an unrecognized
+ color name or color value form is used, and draws an error message.
+ Before this it would get a PHP index error and "headers already sent"
+ condition.
+
+ * Code cleanup: Remove duplicated code for loading image files.
+ Added new class-private function GetImage() which loads an image based
+ on the image type, and also returns the image size. This replaces
+ duplicated code in tile_img() and SetInputFile().
+ Also fixed comment at top of SetImageFile which said it was deprecated.
+ It isn't - it is used by the constructor. Moved the function out of the
+ 'deprecated' area up to below where it is used.
+
+ * Code cleanup: PHPlot should not define or affect anything outside its
+ own class.
+ - Removed the check for __FUNCTION__ (PHP 4.3 and up). This is obsolete.
+ - Do not set error_reporting to E_ALL. Although it is recommended that
+ scripts do this, it is not the place of loaded classes to do it.
+ - Remove unused global constant TOTY.
+ - Removed constants MAXY and MINY. Global constants like this are bad.
+ These were used as magic index values into data[] to hold min and max Y
+ values for the row. Instead, put them in separate arrays which are
+ named data_miny[] and data_maxy[]. (This seems to be only used by the
+ data line drawing function.)
+
+ Comment cleanup: Remove one commented-out partial function DrawPlotLabel,
+ and fix another commented-out code fragment in DrawYErrorBar. Both of
+ these had unmatched braces in them which caused a balance-braces check
+ to fail.
+
+ * Code cleanup, array padding: Get rid of functions outside the class
+ and remove the interim fix for PHP 5 (which changed the behavior of
+ array_merge). Rewrote external function array_pad_array() as a new
+ class function pad_array(). It does not need access to the class,
+ but I don't think PHPlot should add to the global namespace more
+ than necessary. The third argument (array to use for padding) was
+ never used, so it was removed. It always pads the array with itself.
+ It now only works on 'usual integer indexed' arrays (0-based
+ sequential integer index). The was previously required but
+ undocumented for some of the arrays (like line_widths); now it is
+ required for all style arrays and will be documented. Now we can pad
+ the array to the required length, not just N times its previous
+ length, and we don't need array_merge. Deleted external function
+ array_merge_php4() as it is no longer used.
+
+ Deleted PHP end marker ?>. You don't need this and it can cause
+ problems with extra whitespace in your output.
+
+2007-09-24 (lbayuk)
+ * Code cleanup: Fix ternary operator misuse. This doesn't change
+ behavior, but it was annoying me so I fixed it.
+ Replaced all cases of code like this: $a = ($a > $b) ? $b : $a
+ With just: if ($a > $b) $a = $b
+
+ * Fix Makefile 'release' target to set owner/group when creating
+ the tar file. This avoids having to run it as root, but it needs
+ GNU tar to work.
+
+2007-09-08 (lbayuk)
+ * Fix for bug 1790441: Removed the PHPlot quasi-destructor function and
+ the register_shutdown_function() call which arranged for it to be used.
+ This was preventing release of memory when a PHPlot object was unset,
+ because the registered shutdown function held a reference to it.
+ So rather than improving memory use, it had the opposite effect.
+ Note: It is no longer necessary or recommended to use reference
+ assignment ($plot =& new PHPlot) for PHPlot object creation.
+ Thanks to annajilly for the thorough analysis, bug report, and fix.
+
+2007-09-05 (lbayuk)
+ * Rewrote FormatLabel() to ignore blank label values. Adapted from a
+ patch and feature request submitted by Gerhard Reithofer (exgerhardr).
+ Blank labels used to produce an error if the LabelType was set to
+ 'time', and zero if set to 'data'. Now they are just ignored. This
+ provides a simple way to have labels only at selected intervals when
+ using time or data formats. For example, you can have a date/time
+ label at every 10th data point by setting the labels for the other 9
+ to be empty strings. Also: Removed $which_pos values 'plotx' and
+ 'ploty'. These were unused by PHPlot and this is an internal-only
+ function so there is no compatibility issue. Removed error checking on
+ $which_pos for the same reason; the error message used an undefined
+ variable anyway so it wouldn't have worked.
+
+2007-08-26 (lbayuk)
+ * Allow SetLegendStyle colorbox_align argument to be 'none', to suppress
+ the colorboxes in the legend.
+
+ Fix comment on $legend_text_align: empty means right, not left.
+
+ Rewrote DrawLegend layout code to make it easier to understand. The
+ result should be within 1 or 2 pixels of the previous size and position.
+
+ * Fixes for bug 1779115: SetLegendWorld() fails on undefined vars
+ Store the given coordinates and remember that they need to be converted
+ from world to pixel coordinates, but defer trying to actually convert
+ them until it is time to draw the legend. This way, there are no
+ problems with the scale having to being set up first (which is nearly
+ impossible to do). Made the following changes:
+
+ Changed legend class variables to be uninitialized, and unset (rather
+ than empty string) means use the defaults. Added a new variable:
+ $legend_xy_world. If it is set, (legend_x_pos, legend_y_pos) need to
+ be converted to pixel coords. If it is unset, they are already pixel
+ coords (or undefined, meaning defaults).
+
+ Changed usage of internal function DrawLegend(): removed all arguments.
+ X and Y were always the class variables anyway, and now it needs to
+ also use the new flag to tell it if X and Y are world or pixel coords.
+ The third argument was unused.
+
+ Removed third, unused, default NULL argument from SetLegendPixels and
+ SetLegendWorld.
+
+ Changes to DrawLegend to convert x, y coords to pixel coordinates
+ if they came from SetLegendWorld. Also account for new usage of
+ the class variables: Test for unset to mean use default.
+
+2007-08-04 (lbayuk)
+ * New feature: control legend text and color box alignment.
+ Adds a new function SetLegendStyle to adjust the alignment of the
+ text and the color boxes inside the legend.
+ Based on part of bug 1208054, contributed by David Hernández Sanz.
+
+2006-12-02 (lbayuk)
+ * Fixes for bug 1605555: Y Data Labels use wrong font and not formatted.
+ Use y_label_font (not x_label_font) for Y Data Labels.
+ Use the formatted value for the label, not the original text.
+ (This applies to bar charts only, with the new Y data labels.)
+
+ * One fix for bug 1208054: Localization of number format.
+ If number formatting is enabled with 'data' format type, PHPlot previously
+ used dot for decimal point and comma for thousands separator, and there
+ was no way to change it.
+
+ This fix adds a new function:
+ SetNumberFormat($decimal_point, $thousands_separator)
+ to set the separators. In addition, if that function is not used,
+ PHPlot will now try to use locale-dependent separators. If locale
+ information is not available, it will fall back to the old defaults
+ of dot and comma.
+
+ Note: This change may have some negative effects. 1) If your locale is
+ "C" or "Posix", you might not get a thousands separator now by default.
+ You should be using a more specific locale. 2) If your PHP script is
+ forcing a specific locale with setlocale(), PHPlot will probably undo
+ that because it uses setlocale(LC_ALL, '') to import locale information
+ from the environment. We have to do that, or a locale set through
+ the environment is ignored. But it will override a manually set locale.
+
+ * Fix for bug 937944: X/Y Tick Counts
+ PHPlot could draw one too few Y tick marks, and one too many X tick marks.
+
+ Changed the code to stop drawing X (Y) tick marks when the current X (Y)
+ value exceeds the maximum X (Y) value plus a small fudge factor. The fudge
+ factor accounts for cumulative error when repeatedly adding a delta to
+ the X (Y) value.
+
+ Notes: The bug report was writing about Y tick counts only, but X tick
+ counts can also be wrong. The proposed fix in the bug report does not
+ work in all cases.
+
+ This fix changes the appearance of many plots which were missing the
+ top-most Y tick mark. The extra X-tick mark problem is less common.
+
+===== Released as 5.0rc3 =====
+
+2006-11-13 (lbayuk)
+ * Fix for bug 1437912: x-axis label misalignment [bar charts]
+ The calculations were redone from scratch.
+ New control variable 'bar_extra_space', which works in addition to
+ 'group_frac_width' to control how much extra space is around the bars.
+ Made bar widths match for 'stackedbars' and 1-bar-per-group 'bars'.
+
+ NOTE: This changes the appearance of charts. bars in 'stackedbars'
+ will now be thinner, and bars in 'bars' graphs will be thicker. I
+ saw no reason for them being different before.
+
+ This fix required fixing the positioning on the new bar data labels,
+ which was off before. The bar data labels will now be centered.
+ Additional fixes to bar chart data labels:
+ For negative values, the label will center under the bar.
+ Fixed X-adjustment to account for shading.
+ Fixed to not suppress the data label if the value is 0.
+
+
+2006-11-10 (lbayuk)
+ * Fix for bug 1594457: DrawError text wrap and background fix
+ Do error image white background correctly, and word-wrap the text.
+
+ * Fix for bug 1594458: Suppress lines or points in 'linepoints'
+ Don't draw X data labels twice for 'linepoints'.
+ Allow SetPointShapes value 'none' to suppress points, and allow
+ SetLineStyles value 'none' to suppress lines. This allows a 'linepoints'
+ graph to mix lines only, points only, and both on the same graph.
+
+
+2006-11-09 (lbayuk)
+ * Fixes for bug 1446523:
+ + Wrong variable name in deprecated SetAxisFontSize()
+ + Fails to properly handle error if SetDataValues() was never
+ called, or not called with a data array.
+
+ * Fix for bug 1117122: Pie Chart ignores SetPlotAreaPixels
+ Don't let DrawGraph recalculate the plot area for pie charts if the
+ user already set it with SetPlotAreaPixels.
+
+ NOTE: This fix may slightly change the appearance of some pie charts,
+ whether or not they use SetPlotAreaPixels.
+
+ * Fix for bug 1103992: Wrong max Y calculated for stackedbars
+ Changes FindDataLimits to calculate max Y correctly. It was counting
+ the first Y value in each record twice, which is always wrong but
+ only affected stackedbars because the Y values are summed.
+
+ * Fix for bug 1096199: Wrong error bar colors in DrawDotsError.
+ Rewrites DrawDotsError to make it work like DrawLinesError to
+ correctly increment the record and color indexes.
+ Also fixes uninitialized x_now_pixels.
+
+ * Fix for bug 1096197: No borders on unshaded Draw[Stacked]Bars
+ Unshaded Bars and StackedBars covered the border with the rectangle.
+ The fix is to draw the rectangle, then the border.
+
+ NOTE: This fix changes chart appearance. Bars and Stacked Bars
+ will now get a black border around each bar by default, if you
+ turn off the 3D-shading. If you want borderless, unshaded bars
+ you need to use SetDataBorderColors to set the data border colors
+ to be the same as the data colors.
+
+ * Fix for bug 1333164: Negative data values, if string variables, result
+ in unfilled bars. The problem was a string-to-string compare of a
+ negative number with the empty string x_axis_position. Fixed by
+ initializing x_axis_y_pixels to 0 if SetXAxisPosition was not used.
+
+
+2005-04-17 (afan)
+ * Fix for bug [ 1161072 ] SetInputFile warning, background overwrite
+
+ * Bug 1182672 fixed
+
+2005-04-15 (afan)
+ * fix for bug: [ 1182666 ] Y Auto-scale rounds in wrong direction
+
+ * Fix for bugs 1144644 TrueType font path problems and 1106328 TTF
+ path/filename inconsistency
+
+ * Fix Bug: [ 1117120 ] X Title sizing uses Y Title font height
+
+2005-04-13 (afan)
+ * Error in SetLineStyles() - does not accept an array argument
+
+
+2005-03-29 (afan)
+ * Small typo fixed in SetYDataLabelPos
+
+ * Update SetDataLabelPos: For past compatibility we accept plotleft,
+ ...but pass it to SetTickLabelPos
+
+2005-03-26 (afan)
+ * Change to line 3802: data lables now work with multiple bars with *$idx
+
+2005-03-25 (afan)
+ * Added Function DrawDataLabels to put data labels in world coords,
+ added call from DrawBars and modified SetYDataLabelPos to flag
+ whether or not to call DrawDataLabels.
+
+2005-01-20 (migueldb)
+ * Many bugfixes reported and solved by L. J. Bayuk. Thanks!
+ + fixed bug #1096190
+ + FindDataLimits(): fixed bug #1096192
+ + CalcTranslation(): fixed bug #1101317
+ + DrawImageBorder(): fixed bug 1096200
+ + DrawXDataLabel(): fixed bug 1099879
+ + DrawDots(): fixed bug #1096194
+
+===== Released as 5.0rc2 =====
+
+2004-10-24 (migueldb)
+ * array_merge_php4(): added to cope with the bug introduced by
+ the change in array_merge() from PHP4 to PHP5 (I haven't verified this)
+ * Fixed some divisions by zero, thanks to an old bug report.
+
+2004-09-09 (migueldb)
+ * SetPointSize(): deprecated
+ * SetPointSizes(): added as replacement for SetPointSize().
+ Now able to set point sizes on a per line basis.
+ * SetPointShape(): deprecated.
+ * SetPointShapes(): added as replacement for SetPointShape().
+ Now able to set point shape on a per line basis.
+ * DrawDot(): now needs record number to decide which dot shape and
+ size to draw.
+ * CalcMargins(): dirty fix for x data label placing.
+ * tile_img(): fixed tile placement.
+
+2004-06-14 (migueldb)
+ * SetXTickLabelPos() and others: more on the bug reported by Jo Demol.
+ * Fixed bug reported by Jo Demol.
+
+2004-05-11 (migueldb)
+ * SetBgImage(): added.
+ * SetPlotAreaBgImage(): added.
+ * SetInputFile(): deprecated.
+ * DrawBackground(): now accepts images as backgrounds.
+ * DrawPlotAreaBackground(): now accepts images as backgrounds.
+ * tile_img(): internal method added.
+
+..........
+Editor's Note: For older changes to PHPlot, please see the CVS logs.
--- /dev/null
+This is the NEWS file for PHPlot, with release documentation.
+The project web site is http://sourceforge.net/projects/phplot/
+The project home page is http://phplot.sourceforge.net/
+Refer the the ChangeLog file for detailed source changes.
+-----------------------------------------------------------------------------
+
+2011-01-15 Release 5.3.1
+
+Overview:
+
+This is the current stable release of PHPlot. This release focuses on
+providing better support and documentation for creating multiple plots on a
+single image.
+
+The PHPlot reference manual has been updated to match this release. Some
+new material has been added, including a new section on multiple plots per
+image, and a new example of overlay plots.
+
+
+Bugs Fixed in 5.3.1:
+
+#3143586 "Multiple plots per image - fixes & docs":
+ The reference manual now contains a section on multiple plots, and a
+ new example. A bug was fixed with SetLegendWorld and multiple plots.
+ Image border will now be drawn at most once. It is now possible to
+ restore the default 'automatic' behavior for axis positioning. Other
+ functions were changed to make arguments optional, so when called with
+ no arguments they reset to the default. The reference manual has been
+ updated with these changes too.
+
+#3147397 "Data colors missing with multiple plots":
+ The fix for bug #3049726 "Optimize color allocation" caused a problem
+ with multiple plots. This has been fixed. PHPlot will no longer truncate
+ the data color table at each plot. It will still only allocate data colors
+ as needed, but all of the pre-set or configured data colors will be
+ available for each plot.
+
+
+-----------------------------------------------------------------------------
+
+2010-12-04 Release 5.3.0
+
+Overview:
+
+This is the current stable release of PHPlot. This release includes new
+plot types and some new features.
+
+The PHPlot reference manual has been updated to match this release. Some of
+the sections have been moved, there are new examples for the new plot types,
+and a new section on tunable parameters has been added.
+
+
+New features in 5.3.0:
+
+#3093483 "Investing support chart types":
+ Added 3 new plot types: Basic OHLC (Open/High/Low/Close), Candlesticks,
+ and Filled Candlesticks. These are variations of plots that show the
+ performance of a stock or other financial security.
+
+#3111166 "Control legend colorbox width":
+ It is now possible to control the width of the color boxes in the
+ legend, using a class variable which is documented in the manual.
+
+#3117873 "Data value labels in more plot types":
+ Data value labels, which show the dependent variable values near the
+ data points, are now available for more plot types: lines, linepoints,
+ points, and squared. (These were previously available only for bars and
+ stackedbars plots.)
+
+#3127005 "Ability to suppress X/Y axis lines":
+ New functions SetDrawXAxis() and SetDrawYAxis() were added to control
+ display of the X and Y axis lines. (These lines were probably the only
+ PHPlot elements that could not be turned off.) In special cases, these
+ can be used to produce a "bare" plot image.
+
+
+-----------------------------------------------------------------------------
+
+2010-10-03 Release 5.2.0
+
+Overview:
+
+This is the current stable release of PHPlot. This release includes some
+bug fixes and new features, described below, and a reimplementation of
+internal processing of colors.
+
+The PHPlot reference manual has been updated to match this release.
+Horizontal plots are now documented in the manual, and the interim
+documentation in the source release (HorizontalBars.txt) has been removed.
+The manual is available in HTML format as a separate download from
+Sourceforge. The manual is also available for on-line viewing from the
+project home page. Starting with this release, the manual is also
+available in PDF format from the project home page.
+
+
+Cautions, Important Notes, and Compatibility Issues:
+
+Due to changes in color allocation (see bug #3049726 below), image files
+produced with PHPlot-5.2.0 will differ when compared byte-for-byte with
+those created by earlier releases, even when the images are identical (as
+they nearly always are).
+
+If you are creating a horizontal plot with any negative X values, and not
+setting the Y axis position, your plot will change (see bug #3074402 below)
+because PHPlot no longer leaves the Y axis on the left for horizontal plots.
+
+Some internal methods that used to have 'public' visibility are now protected.
+This will generally prevent you from using them. The list of changed functions
+can be found in the release ChangeLog. Avoid using any internal methods.
+
+If you are making a stackedbar plot with any negative values, PHPlot-5.1.3
+and earlier took the absolute value of each data value (which was not
+documented), but PHPlot-5.2.0 does not. See Feature Request #3073679 below.
+
+If your plot fills the 256 available color map slots in a palette image,
+your image may look different with PHPlot-5.2.0 due to changes in color
+allocation order. This was seen on two of the tests in the PHPlot test
+suite. These tests tiled a JPEG image into the plot area or image
+background. Being a truecolor image, the JPEG had a huge number of colors,
+which filled all available slots in the color map. Additional colors for
+plot elements had to be approximated, and different colors resulted with
+PHPlot-5.2.0 versus previous releases. To avoid this problem, either use a
+truecolor PHPlot object (PHPlot_truecolor constructor), or reduce the
+number of colors in the background image and convert it to PNG or GIF.
+
+This release contains significant changes to PHPlot internals. In particular,
+variables and functions related to element colors and color handling have
+changed. Refer to the PHPlot release ChangeLog for more details. Remember,
+if you rely on accessing any member variable, or on using any non-public
+function or any function not documented in the reference section of the manual,
+your code is at risk of breaking with each new release.
+
+
+New features in 5.2.0:
+
+#3077554 "Finer control over plot element colors" (partial):
+ The X, Y, and main titles can now have different colors. See the PHPlot
+ Reference Manual entries for SetXTitleColor and SetYTitleColor.
+
+#3073679 "Stacked bar plots with negative values":
+ A stacked bar plot can now include negative values, and stacks of negative
+ values will be drawn downwards (or leftwards). See the PHPlot Reference
+ Manual under "Plot Type: stackedbars" for details.
+
+
+Bugs Fixed in 5.2.0:
+
+#3045131 "SetTransparentColor problems":
+ Setting a transparent color now works whether before or after setting
+ the background color (for example), and also now works with a data color.
+
+#3049726 "Optimize color allocation"
+ PHPlot now defers allocating colors until drawing time, and tries to allocate
+ only the colors which are actually needed. For palette images, this results
+ in use of fewer color slots and slightly smaller image files.
+
+#3074402 "Fix Y axis default for horizontal plots":
+ When horizontal plots were introduced, an asymmetry with the X and Y axis
+ position defaults was known but left. This behavior was later determined
+ to be unhelpful. So now the Y axis on horizontal plots will default to X=0,
+ or the X value closest to zero within the plot area range. This is the same
+ behavior as for the X axis in vertical plots.
+
+#3056991 "Internal methods should be 'protected'":
+ More of the internal PHPlot functions were changed to 'protected' visibility,
+ as the test suite was fixed to not call them directly.
+
+#3057000 "Review 'deprecated' methods":
+ One broken deprecated method (SetColor) was removed and one changed.
+ Note that deprecated methods are not documented and not tested.
+
+-----------------------------------------------------------------------------
+
+2010-08-30 Release 5.1.3
+
+Overview:
+
+This is the current stable release of PHPlot. Additional horizontal plot
+types and features have been added, however horizontal plots are still
+considered 'experimental'. A new callback has been added which allows
+greater control over the data colors. An improved method for accessing
+TrueType Font (TTF) files means that on many systems TTF text can be used
+without specifying font paths.
+
+
+Cautions and Important Notes:
+
+Since the previous PHPlot release, PHP-5.3.3 and PHP-5.2.14 have been
+released, and these include a fix for the TrueType Font (TTF) rendering
+problem. Use of these releases is now recommended.
+
+There has been extensive cleanup of the PHPlot code. If you have a
+customized version of PHPlot, you may find it difficult to update.
+
+The "additional data support" script phplot_data.php has been removed from
+this release. The script has not been developed or tested in a long time,
+and was found to have numerous problems. The script can still be found in
+the CVS repository.
+
+The changes in this release (horizontal plots, custom data color callback,
+and TrueType Font handling) should not result in any compatibility issues.
+
+
+New features in 5.1.3:
+
+#3049703 "Additional horizontal plots and features":
+ + Implemented data values labels in horizontal bar charts.
+ Use: SetXDataLabelPos('plotin').
+ + Add horizontal stacked bar charts, with data value labels.
+ + Add horizontal thinbarline plots.
+ Horizontal plots are still considered 'experimental', and documentation is
+ in the HorizontalBars.txt text file rather than the PHPlot Reference Manual.
+
+#3034164 "Extended control of data colors":
+ New callback 'data_color' can be used to customize selection of the color
+ of each bar, line segment, point marker, etc. This is documented in the
+ PHPlot Reference Manual section "Custom Data Color Selection", with new
+ examples in the Examples chapter.
+
+
+Bugs Fixed in 5.1.3:
+
+#3051906 "Better choice for default TT font":
+ Rather than always using the unlikely 'benjamingothic.ttf' as its default
+ TrueType font name, PHPlot now has a short list of sans-serif fonts, and
+ tries to find one that works if a default TT font is needed. On many
+ systems, this will provide a high-quality default font without help.
+
+#3051832 "Let PHP/GD find the font file":
+ Instead of using file existence to validate a TT font file, PHPlot now
+ just tries to use the font. This allows PHP/GD to use its own rules to
+ try to find the font, without needing a pathname. This works on Windows
+ and at least some Linux systems.
+
+#3048267 "phplot_data add-on is still broken"
+ Not fixed. phplot_data.php has been removed from the release.
+
+-----------------------------------------------------------------------------
+
+2010-06-29 Release 5.1.2
+
+Overview:
+
+This is the current stable release of PHPlot. Truecolor image support is no
+longer considered 'experimental', and is now documented in the reference
+manual. There is a new experimental feature for horizontal bar charts. This
+release also contains a bug fix and new feature.
+
+
+Cautions and Important Notes:
+
+The advisory against using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use
+TrueType fonts (TTF) continues. See the item below for PHPlot-5.1.1. The
+good news is that this has been fixed by the PHP Team and will be in the
+next releases.
+
+Compatibility of data type and plot type are now checked completely. If
+you used an incorrect data type with certain plot types, your script may no
+longer work until you fix the data type. Specifically, the area, squared,
+and thinbarline plot types failed to check the data type they received, and
+treated anything other than 'data-data' as 'text-data'. If you have a
+squared plot with data type 'data-data-error', for example (which is not
+supposed to work), it did produce a plot, but will now result in an error.
+
+The addition of horizontal bar charts should not impact any existing plot,
+with one small exception. The function SetYDataLabelPos() used to accept
+some additional, undocumented options (plotleft, plotright, both, yaxis)
+and pass these through to SetYTickLabelPos() "for compatibility". It no
+longer does so, as some of those are now used for horizontal bar chart
+labels. To position Y tick labels, use only SetYTickLabelPos().
+
+
+New features in 5.1.2:
+
+#3002606 "Add to plot and image border options":
+ SetPlotBorderType() now accepts 'right', 'top', and 'bottom', as well
+ as an array of options. So you can now control exactly which of the 4
+ border sides will be drawn.
+ SetImageBorderType() now accepts 'solid' as a choice. This will use the
+ actual color set with SetImageBorderColor(), rather than the darker
+ shade as type 'plain' does (which may have been a bug).
+ SetImageBorderWidth() is a new function that sets the width of the image
+ border. The defaults are the same as the fixed values used before: 1
+ pixel for plain, 2 pixels for raised. The image border width is now
+ accounted for in margin calculations, if it is greater than 2 (to make
+ sure existing plots will not change).
+
+#2885930 "Horizontal Bars":
+ Horizontal bar charts are implemented, as an experimental feature.
+ 'Experimental' means they are not yet documented in the reference manual,
+ and subject to change or removal.
+ Refer to the text file HorizontalBars.txt for details.
+
+#2947679 (follow-up) "Support for alpha blending/Truecolor":
+ Truecolor support is now documented in the Reference Manual. The interim
+ documentation file Truecolor.txt has been removed. Alpha channel
+ specification now works with both constructors and both image types. This
+ fixes an issue if the base constructor was used with a truecolor background
+ image. (In PHPlot-5.1.1, the result would be a truecolor image, but the
+ alpha channel features were not available.)
+
+
+Bug Fixed in 5.1.2:
+
+#3010116 "Bad rendering of title in multi-plot image when using TTF":
+ Make sure the main title is drawn only once, to avoid bad rendering of
+ TTF titles with multiple plots due to anti-aliasing.
+
+-----------------------------------------------------------------------------
+
+2010-04-04 Release 5.1.1
+
+Overview:
+
+This is the current stable release of PHPlot. This release adds truecolor
+image support as an experimental feature, fixes a number of bugs and adds
+a few new features.
+
+The PHPlot reference manual has been updated to match this release. The
+manual is available as a separate download from Sourceforge. The manual is
+also available for on-line viewing from the project home page.
+
+See the ChangeLog file in the release for more about changes and bug fixes.
+
+
+Cautions and Important Notes:
+
+Avoid using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use TrueType fonts
+(TTF). Some new bugs were introduced in those releases that adversely
+affects accurate positioning and rendering of TrueType font text.
+
+
+New features in 5.1.1:
+
+#2947679 "Support for alpha blending/Truecolor":
+ PHPlot can now produce truecolor images, with alpha blending of colors and
+ other effects. This is considered an experimental feature, meaning it is
+ not yet documented in the PHPlot Reference Manual, and subject to change.
+ Refer to the text file Truecolor.txt included in the PHPlot release for
+ information on using truecolor.
+ Two drawing changes were made to improve plot appearance with Truecolor:
+ + Filled dots (in points & linepoints plots) are now drawn better. This
+ also makes them look rounder with regular (non-Truecolor) plots.
+ + Area plots have the areas filled without overlapping each area down to
+ the Y axis. This was needed to fix problems with alpha blending, and
+ should have no effect on non-Truecolor plots.
+
+#2973995 "Add y-Data to Stackedbars":
+ You can now have Y Data Labels with 'stackedbars' plots. These label the Y
+ values (incremental and total) for each bar. Refer to the reference manual
+ page for SetYDataLabelPos().
+
+
+Bug Fixes in 5.1.1:
+
+#2976735 "Improvements and fixes for 'area' plots":
+ Moving X axis works; handle Y<0 better; new 'stackedarea' plot type is a
+ variation on 'area' with the data represented differently.
+
+#2974639 "Stacked bars plot breaks with X axis != 0":
+ Moving X axis works.
+
+#2963757 "point_counts undefined error in 5.1.0":
+ Fixed an error introduced in PHPlot-5.1.0 when point size and shape arrays
+ were set to the same size.
+
+#2938219 "Bars go in wrong direction":
+ For bar charts with all Y<0, bars will still be drawn down even if Y=0 is
+ not in range.
+
+-----------------------------------------------------------------------------
+
+2009-12-24 Release 5.1.0
+
+Overview:
+
+This is the current stable release of PHPlot. This release fixes a number of
+bugs and adds some new features. Some of the changes in this release can
+alter the appearance of plots, so be sure to review the information in this
+NEWS file and test this release with your application.
+
+The PHPlot reference manual has been updated to match this release. The
+manual is available as a separate download from Sourceforge. The manual is
+also available for on-line viewing from the project home page.
+
+See the ChangeLog file in the release for more about changes and bug fixes.
+
+
+New features in 5.1.0:
+
++ A new "contrib" directory has been added for useful add-ons.
+ This currently contains:
+ * prune_labels : Control data label density on X axis.
+ * color_range : Define a gradient map for data colors.
+
++ Feature Request 2899921 "Allow different format for data and tick labels"
+ Text angle and format can now be controlled separately for data labels.
+
++ Locale loading override
+ New variable locale_override stops PHPlot from getting locale from system.
+
++ Translating Coordinates
+ New function GetDeviceXY() to translate world to device coordinates.
+
++ New drawing callback
+ New callback 'draw_all', called after all drawing is done.
+ The manual now contains an example of using this new callback and
+ the new GetDeviceXY() function to annotate a plot.
+
+
+Bug Fixes in 5.1.0:
+
+#2914403 "Pie + X/Y titles: Undefined property error"
+ X/Y titles are now properly ignored for pie charts.
+
+#2908256 "Error: array_sum() should be an array" (drupal)
+#2916864 "Should at least print legend on pie charts with empty data"
+ Pie charts with invalid data (no Y values > 0) now make an empty plot.
+
+#2906436 "Fixes for X Tick Labels vs X Data Labels"
+ Smarter determination of whether to do Tick labels, Data labels, or both.
+
+#2900914 "Problem with display of 0 on Y axis"
+ Fixed rounding error that could produce something like Y=8.12345E-16.
+
+#2886365 "PHP 5 patch" (Declare all functions and variables in PHP5 style)
+ Most internal PHPlot member functions now have "protected" visibility.
+
+#2839547 "SetImageBorderType('none')
+ You can use SetImageBorderType('none') to turn the image border back off.
+
+#1795972 "Fix default point shapes"
+ We now have 20 (vs 10) point shapes, with 10 (vs 1) used by default.
+
+#1795971 "Fix default data colors"
+ We now have 16 (vs 8) default data colors, no duplicates, all visible.
+
+
+Visible Changes and Possible Incompatibilities:
+
++ PHP5 visibility changes (Bug #2886365)
+Details: Most internal PHPlot member functions now have visibility
+ 'protected', rather than all being public. All member variables are
+ still 'public'.
+
+Reason for the change: Use the recommended PHP5 syntax, better OO style.
+
+Compatibility: If you were calling a PHPlot internal function that got
+ changed to 'protected', this will break. Please report this.
+
+
++ Fix default point shapes (Bug 1795972)
+Details: We now have 20 (vs 10) point shapes available, and by default we
+ have 10 (vs 1) different shapes in use. The default size is now 6 pixels
+ for all point shapes.
+
+Reason for the changes: Using different shapes helps distinguish the data
+ sets. The existing 10 defined shapes were not enough, since some of them
+ are not centered over the points, too small, or otherwise hard to see.
+ The code to synchronize the point shape and size arrays was broken, and
+ some dubious code to adjust sizes to even numbers needed to be fixed.
+
+Compatibility (1): If you have a points or linepoints plot with more than
+ one dataset, and you did not use SetPointShapes() to configure the
+ shapes, them your plot will change from using a diamond for all data
+ sets to using different shapes for up to 10 data sets.
+
+Compatibility (2): Fixing the point size/point shape array size bug may
+ slightly change the size of some shapes, but it now works the way it
+ was documented and supposed to work.
+
++ Fix default data colors (Bug 1795971)
+Details: Defined a new set of 16 default data colors. The colors are
+ different and contrast well against the default white background.
+ The first 4 colors were not changed.
+
+Reason for the change: The default 8 data colors included two instances
+ of orange, and one color which was invisible on a white background.
+
+Compatibility: Colors will change on any plot with more than 4 data sets
+ where you did not use SetDataColors() to set your own data colors.
+
++ Re-used old function SetXDataLabelAngle()
+Details: SetXDataLabelAngle() now does something different.
+
+Reason for the change: This name was needed for a new function, to set the
+ angle for the X Data Labels. The old use of this function was not
+ documented, and marked "deprecated" in the code since around 2003-12-07.
+
+Compatibility: If you are still using SetXDataLabelAngle() to set both Tick
+ and Data label angles, you need to use SetXLabelAngle() instead.
+
++ Separate controls for tick and data labels (Feature Request 2899921)
+Details: New functions SetXDataLabelAngle(), SetYDataLabelAngle(),
+ SetXDataLabelType(), and SetYDataLabelType() to allow separate control
+ over the angle and format of data labels, versus tick labels.
+
+Reason for the change: Allow Data Labels to use different formatting and
+ angle compared to Tick Labels.
+
+Compatibility: The default behavior has been set up such that there should
+ be no compatibility issues. For example:
+ Old behavior: SetXLabelType() sets the type for both tick and data labels.
+ New behavior: SetXLabelType() sets the type for tick labels and the
+ default type for data labels. SetXDataLabelType() sets the type for
+ data labels (overrides SetXLabelType).
+
++ X Tick Labels vs X Data Labels (Bug 2906436)
+Details: Regarding SetXTickLabelPos() and SetXDataLabelPos(): If only one
+ of them is called, the behavior is unchanged (only that label type will
+ be displayed). If both are called: Do exactly what was requested. If
+ neither was called: display only data labels if any data labels are
+ non-empty, else display only tick labels.
+
+Reason for the change: 1) Fix the long-standing problem behavior that by
+ default PHPlot overlays tick and data labels below the X axis. 2) Fix
+ order dependency between setting the position of tick and data labels.
+ 3) Prepare for future extension of data labels, and allow both tick
+ and data labels to be on if the programmer enables both.
+
+Compatibility: There are some cases where your plot will change.
+ (a) Calls neither SetXDataLabelPos() nor SetXTickLabelPos():
+ Old behavior: Both tick and data labels displayed, possibly overlaid.
+ New behavior: If there are any non-blank data labels, then show only
+ the data labels, not the tick labels. Otherwise, show tick labels.
+
+ (b) Calls both SetXDataLabelPos() and SetXTickLabelPos(), with other than
+ 'none' for each position:
+ Old behavior: The latter call was effective; earlier one ignored.
+ New behavior: Independent of order, both calls are effective.
+
+-----------------------------------------------------------------------------
+
+2009-06-14 Release 5.0.7
+
+Overview:
+
+This is the current stable release of PHPlot. The release adds one new
+feature, fixes a few bugs, and changes the license under which PHPlot
+is released.
+
+The PHPlot reference manual has been updated to match this release. The
+manual is available as a separate download from Sourceforge. The manual is
+also now available for on-line viewing at http://phplot.sourceforge.net
+
+See the ChangeLog file for more about changes and bug fixes.
+
+
+Licensing:
+
+PHPlot is now released on the terms of the GNU Lesser General Public
+License, version 2.1. (Previous versions of PHPlot were released under
+a dual "PHP/GPL" license.) The licensing change was authorized by the
+original author and copyright holder of PHPlot.
+
+
+New feature in 5.0.7:
+
++ Plot area margins can now be partially specified, using either
+ SetMarginsPixels or SetPlotAreaPixels. In previous releases of
+ PHPlot you had to either specify all 4 margins or none.
+ Credit to adoll for this feature.
+
+
+Visible Changes and Possible Incompatibilities:
+
++ Y data range can change:
+ As a result of the bug fixes in this release, automatically-calculated
+ Y data ranges can change. If you have missing Y values in your data,
+ and you let PHPlot calculate the Y data range (that is, you do not
+ call SetPlotAreaWorld with a Ymin value), then the lower limit for Y
+ can change. If you have a plot with data-data-error data type, different
+ error values for different points, and let PHPlot calculate the Y data
+ range, then either Y limit can change.
+
+
+Bug Fixes in 5.0.7:
+
+
++ Fix for bug 2803900: SetRGBArray('large') does not work:
+ Corrected an array name usage problem. You can now select the large
+ color map. Also PHPlot no longer overrides use of the PHP include
+ path when loading the large color map, and now reports an error if the
+ file is needed and not found.
+
++ Fix for bug 2791502 "Error plots treat missing Y values as 0":
+ Missing Y values now with with data-data-error plots.
+
++ Fix for bug 2792860 "Wrong DataLabelLines with missing Y":
+ Data label lines are now suppressed at missing Y values.
+
++ Fix for bug 2786350 "Missing Y data results in bad auto-range":
+ Missing Y values are now ignored when calculating the Y data range.
+ Bug report and analysis by mrten.
+
++ Fix for bug 2786354 "Incorrect auto-range for data-data-error":
+ The Y data range is now correctly calculated for data-data-error plots
+ when the error values differ from point to point.
+
+
+-----------------------------------------------------------------------------
+
+2009-01-20 Release 5.0.6
+
+Overview:
+
+This is the current stable release of PHPlot. The purpose of this release
+is to fix additional problems with text spacing and positioning, and
+introduce some minor new features.
+
+The PHPlot reference manual has been updated to match this release. The
+manual is available as a separate download from Sourceforge. The manual is
+also now available for on-line viewing at http://phplot.sourceforge.net
+
+
+New features in 5.0.6:
+
++ Allow mixing GD and TrueType font text on the same plot
+ You can use the new method functions SetFontGD() and SetFontTTF() to
+ select a font and font type for text element (labels, titles, etc.) For
+ example, you can have TrueType plot titles, and GD-fixed font labels.
+ SetUseTTF() now sets the default text type, TTF or GD. This is fully
+ backward compatible.
+
++ Extended label formatting
+ See the reference manual for more information on these.
+
+ New label formatting types are added: 'printf' (using a user-defined
+ format), and 'custom' (using a callback function).
+
+ For 'data' type formatting, a prefix and suffix can be added. (PHPlot
+ previously had an undocumented suffix for 'data' type, which still
+ works.)
+
+ For 'time' formatting, the format can now be specified in the same function
+ call rather than using SetXTimeFormat and SetYTimeFormat.
+
+ For 'data' formatting, the precision can now be specified in the same
+ function call, rather than using SetPrecisionX and SetPrecisionY.
+
++ Better control over line spacing in multi-line labels
+
+ Line spacing can now be set separately for each text element using an
+ additional argument to SetFont, SetFontGD, and SetFontTTF. The overall
+ SetLineSpacing() value is the default for each text element that does not
+ have a specific line spacing set.
+
+ PHPlot now interprets the value set for line spacing as the number of
+ pixels only for GD text. For TrueType text, it is a scale factor for the
+ font's built-in line spacing for TrueType text. The equation used is:
+ interline_spacing = line_spacing * font_natural_spacing / 6
+ where line_spacing is either the global value set with SetLineSpacing
+ or a more specific value set with SetFont(), and font_natural_spacing
+ is the amount of space between lines built-in to the TrueType font. The
+ factor 6 should really be 4 (since PHPlot always used 4 as the default
+ line_spacing, this would give the natural font spacing by default). But
+ the text is too widely spaced with this value, and 6 was chosen to be
+ more compatible for typical font sizes.
+
+Visible Changes and Possible Incompatibilities:
+
++ Line spacing
+ Multi-line TrueType titles and labels will have different inter-line
+ spacing. Since the text size affects the margin and plot area sizes,
+ this results in slightly different sized features on any plot with
+ multi-line TrueType text.
+ Previous versions of PHPlot used a default 4 pixels for inter-line
+ spacing of multi-line TrueType text, regardless of the font size.
+ PHPlot now uses the 'natural' font inter-line spacing, adjusted by a line
+ spacing parameter (per text type, with a global default).
+
+ The same change can also increase the size of the legend box slightly.
+
++ Internal changes were made to the way font information is stored. Anything
+ that directly references PHPlot internals regarding fonts will break. Usage
+ also changed for the internal functions to size and draw text (ProcessText*,
+ SizeText*) due to font data storage changes.
+
++ Changes were made to internal class variables used to store label
+ formatting information. Anything relying on these internals may break.
+
+
+Bug Fixes in 5.0.6:
+
+#1932571: Data-Data Plot fails with same X values
+ PHPlot will no longer hang if all X values are the same. But this is
+ interim fix to force the X range to 1 to prevent the hang. Eventually,
+ smarter automatic range code will handle this better.
+ Credit to andyl for finding this.
+
+#1891636: Misaligned TTF X Labels
+ PHPlot will now correctly line-up TrueType labels along the X axis. There
+ were small but very noticeable errors before, when the text had descenders
+ or lines with all short letters.
+
+
+-----------------------------------------------------------------------------
+
+2008-01-13 Released 5.0.5
+
+Overview:
+
+This is the current stable release of PHPlot. The emphasis of this release
+is to improve text positioning, margin calculation, and error handling.
+
+Although this is considered a stable release, it has a large amount
+of changed code compared to the previous release 5.0.4. Two of the more
+complex components of PHPlot - text and margin calculations - were mostly
+re-written in this release. You are advised to carefully test your own
+applications with PHPlot-5.0.5 to see how your plots look. Refer to the
+README.txt file included in the release for information on reporting problems.
+
+Starting with this release, PHPlot no longer supports PHP4, since the PHP
+group officially declared end-of-life for PHP4 as of 31 December 2007.
+PHPlot-5.0.5 was tested only with PHP-5.2.5 and we are unlikely to address
+any issues using PHPlot with older versions of PHP.
+
+The PHPlot reference manual has been updated to match this release. The
+manual is available as a separate download from Sourceforge. The manual is
+now also now available for on-line viewing at http://phplot.sourceforge.net
+
+The callback feature added in 5.0.4 is now documented in the reference
+manual. It is still considered experimental and subject to change, however.
+
+
+
+Visible Changes and Possible Incompatibilities:
+
++ Dropped support for PHP4.
+
++ Eliminated remaining order-dependent behavior related to margins and
+text. PHPlot should now do nothing at all, except record parameters, until
+you draw the graph with DrawGraph. I believe this was always the intended
+behavior of PHPlot, but over time perhaps various pre-calculations and
+dependencies crept in. Fixing this simplifies processing and should lead to
+more consistent behavior.
+
++ The rewritten margin calculation code now uses actual sizes of all tick
+and data labels and tick marks, rather than guesses. Margins collapse to
+remove unused elements, but a minimum margin (currently fixed at 15 pixels)
+is applied so the plot edges don't get to close to the image edges. The
+result is that most graphs with auto-calculated margins will change in
+appearance. It most cases, the margins get slightly smaller. In other
+cases, earlier releases mis-calculated the margins, so this release will
+produce much neater margins.
+
++ The X and Y titles are now offset out from the plot area, not in from the
+image area. For auto-calculated margins this should not make any
+difference, but if you use SetMarginsPixels or SetPlotAreaPixels to set
+larger margins, the axis titles will move in closer to the plot with this
+release.
+
++ Changes were made to PHPlot internals, including removal of some class
+variables and functions, and addition of new variables and functions.
+These are documented in the ChangeLog. Relying on any internal variables
+or functions in an application using PHPlot is unwise. The following
+internal functions were removed:
+ SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights()
+ CalcYWidths() DrawLabels() InitImage() DrawDashedLine()
+ These were marked 'deprecated', were undocumented and unmaintained.
+ TTFBBoxSize()
+ This was replaced with SizeText().
+
++ Line spacing set with SetLineSpacing() now affects TTF text as well as
+GD text. Previously, it only affected GD text. The default line spacing
+happens to be usable for TTF text.
+
++ Changes were made to error handling. PHPlot will now trigger a user-level
+error after producing an error image, instead of exiting. If no error
+handler has been set, it will exit, as before. But now the error message
+should also get logged, or written to the standard error stream, depending
+on the SAPI in use. You can now establish an error handler to catch most
+PHPlot errors and do some cleanup before exit.
+
++ PHPlot no longer accepts some invalid option values (such as a substring
+of a valid value, or empty strings) passed to functions. If your
+application aborts in CheckOption with PHPlot-5.0.5 but 'worked' with
+previous releases, them you were probably using an invalid option value.
+
+
+
+Bug Fixes in 5.0.5:
+
+#945439: x_tick_label_height not set correctly
+ Exact sizes of labels are now used to calculate margins.
+
+#1813070: Bad position for multi-line TrueType text
+ Fixed as part of text functions rewrite. Use correct basepoint
+ (lower left of each line) when positioning text lines.
+
+#1813071: Wrong title height for multi-line TTF text
+ Fixed as part of text functions rewrite: calculate height of
+ multi-line text correctly. Also now uses the line-spacing setting.
+
+#1813474: DrawText alignment arguments wrong
+ Fixed so 'top' and 'bottom' now have the usual meaning: top means
+ align top of text with reference, bottom means align bottom of text.
+ This was switched before. Changed every internal caller to compensate.
+
+#1816844: Fix order dependency for setting titles
+ Defer processing of title strings until DrawGraph(),
+ so it doesn't matter if fonts, etc. are set before or after.
+
+#1819668: Horiz. align multi-line text: GD vs TTF
+ The text functions were rewritten to draw TTF text line-by-line,
+ like GD text, and correctly align each line.
+
+#1823774: Default Font Path and Error Message
+ Error handling has been improved to make sure a message is logged, in
+ addition to the error image, and use error_trigger rather than exit.
+
+#1826513: FIXME in DrawLegend: Max label length
+ The actual size needed for legend text is now used.
+
+#1827263: Spoiled up pie-chart if $val is close to zero
+ Fixed by skipping over any segment that rounds to 0 degrees of
+ arc. (The GD function uses integer angles only, and 0 degrees
+ means draw a complete circle.)
+
+#1836528: Insufficient checking of parameter values
+ Rewrote validator function to reject improper parameter values.
+
+#1843012: Make margins, drawing consistent
+ Margin code logic was rewritten and checked for consistency.
+
+#1856207: Margin error with 'xaxis'/'yaxis' position
+ Margin space is now allocated for ticks and labels if their position
+ is 'xaxis' or 'yaxis' and the axis is at the plot edge. This is not
+ a perfect fix (the axis could be close but not at the edge).
+
+
+-----------------------------------------------------------------------------
+
+2007-10-20 Released 5.0.4
+
+Overview:
+
+This is the latest stable release of PHPlot. We are abandoning the 'rc'
+version naming style, because we don't consider these last releases
+'release candidate' versions. As we continue to make changes to PHPlot,
+we are not converging toward a final "5.0" release, however we do consider
+these releases stable and complete enough for production use.
+
+This release fixes a number of problems and introduces a few new features.
+
+The PHPlot reference manual has also been updated to match this release.
+New material has been added documenting some of the PHPlot internals.
+The manual is available as a separate download from Sourceforge.
+
+
+Code Cleanup:
+
+Some code cleanup is going in to this release. It is hoped that these
+changes will not impact any existing scripts using PHPlot, but will make
+the PHPlot code itself easier to understand and maintain.
+
+PHPlot now avoids making changes outside its own class definition. There
+are no longer any functions defined outside the class, nor any constants.
+Three constants (MINY MAXY TOTY) were removed, and 2 functions were removed
+(see Visible Changes below). Also PHPlot no longer sets the PHP error
+reporting level to E_ALL. Although we highly recommend setting error
+reporting to E_ALL in your php.ini file or scripts, it is not right for
+PHPlot to assume that you want it.
+
+
+Visible Changes and Possible Incompatibilities:
+
+Arrays containing color and style information are used with several PHPlot
+functions to control the plot style array. These functions are:
+ SetPointShapes, SetPointSizes, SetLineWidths, SetLineStyles,
+ SetDataColors, SetDataBorderColors, and SetErrorBarColors.
+The arrays passed to these functions MUST used sequential integer 0-based
+indexes. This is what the PHP manual calls "Usual integer indices (starting
+from zero, increasing by one)". This is the type of array you get in PHP by
+default if you use array() without specifying key values, or use the
+empty-bracket assignment operator to add values onto an array. In previous
+versions of PHPlot, some of these functions would also work with
+string-indexed or non-sequentially-indexed arrays, but this was not clearly
+defined. Starting with PHPlot-5.0.4, only arrays with "usual integer
+indices" work, and other array indexes will cause errors.
+
+Some internal-use-only functions have had their usage changed or been removed.
+If you are using functions that are not documented in the PHPlot Function
+Reference in the manual, your code may have to be changed.
+
+As part of the code cleanup, two functions which were defined outside the
+PHPlot class were removed: array_pad_array(), and array_merge_php4().
+If your code used these, you need to fix your code.
+
+The routines which accept a color name, value, or array now check for a valid
+color name. If you specify a color name which is not in your current color
+table, PHPlot will draw an error and exit. Previously, PHP would report an
+index error, continue, and get a 'headers already sent' message.
+
+
+Bug Fixes in 5.0.4:
+
+#1813021: Miss-positioned right-justified vertical GD text.
+ Fixed DrawText() to correctly position 90 degree right-justified text
+ drawn in a fixed GD font. This could be seen with 90 degree Y tick labels.
+
+#1790441 Removed destructor/shutdown function, and no longer recommend
+ using reference assignment when creating a PHPlot object. This was
+ interfering with memory usage.
+ Credit to annajilly for analysis.
+
+#1779115 SetLegendWorld() failed because of undefined variables. The
+ required order dependency was too hard to meet. This is now fixed.
+ You can now use SetLegendWorld anywhere before DrawGraph.
+
+#1726810 (feature request, but actually a bug fix) Ignore empty strings
+ as data labels when doing time or data label formatting. These would
+ previously produce errors or bad formatting. Now you can omit labels
+ as needed even with time and data formatting.
+ Credit to exgerhardr for finding this.
+
+#1605555 Y data labels used wrong font and not formatted (bar charts only).
+
+#1208054 Localization of number formatting in 'data' format type. PHPlot
+ will attempt to format the numbers in a way appropriate to your locale.
+ You can also force the formatting with the new function SetNumberFormat.
+ Credit to David Hernández Sanz.
+
+#937944 X/Y Tick counts: PHPlot could draw one two few Y tick counts, and
+ one too many X tick counts. This is not a perfect fix, and more work is
+ needed here, but this fixes an error case in both X and Y values.
+
+
+New Features in 5.0.4:
+
+New function SetLegendStyle allows control of the alignment of text and
+ color boxes within the legend. Also allows removing the color boxes.
+ Based on bug #1208054.
+ Credit to David Hernández Sanz.
+
+New function SetNumberFormat. See bug report #1208054 above.
+
+Callbacks are added. PHPlot can call back your functions while generating the
+ plot. This is experimental, and documented only in the file "Callbacks".
+ Credit to annajilly for the idea and design.
+
+-----------------------------------------------------------------------------
+
+2006-11-13 Released 5.0rc3
+
+Overview:
+
+This is an interim release. It has been a long time since the previous
+release 5.0rc2, and there have been a lot of changes. There are still more
+changes likely to go in before we have "5.0", but there are enough for now.
+
+The PHPlot Reference Manual has also been released, and is available as a
+separate download from Sourceforge. PHPlot users and developers are
+strongly encouraged to read the manual.
+
+This release does not include the "doc/" and "examples/" directories of
+previous releases. The Reference Manual contains more complete and
+up-to-date information and examples, and I am unable to maintain the doc/
+and examples/ files while also maintaining the Reference Manual. If you
+need those files, they can be accessed with the Sourceforge web CVS
+browser.
+
+
+New Features:
+
+The emphasis for this release is bug fixing, so there are few new features.
+
++ You can now suppress lines or points on individual plots in a linepoints
+ graph. This feature was added because I needed a graph with several
+ linepoints lines, but also with a solid line showing an "80% goal".
+ Use SetPointShapes with the value 'none' in the array to suppress the
+ point markers for that plot (and only draw the line).
+ Use SetLineStyles with the value 'none' in the array to suppress the
+ line for that plot (and only draw the point markers).
+ [Bug # 1594458]
+
++ Bar charts can have data labels above the bar with the value. Turn
+ these on with SetYDataLabelPos('plotin'). This is somewhat experimental,
+ since there isn't a lot of room for labels on top of the bars and you
+ may find the results are not useful.
+
+
+Visible Changes:
+
+Here are the more significant changes in this release. These are changes
+which may affect existing scripts and output from PHPlot. See the
+ChangeLog file for information about all changes and bug fixes.
+
++ A bug fix on bar chart bar borders results in black borders around the
+ bars if shading is turned off. The border was previously covered up,
+ but was supposed to be there. If you need borderless, unshaded bars,
+ you need to use SetDataBorderColors to make the borders the same colors
+ as the bars. [Bug # 1096197]
+
++ TrueType font pathname handling was fixed. You no longer need to use
+ SetUseTTF(True). You can either use full paths to the font files with
+ SetDefaultTTFont() and SetFont(), or you can call SetTTFPath() to point
+ to a directory of font files, and then use simple font filenames without
+ paths in SetDefaultTTFont() and SetFont().
+ [Bug # 1144644 plus several others]
+
++ There have been several fixes regarding automatically calculated ranges
+ and scales. The result is that you may see less extra space and fewer
+ tick marks in some cases.
+
++ A fix was made to bar and stackedbar graph bar widths in order to get
+ the X axis labels to properly center. As part of the fix, the bar widths
+ now match between the two graph types. (Before this fix, the bars were
+ narrower in bar graphs compared to the same data plotted as a stacked
+ bar.) As a result, bar graph bars will now be drawn with wider bars, and
+ stackedbar graph bars will be narrower. You can adjust this with the new
+ class variable bar_extra_space. [Bug # 1437912]
+
++ Dot shapes and sizes were off by 1 or 2 slots in the array of shapes or
+ sizes. After the fix, you may get different dot shapes or sizes per
+ plot line. [Bug # 1096194]
+
+
+Testing:
+
+Since its output is visual (graphics), and it has so many interconnected
+modes and options, PHPlot is difficult to test. But at least we are now
+trying. I have a collection of PHPlot scripts (currently about 60) and a
+script to run through them. The script automatically checks that:
+ 1) Nothing was written to the standard error stream;
+ 2) An image file of size greater than 0 was written;
+ 3) Neither the test script nor PHPlot did exit(). This catches cases
+ where PHPlot aborts with DrawError().
+
+The automated test is an easy way to check for serious regression, but you
+really need to inspect the output files to validate PHPlot. This takes a
+little time, and it is easy to overlook problems.
+
+The real issue is test coverage. Just as we can be sure that future
+PHPlot releases will pass the test collection, we can also be sure that
+future bug reports will be written against untested cases.
+
+--------------------
+
+2006-11-08 PHPlot on Sourceforge has a new maintainer: lbayuk
+
+--------------------
+
+2004-10-24 Released 5.0rc2
+
+--------------------
+
--- /dev/null
+This is the README file for PHPlot
+Last updated for PHPlot-5.3.1 on 2011-01-15
+The project web site is http://sourceforge.net/projects/phplot/
+The project home page is http://phplot.sourceforge.net/
+-----------------------------------------------------------------------------
+
+OVERVIEW:
+
+PHPlot is a PHP class for creating scientific and business charts.
+
+The release documentation contains only summary information. For more
+complete information, download the PHPlot Reference Manual from the
+Sourceforge project web site. You can also view the manual online at
+http://phplot.sourceforge.net
+
+For information about changes in this release, including any possible
+incompatibilities, see the NEWS.txt file.
+
+
+CONTENTS:
+
+ COPYING . . . . . . . . . . . . LGPL 2.1 License file
+ ChangeLog . . . . . . . . . . . Lists changes to the sources
+ NEWS.txt . . . . . . . . . . . . Highlights changes in releases
+ README.txt . . . . . . . . . . This file
+ contrib . . . . . . . . . . . . "Contributed" directory, add-ons
+ phplot.php . . . . . . . . . . The main PHPlot source file
+ rgb.inc.php . . . . . . . . . . Optional extended color table
+
+
+REQUIREMENTS:
+
+You need a recent version of PHP5, and you are advised to use the latest
+stable release. This version of PHPlot has been tested with PHP-5.3.5 and
+PHP-5.2.17 on Linux, and with PHP-5.3.5 on Windows XP.
+
+Use of PHP-5.3.2 or PHP-5.2.13 is not recommended, if you are using
+TrueType Font (TTF) text. A bug with TTF rendering in those versions
+affects PHPlot images. This was fixed in PHP-5.3.3 and PHP-5.2.14.
+
+You need the GD extension to PHP either built in to PHP or loaded as a
+module. Refer to the PHP documentation for more information - see the
+Image Functions chapter in the PHP Manual. We test PHPlot only with the
+PHP-supported, bundled GD library.
+
+If you want to display PHPlot charts on a web site, you need a PHP-enabled
+web server. You can also use the PHP CLI interface without a web server.
+
+PHPlot supports TrueType fonts, but does not include any TrueType font
+files. If you want to use TrueType fonts on your charts, you need to have
+TrueType support in GD, and some TrueType font files. By default, PHPlot
+uses a simple font which is built in to the GD library.
+
+
+INSTALLATION:
+
+Unpack the distribution. (If you are reading this file, you have probably
+already done that.)
+
+Installation of PHPlot simply involves copying two script files somewhere
+your PHP application scripts will be able to find them. The scripts are:
+ phplot.php - The main script file
+ rgb.inc.php - Optional large color table
+Make sure the permissions on these files allow the web server to read them.
+
+The ideal place is a directory outside your web server document area,
+and on your PHP include path. You can add to the include path in the PHP
+configuration file; consult the PHP manual for details.
+
+
+KNOWN ISSUES:
+
+Here are some of the problems we know about in PHPlot. See the bug tracker
+on the PHPlot project web site for more information.
+
+#3142124 Clip plot elements to plot area
+ Plot elements are not currently clipped to the plot area, and may extend
+ beyond. PHP does not currently support the GD clipping control.
+
+#1795969 The automatic range calculation for Y values needs to be rewritten.
+ This is especially a problem with small offset ranges (e.g. Y=[999:1001]).
+ You can use SetPlotAreaWorld to set a specific range instead.
+
+#1605558 Wide/Custom dashed lines don't work well
+ This is partially a GD issue, partially PHPlot's fault.
+
+#2919086 Improve tick interval calculations
+ Tick interval calculations should try for intervals of 1, 2, or 5 times
+ a power of 10.
+
+PHP Issues:
+
+ PHP has many build-time and configuration options, and these can affect
+the operation of PHPlot (as well as any other application or library). Here
+are some known issues:
+ + Slackware Linux includes a version of PHP built with --enable-gd-jis-conv
+(JIS-mapped Japanese font support). This prevents the usual UTF-8 encoding
+of characters from working in TrueType Font (TTF) text strings.
+ + The Ubuntu Linux PHP GD package (php5-gd) was built to use the external
+shared GD library, not the one bundled with PHP. This can result in small
+differences in images, and some unsupported features (such as advanced
+truecolor image operations). Also, although this Ubuntu GD library was
+built with fontconfig support, PHP does not use it, so you still need to
+specify TrueType fonts with their actual file names.
+ + Some PHP installations may have a memory limit set too low to support
+large images, especially truecolor images.
+
+
+If you think you found a problem with PHPlot, or want to ask questions or
+provide feedback, please use the Help and Discussion forum at
+ http://sourceforge.net/projects/phplot/
+If you are sure you have found a bug, you can report it on the Bug tracker
+at the same web site. There is also a Features Request tracker.
+
+
+TESTING:
+
+You can test your installation by creating the following two files somewhere
+in your web document area. First, the HTML file:
+
+------------ simpleplot.html ----------------------------
+<html>
+<head>
+<title>Hello, PHPlot!</title>
+</head>
+<body>
+<h1>PHPlot Test</h1>
+<img src="simpleplot.php">
+</body>
+</html>
+---------------------------------------------------------
+
+Second, in the same directory, the image file producing PHP script file.
+Depending on where you installed phplot.php, you may need to specify a path
+in the 'require' line below.
+
+------------ simpleplot.php -----------------------------
+<?php
+require 'phplot.php';
+$plot = new PHPlot();
+$data = array(array('', 0, 0), array('', 1, 9));
+$plot->SetDataValues($data);
+$plot->SetDataType('data-data');
+$plot->DrawGraph();
+---------------------------------------------------------
+
+Access the URL to 'simpleplot.html' in your web browser. If you see a
+simple graph, you have successfully installed PHPlot. If you see no
+graph, check your web server error log for more information.
+
+
+COPYRIGHT and LICENSE:
+
+PHPlot is Copyright (C) 1998-2011 Afan Ottenheimer
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License.
+
+This software 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this software; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--- /dev/null
+This is the README for PHPlot Contributed Code
+The project web site is http://sourceforge.net/projects/phplot/
+Last updated on 2009-12-08
+-----------------------------------------------------------------------------
+
+The PHPlot Contributed Code directory contains code you might find useful
+with PHPlot, but that doesn't quite belong as part of PHPlot itself.
+
+You will have to read the comments in the code files, and see the example
+files, to determine what these do and if they are useful to you. None of
+these functions is documented in the PHPlot Reference Manual.
+
+You may include or paste these functions into your own scripts. Check the
+files for details, but some of these are considered "public domain" with no
+usage or license restrictions.
+
+-----------------------------------------------------------------------------
+Contents:
+
+prune_labels: Reduce the number of labels along the X axis
+ prune_labels.php . . . . . . . . . . . . Code
+ prune_labels.example.php . . . . . . . . Example
+ prune_labels.test.php . . . . . . . . . Test
+
+color_range: Create a gradient color map for data colors
+ color_range.php . . . . . . . . . . . . Code
+ color_range.example.php . . . . . . . . Example
+ color_range.test1.php . . . . . . . . . Image creation test
+ color_range.test2.php . . . . . . . . . Unit test
+
+-----------------------------------------------------------------------------
--- /dev/null
+<?php
+# PHPlot / contrib / color_range : Example
+# $Id: color_range.example.php,v 1.1 2009/12/09 03:45:45 lbayuk Exp $
+# This is a bar chart with a color gradient for the bars in each group.
+
+require_once 'phplot.php';
+require_once 'color_range.php';
+
+$bars_per_group = 10;
+$x_values = 4;
+
+mt_srand(1);
+$data = array();
+for ($i = 0; $i < $x_values; $i++) {
+ $row = array($i);
+ for ($j = 0; $j < $bars_per_group; $j++) $row[] = mt_rand(0, 100);
+ $data[] = $row;
+}
+
+$p = new PHPlot(800, 600);
+$p->SetTitle('Example - Bar Chart with gradient colors');
+$p->SetDataType('text-data');
+$p->SetDataValues($data);
+$p->SetPlotAreaWorld(0, 0, $x_values, 100);
+
+# This isn't necessary, as we do know how many data sets (bars_per_group):
+$n_data = count_data_sets($data, 'text-data');
+# Make a gradient color map:
+$colors = color_range($p->SetRGBColor('SkyBlue'),
+ $p->SetRGBColor('DarkGreen'), $n_data);
+$p->SetDataColors($colors);
+$p->SetXTickLabelPos('none');
+$p->SetXTickPos('none');
+$p->SetPlotType('bars');
+$p->DrawGraph();
--- /dev/null
+<?php
+/*
+ PHPlot / contrib / color_range
+ $Id: color_range.php,v 1.2 2010/10/03 21:57:15 lbayuk Exp $
+ PHPlot contrib code - public domain - no copyright - use as you wish
+
+ Original contribution from: Josep Sanz <josep dot sans at w3 dot es>
+ "I wrote this code to calculate the range of colors between 2 colors
+ to plot using the range from color_a to color_b..."
+
+ I have changed the code and repackaged it, but the idea is the same.
+ Given 2 colors and number of data sets, computes an array of colors
+ that make up a gradient between the two provided colors, for use
+ with SetDataColors().
+
+ Provides the following functions:
+ $colors = color_range($color_a, $color_b, $n_intervals)
+ Returns a color array for SetDataColors.
+
+ $n = count_data_sets($data, $data_type)
+ Counts the number of data sets in a data array.
+ This can be used to provide $n_intervals in color_range().
+*/
+
+
+
+/*
+ Fill a color map with a gradient step between two colors.
+ Arguments:
+ $color_a : Starting color for the gradient. Array of (r, g, b)
+ $color_b : Ending color for the gradient. Array of (r, g, b)
+ $n_steps : Total number of color steps, including color_a and color_b.
+
+ Returns: A color map array with n_steps colors in the form
+ $colors[i][3], suitable for SetDataColors().
+
+ Notes:
+ You may use the PHPlot internal function $plot->SetRGBColor($color)
+ to convert a color name or #rrggbb notation into the required array
+ of 3 values (r, g, b) for color_a and color_b.
+
+ Newer versions of PHPlot use 4 components (r, g, b, a) arrays for color.
+ This script ignores the alpha component in those arrays.
+
+*/
+function color_range($color_a, $color_b, $n_steps)
+{
+ if ($n_steps < 2) $n_steps = 2;
+ $nc = $n_steps - 1;
+ # Note: $delta[] and $current[] are kept as floats. $colors is integers.
+ for ($i = 0; $i < 3; $i++)
+ $delta[$i] = ($color_b[$i] - $color_a[$i]) / $nc;
+ $current = $color_a;
+ for ($col = 0; $col < $nc; $col++) {
+ for ($i = 0; $i < 3; $i++) {
+ $colors[$col][$i] = (int)$current[$i];
+ $current[$i] += $delta[$i];
+ }
+ }
+ $colors[$nc] = $color_b; # Make sure the last color is exact.
+ return $colors;
+}
+
+
+/*
+ Determine the number of data sets (plot lines, bars per group, pie
+ segments, etc.) contained in a data array.
+ This can be used to determine n_steps for $color_range.
+
+ Arguments:
+ $data : PHPlot data array
+ $data_type : PHPlot data type, describing $data. (e.g. 'data-data')
+ Returns: The number of data sets in the data array.
+ Notes:
+ This has to scan the entire data array. Don't use this unless you
+ really don't have a better way to determine the number of data sets.
+
+ This does NOT require that the data array be integer indexed.
+
+*/
+function count_data_sets($data, $data_type)
+{
+
+ if ($data_type == 'text-data-single')
+ return count($data); # Pie chart, 1 segment per record
+
+ # Get the longest data record:
+ $max_row = 0;
+ foreach ($data as $row)
+ if (($n = count($row)) > $max_row) $max_row = $n;
+
+ if ($data_type == 'text-data' || $data_type == 'text-data-yx')
+ return ($max_row - 1); # Each record is (label Y1 Y2...)
+
+ if ($data_type == 'data-data' || $data_type == 'data-data-yx')
+ return ($max_row - 2); # Each record is (label X Y1 Y2...)
+
+ if ($data_type == 'data-data-error')
+ return (($max_row - 2) / 3); # Each record is (label X Y1 Y1+ Y1-...)
+
+ # Not a recognized data type... Just return something sane.
+ return $max_row;
+}
--- /dev/null
+<?php
+# PHPlot / contrib / color_range : Test 1, make a picture
+# $Id: color_range.test1.php,v 1.1 2009/12/09 03:45:49 lbayuk Exp $
+# This creates a PNG file on output with a color gradient.
+
+require_once 'color_range.php';
+
+function usage()
+{
+ fwrite(STDERR, "Usage: color_range.test1.php color1 color2 number_of_colors
+Each color is of the form rrggbb with 2 digit hex color components.
+");
+ exit(1);
+}
+
+# Split color "rrggbb" into separate components. Code is from PHPlot.
+function rgb($color)
+{
+ return array(hexdec(substr($color, 1, 2)),
+ hexdec(substr($color, 3, 2)),
+ hexdec(substr($color, 5, 2)));
+}
+
+if ($_SERVER['argc'] != 4) usage();
+
+$color1 = rgb($_SERVER['argv'][1]);
+$color2 = rgb($_SERVER['argv'][2]);
+$n_col = (int)$_SERVER['argv'][3];
+if ($n_col < 2) usage();
+
+# Build a color map from colors[0]=color1 to colors[$n_col-1]=color2.
+$colors = color_range($color1, $color2, $n_col);
+
+# Make a picture:
+$w = 800;
+$h = 800;
+$im = imagecreate($w, $h);
+$background = imagecolorresolve($im, 0, 0, 0);
+for ($col = 0; $col < $n_col; $col++) {
+ list($r, $g, $b) = $colors[$col];
+ $colmap[$col] = imagecolorresolve($im, $r, $g, $b);
+}
+
+$margin = 20;
+$bar_width = (int)(($w - 2 * $margin) / $n_col);
+$x1 = $margin;
+$x2 = $x1 + $bar_width;
+$y1 = $margin;
+$y2 = $h - $margin;
+for ($col = 0; $col < $n_col; $col++) {
+ imagefilledrectangle($im, $x1, $y1, $x2, $y2, $colmap[$col]);
+ $x1 = $x2;
+ $x2 += $bar_width;
+}
+imagepng($im);
--- /dev/null
+<?php
+/*
+ PHPlot / contrib / color_range : Unit tests
+ $Id: color_range.test2.php,v 1.1 2009/12/09 03:45:51 lbayuk Exp $
+
+ Tests color.range.php functions:
+ color_range($color_a, $color_b, $n_steps)
+ count_data_sets($data, $data_type)
+
+*/
+require_once 'color_range.php';
+
+
+# Testing count_data_sets()
+function test_count_data_sets($data, $data_type, $expected)
+{
+ $n = count_data_sets($data, $data_type);
+ if ($n == $expected) $result = "Pass";
+ else $result = "FAIL: Expected $expected but got";
+ echo "$result: $n data sets, $data_type with " . count($data) . " records.\n";
+}
+
+function test_driver_count_data_sets()
+{
+ echo "\nTesting count_data_sets():\n";
+ $data1 = array(array('a', 1, 2, 3), array('b', 2, 2, 3));
+ $data2 = array(array('a', 1, 2, 3, 4, 5, 6, 7), array('b', 2, 4, 5, 6));
+ $data3 = array(array('', 1), array('', 2), array('', 3), array('', 4));
+ $data4 = array(array('', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
+ array('', 1, 2, 3, 4, 5, 6, 7),
+ array('', 1, 2, 3, 4));
+
+ test_count_data_sets($data1, 'text-data', 3);
+ test_count_data_sets($data1, 'data-data', 2);
+ test_count_data_sets($data2, 'data-data-error', 2);
+ test_count_data_sets($data3, 'text-data-single', 4);
+
+ test_count_data_sets($data4, 'text-data', 13);
+ test_count_data_sets($data4, 'data-data', 12);
+ test_count_data_sets($data4, 'data-data-error', 4);
+ test_count_data_sets($data4, 'text-data-single', 3);
+}
+
+# Testing color_range()
+function test_color_range($color1, $color2, $nsteps, $expected)
+{
+ $info = 'From (' . implode(', ', $color1)
+ . ') To (' . implode(', ', $color2) . ") with $nsteps steps";
+
+ $colors = color_range($color1, $color2, $nsteps);
+ if ($colors == $expected) echo "Pass: $info\n";
+ else echo "FAIL: $info\n" . print_r($colors, True) . "\n";
+ if (($n = count($colors)) != $nsteps)
+ echo "FAIL: Bad count $n expecting $nsteps\n";
+}
+
+function test_driver_color_range()
+{
+ echo "\nTesting color_range():\n";
+ test_color_range(array(0,0,0), array(255,255,255), 3,
+ array(array(0,0,0), array(127,127,127), array(255,255,255)));
+
+ test_color_range(array(255,0,0), array(0,255,0), 2,
+ array(array(255,0,0), array(0,255,0)));
+
+ test_color_range(array(100,0,100), array(0,100,0), 6,
+ array(array(100,0,100), array(80,20,80), array(60,40,60),
+ array(40,60,40), array(20,80,20), array(0,100,0)));
+}
+
+
+test_driver_count_data_sets();
+test_driver_color_range();
--- /dev/null
+<?php
+# PHPlot / contrib / prune_labels : Example
+# $Id: prune_labels.example.php,v 1.1 2009/12/09 03:45:53 lbayuk Exp $
+# This produces 250 data points with date-formatted labels, and sets
+# a max of 20 labels to display.
+
+require_once 'phplot.php';
+require_once 'prune_labels.php';
+
+$base = mktime(12, 0, 0, 1, 1, 2000);
+$data = array();
+for ($i = 0; $i < 250; $i++) {
+ $data[] = array(86400 * $i + $base, $i, $i * 0.20);
+}
+
+# Show no more than 20 labels:
+prune_labels($data, 20);
+
+$p = new PHPlot(800, 600);
+$p->SetTitle('Example - pruned data labels');
+$p->SetDataType('data-data');
+$p->SetDataValues($data);
+$p->SetXLabelType('time', '%Y-%m-%d');
+$p->SetXLabelAngle(90);
+$p->SetXDataLabelPos('plotdown');
+$p->SetXTickLabelPos('none');
+$p->SetXTickPos('none');
+$p->SetDrawXGrid(False);
+$p->SetDrawYGrid(False);
+$p->SetPlotType('lines');
+$p->DrawGraph();
--- /dev/null
+<?php
+/*
+ PHPlot / contrib / prune_labels
+ $Id: prune_labels.php,v 1.1 2009/12/09 03:45:55 lbayuk Exp $
+ PHPlot contrib code - public domain - no copyright - use as you wish
+
+Reduce the number of data labels along the X axis, when the density is too
+high. This simply blanks out M-1 of every M labels in the data array.
+There are other ways to do this, but we need to keep the labels uniformly
+spaced. You select the target maximum label count (maxlabels), and you will
+get no more than maxlabels data labels.
+
+ Arguments:
+ $data - The PHPlot data array (reference variable)
+ $maxlabels - The maximum number of data labels you are willing to have,
+ Returns: Nothing
+ Modifies the $data array in place to remove some of the labels.
+
+ Notes:
+ The data array and its rows must be 0-based integer indexed arrays.
+*/
+function prune_labels(&$data, $maxlabels)
+{
+ # Do nothing if there are not already too many labels:
+ if (($n = count($data)) <= $maxlabels) return;
+
+ # Compute how many labels to erase. Keep 1 of every $m labels.
+ $m = (int)ceil($n / $maxlabels);
+
+ # Process the data array, zapping M-1 of every M labels:
+ $k = 0;
+ for ($i = 0; $i < $n; $i++) {
+ if ($k > 0) $data[$i][0] = '';
+ if (++$k >= $m) $k = 0;
+ }
+}
--- /dev/null
+<?php
+# PHPlot / contrib / prune_labels : Test
+# $Id: prune_labels.test.php,v 1.1 2009/12/09 03:45:57 lbayuk Exp $
+# Test driver for contrib / prune_labels
+
+require_once 'prune_labels.php';
+
+/* Testing the prune_labels function: */
+function test($count, $maxlabels)
+{
+ # Make an array of count records, like PHPlot uses, with labels:
+ $data = array();
+ for ($i = 0; $i < $count; $i++) {
+ $data[] = array("Row $i", $i, 100, 200, 300);
+ }
+
+ prune_labels($data, $maxlabels);
+
+ # See how many labels are non-blank now:
+ $line = '';
+ $non_blank = 0;
+ for ($i = 0; $i < $count; $i++) {
+ if (!empty($data[$i][0])) {
+ $non_blank++;
+ $line .= '*';
+ } else {
+ $line .= '_';
+ }
+ }
+ $status = ($non_blank <= $maxlabels) ? 'PASS' : 'FAIL';
+ echo "$status: $count rows, maxlabels=$maxlabels => $non_blank labels\n";
+ echo substr($line, 0, 80) . "\n"; # Only show first 80 chars.
+}
+
+/* Test cases for prune_labels */
+for ($n = 7; $n <= 1000; $n *= 2) test($n, 10);
+for ($g = 5; $g <= 40; $g++) test(72, $g);
+# Edge cases
+test(80, 41);
+test(80, 40);
+test(80, 39);
--- /dev/null
+<?php
+/* $Id: phplot.php,v 1.216 2011/01/16 01:19:55 lbayuk Exp $ */
+/*
+ * PHPLOT Version 5.3.1
+ *
+ * A PHP class for creating scientific and business charts
+ * Visit http://sourceforge.net/projects/phplot/
+ * for PHPlot documentation, downloads, and discussions.
+ * ---------------------------------------------------------------------
+ * Copyright (C) 1998-2011 Afan Ottenheimer
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * ---------------------------------------------------------------------
+ *
+ * Co-author and maintainer (2003-2005)
+ * Miguel de Benito Delgado <nonick AT vodafone DOT es>
+ *
+ * Maintainer (2006-present)
+ * <lbayuk AT users DOT sourceforge DOT net>
+ *
+ * Requires PHP 5.2.x or later. (PHP 4 is unsupported as of Jan 2008)
+ */
+
+class PHPlot
+{
+ /* Declare class variables which are initialized to static values. Many more class variables
+ * are used, defined as needed, but are unset by default.
+ * All these are declared as public. While it is tempting to make them private or protected, this
+ * is avoided for two reasons. First, it will break existing code, since all member variables
+ * were public in PHP4 and who knows what internal variables people used. Second, it makes
+ * testing harder and less effective. Nevertheless, your code should not modify these.
+ */
+
+ public $is_inline = FALSE; // FALSE = Sends headers, TRUE = sends just raw image data
+ public $browser_cache = FALSE; // FALSE = Sends headers for browser to not cache the image,
+ // (only if is_inline = FALSE also)
+ public $print_image = TRUE; // DrawGraph calls PrintImage. See SetPrintImage
+
+ public $safe_margin = 5; // Extra margin used in several places, in pixels
+
+ public $x_axis_position = ''; // X axis position in Y world coordinates, blank for default.
+ public $y_axis_position = ''; // Y axis position in X world coordinates, blank for default.
+
+ public $xscale_type = 'linear'; // linear, log
+ public $yscale_type = 'linear';
+
+//Fonts
+ public $use_ttf = FALSE; // Use True Type Fonts by default?
+ public $ttf_path = '.'; // Default path to look in for TT Fonts.
+ // public $default_ttfont; // Initialized in GetDefaultTTFont
+ public $line_spacing = 4; // Controls line spacing of multi-line labels
+
+ // Label angles: 0 or 90 degrees for fixed fonts, any for TTF
+ public $x_label_angle = 0; // For X tick labels
+ // public $x_data_label_angle; // For X data labels; defaults to x_label_angle - see CheckLabels()
+ public $y_label_angle = 0; // For Y tick labels
+ public $y_data_label_angle = 0; // For Y data labels
+
+//Formats
+ public $file_format = 'png';
+ public $output_file = ''; // For output to a file instead of stdout
+
+//Data
+ public $data_type = 'text-data'; // Structure of the data array
+ public $plot_type = 'linepoints'; // See $plots[] below
+
+ public $label_scale_position = 0.5; // Shifts data labels in pie charts. 1 = top, 0 = bottom
+ public $group_frac_width = 0.7; // Bars use this fraction (0 to 1) of a group's space
+ public $bar_extra_space = 0.5; // Number of extra bar's worth of space in a group
+ public $bar_width_adjust = 1; // 1 = bars of normal width, must be > 0
+
+// Titles
+ public $title_txt = '';
+
+ public $x_title_txt = '';
+ public $x_title_pos = 'none'; // plotdown, plotup, both, none
+
+ public $y_title_txt = '';
+ public $y_title_pos = 'none'; // plotleft, plotright, both, none
+
+//Labels
+ // There are two types of labels in PHPlot:
+ // Tick labels: Follow the grid, next to ticks in axis.
+ // Are drawn at grid drawing time, by DrawXTicks() and DrawYTicks()
+ // Data labels: Follow the data points, and can be placed on the axis or the plot (x/y)
+ // Are drawn at graph plotting time, by Draw*DataLabel(), called by DrawLines(), etc.
+ // DrawXDataLabel() also draws vertical lines to data points, depending on
+ // draw_x_data_label_lines.
+ // Tick Labels
+ // Tick and Data label positions are not initialized, because PHPlot needs to tell if they
+ // defaulted or are set by the user. See CheckLabels() for details. The variables and
+ // effective defaults are shown here in comments (but CheckLabels adjusts the defaults).
+ // public $x_tick_label_pos = 'plotdown'; // X tick label position
+ // public $y_tick_label_pos = 'plotleft'; // Y tick label position
+ // public $x_data_label_pos = 'plotdown'; // X data label position
+ // public $y_data_label_pos = 'none'; // Y data label position
+
+ public $draw_x_data_label_lines = FALSE; // Draw a line from the data point to the axis?
+
+ // Label format controls: (for tick, data and plot labels)
+ // Unset by default, these array members are used as needed for 'x' (x tick labels), 'xd' (x data
+ // labels), 'y' (y tick labels), and 'yd' (y data labels).
+ // type, precision, prefix, suffix, time_format, printf_format, custom_callback, custom_arg.
+ // These replace the former: x_label_type, x_time_format, x_precision (similar for y), data_units_text.
+ public $label_format = array('x' => array(), 'xd' => array(), 'y' => array(), 'yd' => array());
+ // data_units_text is retained for backward compatibility, because there was never a function
+ // to set it. Use the 'suffix' argument to Set[XY]LabelType instead.
+ public $data_units_text = ''; // Units text for 'data' labels (i.e: '¤', '$', etc.)
+
+// Legend
+ public $legend = ''; // An array with legend titles
+ // These variables are unset to take default values:
+ // public $legend_x_pos; // User-specified upper left coordinates of legend box
+ // public $legend_y_pos;
+ // public $legend_xy_world; // If set, legend_x/y_pos are world coords, else pixel coords
+ // public $legend_text_align; // left or right, Unset means right
+ // public $legend_colorbox_align; // left, right, or none; Unset means same as text_align
+
+//Ticks
+ public $x_tick_length = 5; // tick length in pixels for upper/lower axis
+ public $y_tick_length = 5; // tick length in pixels for left/right axis
+
+ public $x_tick_cross = 3; // ticks cross x axis this many pixels
+ public $y_tick_cross = 3; // ticks cross y axis this many pixels
+
+ public $x_tick_pos = 'plotdown'; // plotdown, plotup, both, xaxis, none
+ public $y_tick_pos = 'plotleft'; // plotright, plotleft, both, yaxis, none
+
+ public $num_x_ticks = '';
+ public $num_y_ticks = '';
+
+ public $x_tick_inc = ''; // Set num_x_ticks or x_tick_inc, not both.
+ public $y_tick_inc = ''; // Set num_y_ticks or y_tick_inc, not both.
+
+ public $skip_top_tick = FALSE;
+ public $skip_bottom_tick = FALSE;
+ public $skip_left_tick = FALSE;
+ public $skip_right_tick = FALSE;
+
+//Grid Formatting
+ // public $draw_x_grid = FALSE; // Default is False except for swapped data type
+ // public $draw_y_grid = TRUE; // Default is True except for swapped data type
+
+ public $dashed_grid = TRUE;
+ public $grid_at_foreground = FALSE; // Chooses whether to draw the grid below or above the graph
+
+//Colors and styles (all colors can be array (R,G,B) or named color)
+ public $color_array = 'small'; // 'small', 'large' or array (define your own colors)
+ // See rgb.inc.php and SetRGBArray()
+ public $default_colors = array( // The default colors for data and error bars
+ 'SkyBlue', 'green', 'orange', 'blue', 'red', 'DarkGreen', 'purple', 'peru',
+ 'cyan', 'salmon', 'SlateBlue', 'YellowGreen', 'magenta', 'aquamarine1', 'gold', 'violet');
+
+ // See SetDefaultStyles() for default colors for PHPlot elements.
+
+ public $line_widths = 1; // single value or array
+ public $line_styles = array('solid', 'solid', 'dashed'); // single value or array
+ public $dashed_style = '2-4'; // colored dots-transparent dots
+
+ public $point_sizes = array(6); // Array of sizes for points. See CheckPointParams()
+ public $point_shapes = array( // Array of point shapes. See SetPointShapes() and DrawDot()
+ 'diamond', 'dot', 'delta', 'home', 'yield', 'box', 'circle', 'up', 'down', 'cross'
+ );
+
+ public $error_bar_size = 5; // right and left size of tee
+ public $error_bar_shape = 'tee'; // 'tee' or 'line'
+ public $error_bar_line_width = 1; // single value (or array TODO)
+
+ public $plot_border_type = 'sides'; // left, right, top, bottom, sides, none, full; or array
+ public $image_border_type = 'none'; // 'raised', 'plain', 'none'
+ // public $image_border_width; // NULL, 0, or unset for default. Default depends on type.
+
+ public $shading = 5; // 0 for no shading, > 0 is size of shadows in pixels
+
+ public $draw_plot_area_background = FALSE;
+ public $draw_broken_lines = FALSE; // Tells not to draw lines for missing Y data.
+
+//Miscellaneous
+ public $callbacks = array( // Valid callback reasons (see SetCallBack)
+ 'draw_setup' => NULL,
+ 'draw_image_background' => NULL,
+ 'draw_plotarea_background' => NULL,
+ 'draw_titles' => NULL,
+ 'draw_axes' => NULL,
+ 'draw_graph' => NULL,
+ 'draw_border' => NULL,
+ 'draw_legend' => NULL,
+ 'draw_all' => NULL,
+ 'data_color' => NULL,
+ 'debug_textbox' => NULL, // For testing/debugging text box alignment
+ 'debug_scale' => NULL, // For testing/debugging scale setup
+ );
+
+ // Defined plot types static array:
+ // Array key is the plot type. (Upper case letters are not allowed due to CheckOption)
+ // Value is an array with these keys:
+ // draw_method (required) : Class method to call to draw the plot.
+ // draw_arg : Optional array of arguments to pass to draw_method.
+ // draw_axes : If FALSE, do not draw X/Y axis lines, labels, ticks, grid, titles.
+ // abs_vals, sum_vals : Data array processing flags. See FindDataLimits().
+ static protected $plots = array(
+ 'area' => array(
+ 'draw_method' => 'DrawArea',
+ 'abs_vals' => TRUE,
+ ),
+ 'bars' => array(
+ 'draw_method' => 'DrawBars',
+ ),
+ 'candlesticks' => array(
+ 'draw_method' => 'DrawOHLC',
+ 'draw_arg' => array(TRUE, FALSE), // Draw candlesticks, only fill if "closed down"
+ ),
+ 'candlesticks2' => array(
+ 'draw_method' => 'DrawOHLC',
+ 'draw_arg' => array(TRUE, TRUE), // Draw candlesticks, fill always
+ ),
+ 'linepoints' => array(
+ 'draw_method' => 'DrawLinePoints',
+ ),
+ 'lines' => array(
+ 'draw_method' => 'DrawLines',
+ ),
+ 'ohlc' => array(
+ 'draw_method' => 'DrawOHLC',
+ 'draw_arg' => array(FALSE), // Don't draw candlesticks
+ ),
+ 'pie' => array(
+ 'draw_method' => 'DrawPieChart',
+ 'draw_axes' => FALSE,
+ 'abs_vals' => TRUE,
+ ),
+ 'points' => array(
+ 'draw_method' => 'DrawDots',
+ ),
+ 'squared' => array(
+ 'draw_method' => 'DrawSquared',
+ ),
+ 'stackedarea' => array(
+ 'draw_method' => 'DrawArea',
+ 'draw_arg' => array(TRUE), // Tells DrawArea to draw stacked area plot
+ 'sum_vals' => TRUE,
+ 'abs_vals' => TRUE,
+ ),
+ 'stackedbars' => array(
+ 'draw_method' => 'DrawStackedBars',
+ 'sum_vals' => TRUE,
+ ),
+ 'thinbarline' => array(
+ 'draw_method' => 'DrawThinBarLines',
+ ),
+ );
+
+//////////////////////////////////////////////////////
+//BEGIN CODE
+//////////////////////////////////////////////////////
+
+ /*
+ * Constructor: Setup img resource, colors and size of the image, and font sizes.
+ *
+ * $which_width : Image width in pixels.
+ * $which_height : Image height in pixels.
+ * $which_output_file : Filename for output.
+ * $which_input_file : Path to a file to be used as background.
+ */
+ function PHPlot($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
+ {
+ $this->SetRGBArray($this->color_array);
+
+ if ($which_output_file)
+ $this->SetOutputFile($which_output_file);
+
+ if ($which_input_file) {
+ $this->SetInputFile($which_input_file);
+ } else {
+ $this->image_width = $which_width;
+ $this->image_height = $which_height;
+
+ $this->img = ImageCreate($this->image_width, $this->image_height);
+ if (! $this->img)
+ return $this->PrintError('PHPlot(): Could not create image resource.');
+ }
+
+ $this->SetDefaultStyles();
+ $this->SetDefaultFonts();
+ }
+
+ /*
+ * Reads an image file. Stores width and height, and returns the image
+ * resource. On error, calls PrintError and returns False.
+ * This is used by the constructor via SetInputFile, and by tile_img().
+ */
+ protected function GetImage($image_filename, &$width, &$height)
+ {
+ $error = '';
+ $size = getimagesize($image_filename);
+ if (!$size) {
+ $error = "Unable to query image file $image_filename";
+ } else {
+ $image_type = $size[2];
+ switch ($image_type) {
+ case IMAGETYPE_GIF:
+ $img = @ ImageCreateFromGIF ($image_filename);
+ break;
+ case IMAGETYPE_PNG:
+ $img = @ ImageCreateFromPNG ($image_filename);
+ break;
+ case IMAGETYPE_JPEG:
+ $img = @ ImageCreateFromJPEG ($image_filename);
+ break;
+ default:
+ $error = "Unknown image type ($image_type) for image file $image_filename";
+ break;
+ }
+ }
+ if (empty($error) && !$img) {
+ // getimagesize is OK, but GD won't read it. Maybe unsupported format.
+ $error = "Failed to read image file $image_filename";
+ }
+ if (!empty($error)) {
+ return $this->PrintError("GetImage(): $error");
+ }
+ $width = $size[0];
+ $height = $size[1];
+ return $img;
+ }
+
+ /*
+ * Selects an input file to be used as background for the whole graph.
+ * This resets the graph size to the image's size.
+ * Note: This is used by the constructor. It is deprecated for direct use.
+ */
+ function SetInputFile($which_input_file)
+ {
+ $im = $this->GetImage($which_input_file, $this->image_width, $this->image_height);
+ if (!$im)
+ return FALSE; // GetImage already produced an error message.
+
+ // Deallocate any resources previously allocated
+ if (isset($this->img))
+ imagedestroy($this->img);
+
+ $this->img = $im;
+
+ // Do not overwrite the input file with the background color.
+ $this->done['background'] = TRUE;
+
+ return TRUE;
+ }
+
+/////////////////////////////////////////////
+////////////// COLORS
+/////////////////////////////////////////////
+
+ /*
+ * Allocate a GD color index for a color specified by a 4 component array.
+ * When a color is requested, it is parsed and checked by SetRGBColor, and then saved as an array
+ * of (R,G,B,A) components. At graph drawing time, this function is used to allocate the color.
+ * $color : The color specification as a 4 component array: R, G, B, A.
+ * Returns: A GD color index that can be used when drawing.
+ */
+ protected function GetColorIndex($color)
+ {
+ list($r, $g, $b, $a) = $color;
+ return imagecolorresolvealpha($this->img, $r, $g, $b, $a);
+ }
+
+ /*
+ * Allocate an array of GD color indexes for an array of color specifications.
+ * This is used for the data_colors array, for example.
+ * $color_array : Array of color specifications, each an array of R,G,B,A components.
+ * This must use 0-based sequential integer indexes.
+ * $max_colors : Limit color allocation to no more than this.
+ * Returns an array of GD color indexes.
+ */
+ protected function GetColorIndexArray($color_array, $max_colors)
+ {
+ $n = min(count($color_array), $max_colors);
+ $result = array();
+ for ($i = 0; $i < $n; $i++)
+ $result[] = $this->GetColorIndex($color_array[$i]);
+ return $result;
+ }
+
+ /*
+ * Allocate an array of GD color indexes for darker shades of an array of color specifications.
+ * $color_array : Array of color specifications, each an array of R,G,B,A components.
+ * $max_colors : Limit color allocation to this many colors from the array.
+ * Returns an array of GD color indexes.
+ */
+ protected function GetDarkColorIndexArray($color_array, $max_colors)
+ {
+ $n = min(count($color_array), $max_colors);
+ $result = array();
+ for ($i = 0; $i < $n; $i++)
+ $result[] = $this->GetDarkColorIndex($color_array[$i]);
+ return $result;
+ }
+
+ /*
+ * Allocate a GD color index for a darker shade of a color specified by a 4 component array.
+ * See notes for GetColorIndex() above.
+ * $color : The color specification as a 4 component array: R, G, B, A.
+ * Returns: A GD color index that can be used when drawing.
+ */
+ protected function GetDarkColorIndex($color)
+ {
+ list ($r, $g, $b, $a) = $color;
+ $r = max(0, $r - 0x30);
+ $g = max(0, $g - 0x30);
+ $b = max(0, $b - 0x30);
+ return imagecolorresolvealpha($this->img, $r, $g, $b, $a);
+ }
+
+ /*
+ * Sets/reverts all colors and styles to their defaults.
+ */
+ protected function SetDefaultStyles()
+ {
+ $this->SetDefaultDashedStyle($this->dashed_style);
+ $this->SetImageBorderColor(array(194, 194, 194));
+ $this->SetPlotBgColor('white');
+ $this->SetBackgroundColor('white');
+ $this->SetTextColor('black');
+ $this->SetGridColor('black');
+ $this->SetLightGridColor('gray');
+ $this->SetTickColor('black');
+ $this->SetTitleColor('black');
+ // These functions set up the default colors when called without parameters
+ $this->SetDataColors();
+ $this->SetErrorBarColors();
+ $this->SetDataBorderColors();
+ return TRUE;
+ }
+
+ /*
+ * Set the image background color to $which_color.
+ */
+ function SetBackgroundColor($which_color)
+ {
+ return (bool)($this->bg_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the plot area background color (if enabled) to $which_color.
+ */
+ function SetPlotBgColor($which_color)
+ {
+ return (bool)($this->plot_bg_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the color of the titles (main, X, and Y) to $which_color.
+ * See also SetXTitleColor and SetYTitleColor.
+ */
+ function SetTitleColor($which_color)
+ {
+ return (bool)($this->title_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the color of the X title to $which_color.
+ * This overrides the color set with SetTitleColor.
+ */
+ function SetXTitleColor($which_color)
+ {
+ return (bool)($this->x_title_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the color of the Y title to $which_color.
+ * This overrides the color set with SetTitleColor.
+ */
+ function SetYTitleColor($which_color)
+ {
+ return (bool)($this->y_title_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the color of the axis tick marks to $which_color.
+ */
+ function SetTickColor($which_color)
+ {
+ return (bool)($this->tick_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Deprecated. Use SetTitleColor()
+ */
+ function SetLabelColor($which_color)
+ {
+ return $this->SetTitleColor($which_color);
+ }
+
+ /*
+ * Set the general text color (tick and data labels, legend, etc) to $which_color.
+ */
+ function SetTextColor($which_color)
+ {
+ return (bool)($this->text_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the X and Y grid colors to $which_color. Also sets the data label line color.
+ */
+ function SetLightGridColor($which_color)
+ {
+ return (bool)($this->light_grid_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the color used for the X and Y axis, plot border, legend border to $which_color.
+ * Note: This has nothing to do with the grid, and we don't recall where this name came from.
+ */
+ function SetGridColor($which_color)
+ {
+ return (bool)($this->grid_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Set the color used for the image border to $which_color.
+ */
+ function SetImageBorderColor($which_color)
+ {
+ return (bool)($this->i_border = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Designate color $which_color to be transparent, if supported by the image format.
+ */
+ function SetTransparentColor($which_color)
+ {
+ return (bool)($this->transparent_color = $this->SetRGBColor($which_color));
+ }
+
+ /*
+ * Sets the array of colors to be used. It can be user defined, a small predefined one
+ * or a large one included from 'rgb.inc.php'.
+ *
+ * $which_color_array : A color array, or 'small' or 'large'.
+ * Color arrays map color names into arrays of R, G, B and optionally A values.
+ */
+ function SetRGBArray($which_color_array)
+ {
+ if (is_array($which_color_array)) { // User defined array
+ $this->rgb_array = $which_color_array;
+ } elseif ($which_color_array == 'small') { // Small predefined color array
+ $this->rgb_array = array(
+ 'white' => array(255, 255, 255),
+ 'snow' => array(255, 250, 250),
+ 'PeachPuff' => array(255, 218, 185),
+ 'ivory' => array(255, 255, 240),
+ 'lavender' => array(230, 230, 250),
+ 'black' => array( 0, 0, 0),
+ 'DimGrey' => array(105, 105, 105),
+ 'gray' => array(190, 190, 190),
+ 'grey' => array(190, 190, 190),
+ 'navy' => array( 0, 0, 128),
+ 'SlateBlue' => array(106, 90, 205),
+ 'blue' => array( 0, 0, 255),
+ 'SkyBlue' => array(135, 206, 235),
+ 'cyan' => array( 0, 255, 255),
+ 'DarkGreen' => array( 0, 100, 0),
+ 'green' => array( 0, 255, 0),
+ 'YellowGreen' => array(154, 205, 50),
+ 'yellow' => array(255, 255, 0),
+ 'orange' => array(255, 165, 0),
+ 'gold' => array(255, 215, 0),
+ 'peru' => array(205, 133, 63),
+ 'beige' => array(245, 245, 220),
+ 'wheat' => array(245, 222, 179),
+ 'tan' => array(210, 180, 140),
+ 'brown' => array(165, 42, 42),
+ 'salmon' => array(250, 128, 114),
+ 'red' => array(255, 0, 0),
+ 'pink' => array(255, 192, 203),
+ 'maroon' => array(176, 48, 96),
+ 'magenta' => array(255, 0, 255),
+ 'violet' => array(238, 130, 238),
+ 'plum' => array(221, 160, 221),
+ 'orchid' => array(218, 112, 214),
+ 'purple' => array(160, 32, 240),
+ 'azure1' => array(240, 255, 255),
+ 'aquamarine1' => array(127, 255, 212)
+ );
+ } elseif ($which_color_array == 'large') { // Large color array
+ if (!@include('rgb.inc.php')) {
+ return $this->PrintError("SetRGBArray(): Large color map could not be loaded\n"
+ . "from 'rgb.inc.php'.");
+ }
+ $this->rgb_array = $ColorArray;
+ } else { // Default to black and white only.
+ $this->rgb_array = array('white' => array(255, 255, 255), 'black' => array(0, 0, 0));
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * Parse a color description and return the color component values.
+ * Arguments:
+ * $color_asked : The desired color description, in one of these forms:
+ * Component notation: array(R, G, B) or array(R, G, B, A) with each
+ * in the range described below for the return value.
+ * Examples: (255,255,0) (204,0,0,30)
+ * Hex notation: "#RRGGBB" or "#RRGGBBAA" where each pair is a 2 digit hex number.
+ * Examples: #FF00FF (magenta) #0000FF40 (Blue with alpha=64/127)
+ * Named color in the current colormap, with optional suffix ":alpha" for alpha value.
+ * Examples: blue red:60 yellow:20
+ * $alpha : optional default alpha value. This is applied to the color if it doesn't
+ * already have an alpha value. If not supplied, colors are opaque (alpha=0) by default.
+ *
+ * Returns an array describing a color as (R, G, B, Alpha).
+ * R, G, and B are integers 0-255, and Alpha is 0 (opaque) to 127 (transparent).
+ * Note: This function should be considered 'protected', and is not documented for public use.
+ */
+ function SetRGBColor($color_asked, $alpha = 0)
+ {
+ if (empty($color_asked)) {
+ $ret_val = array(0, 0, 0);
+
+ } elseif (is_array($color_asked) && (($n = count($color_asked)) == 3 || $n == 4) ) {
+ // Already an array of 3 or 4 elements:
+ $ret_val = $color_asked;
+
+ } elseif (preg_match('/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i',
+ $color_asked, $ss)) {
+ // #RRGGBB or #RRGGBBAA notation:
+ $ret_val = array(hexdec($ss[1]), hexdec($ss[2]), hexdec($ss[3]));
+ if (isset($ss[4])) $ret_val[] = hexdec($ss[4]);
+
+ } elseif (isset($this->rgb_array[$color_asked])) {
+ // Color by name:
+ $ret_val = $this->rgb_array[$color_asked];
+
+ } elseif (preg_match('/(.+):([\d]+)$/', $color_asked, $ss)
+ && isset($this->rgb_array[$ss[1]])) {
+ // Color by name with ":alpha" suffix, alpha is a decimal number:
+ $ret_val = $this->rgb_array[$ss[1]];
+ $ret_val[3] = (int)$ss[2];
+
+ } else {
+ return $this->PrintError("SetRGBColor(): Color '$color_asked' is not valid.");
+ }
+
+ // Append alpha if not already provided for:
+ if (count($ret_val) == 3)
+ $ret_val[] = $alpha;
+ return $ret_val;
+ }
+
+ /*
+ * Sets the colors for the data, with optional default alpha value (for PHPlot_truecolor only)
+ * Cases are:
+ * SetDataColors(array(...)) : Use the supplied array as the color map.
+ * SetDataColors(colorname) : Use an array of just colorname as the color map.
+ * SetDataColors() or SetDataColors(NULL) : Load default color map if no color map is already set.
+ * SetDataColors('') or SetDataColors(False) : Load default color map (even if one is already set).
+ * $which_border is passed to SetDataBorderColors, for backward compatibility.
+ * $alpha is a default Alpha to apply to all data colors that do not have alpha.
+ * The default for this is NULL, not 0, so we can tell if it was defaulted. But the effective
+ * default value is 0 (opaque).
+ */
+ function SetDataColors($which_data = NULL, $which_border = NULL, $alpha = NULL)
+ {
+ if (is_array($which_data)) {
+ $colors = $which_data; // Use supplied array
+ } elseif (!empty($which_data)) {
+ $colors = array($which_data); // Use supplied single color
+ } elseif (empty($this->data_colors) || !is_null($which_data)) {
+ $colors = $this->default_colors; // Use default color array
+ } else {
+ // which_data is NULL or missing and a color array is already set.
+ // The existing color array is left alone, except that if $alpha is
+ // given this will replace the alpha value of each existing color.
+ // This makes SetDataColors(NULL, NULL, $alpha) work.
+ if (isset($alpha)) {
+ $n_colors = count($this->data_colors);
+ for ($i = 0; $i < $n_colors; $i++) {
+ $this->data_colors[$i][3] = $alpha; // Component 3 = alpha value
+ }
+ }
+ // No need to reparse the colors or anything else.
+ return TRUE;
+ }
+
+ if (!isset($alpha))
+ $alpha = 0; // Actual default is opaque colors.
+
+ // Check each color and convert to array (r,g,b,a) form.
+ // Use the $alpha argument as a default for the alpha value of each color.
+ $this->data_colors = array();
+ foreach ($colors as $color) {
+ $color_array = $this->SetRGBColor($color, $alpha);
+ if (!$color_array) return FALSE; // SetRGBColor already did an error message.
+ $this->data_colors[] = $color_array;
+ }
+
+ // For past compatibility:
+ return $this->SetDataBorderColors($which_border);
+ }
+
+ /*
+ * Set the colors for the bars and stacked bars outlines.
+ * Argument usage is similar to SetDataColors(), except the default is just black.
+ */
+ function SetDataBorderColors($which_br = NULL)
+ {
+ if (is_array($which_br)) {
+ $colors = $which_br; // Use supplied array
+ } elseif (!empty($which_br)) {
+ $colors = array($which_br); // Use supplied single color
+ } elseif (empty($this->data_border_colors) || !is_null($which_br)) {
+ $colors = array('black'); // Use default
+ } else {
+ return TRUE; // Do nothing: which_br is NULL or missing and a color array is already set.
+ }
+
+ // Check each color and convert to array (r,g,b,a) form.
+ $this->data_border_colors = array();
+ foreach ($colors as $color) {
+ $color_array = $this->SetRGBColor($color);
+ if (!$color_array) return FALSE; // SetRGBColor already did an error message.
+ $this->data_border_colors[] = $color_array;
+ }
+ return TRUE;
+ }
+
+ /*
+ * Sets the colors for the data error bars.
+ * Argument usage is the same as SetDataColors().
+ */
+ function SetErrorBarColors($which_err = NULL)
+ {
+ if (is_array($which_err)) {
+ $colors = $which_err; // Use supplied array
+ } elseif (!empty($which_err)) {
+ $colors = array($which_err); // Use supplied single color
+ } elseif (empty($this->error_bar_colors) || !is_null($which_err)) {
+ $colors = $this->default_colors; // Use default color array
+ } else {
+ return TRUE; // Do nothing: which_err is NULL or missing and a color array is already set.
+ }
+
+ // Check each color and convert to array (r,g,b,a) form.
+ $this->error_bar_colors = array();
+ foreach ($colors as $color) {
+ $color_array = $this->SetRGBColor($color);
+ if (!$color_array) return FALSE; // SetRGBColor already did an error message.
+ $this->error_bar_colors[] = $color_array;
+ }
+ return TRUE;
+ }
+
+ /*
+ * Sets the default dashed line style.
+ * $which_style : A string specifying the dashed line style, as alternating numbers
+ * of the length (in pixels) of lines and spaces, separated by dashes.
+ * For example: '2-3-1-2' means 2 dots of color, 3 transparent, 1 color, then 2 transparent.
+ * This builds a string which will evaluate to an array of integers. Each colored dot
+ * is '$which_ndxcol' and each transparent dot is 'IMG_COLOR_TRANSPARENT'. When SetDashedStyle()
+ * eval's this with $which_ndxcol set, the result is a GD line style array.
+ */
+ function SetDefaultDashedStyle($which_style)
+ {
+ // Explode "numcol-numtrans-numcol-numtrans..." into segment counts:
+ $asked = explode('-', $which_style);
+
+ if (count($asked) < 2) {
+ return $this->PrintError("SetDefaultDashedStyle(): Wrong parameter '$which_style'.");
+ }
+
+ // Build the string to be evaluated later by SetDashedStyle() with $which_ndxcolor set.
+ $result = '';
+ $vals = array('$which_ndxcol,', 'IMG_COLOR_TRANSPARENT,');
+ $index = 0;
+ foreach ($asked as $n) {
+ $result .= str_repeat($vals[$index], $n);
+ $index = 1 - $index;
+ }
+ $this->default_dashed_style = "array($result)";
+
+ return TRUE;
+ }
+
+ /*
+ * Sets the style before drawing a dashed line. Defaults to $this->default_dashed_style
+ * $which_ndxcol : Color index to be used.
+ */
+ protected function SetDashedStyle($which_ndxcol)
+ {
+ // See SetDefaultDashedStyle() to understand this.
+ eval ("\$style = $this->default_dashed_style;");
+ return imagesetstyle($this->img, $style);
+ }
+
+ /*
+ * Set line widths for each data set.
+ * $which_lw : Array of line widths in pixels, or a single value to use for all data sets.
+ */
+ function SetLineWidths($which_lw=NULL)
+ {
+ if (is_array($which_lw)) {
+ $this->line_widths = $which_lw; // Use provided array
+ } elseif (!is_null($which_lw)) {
+ $this->line_widths = array($which_lw); // Convert value to array
+ }
+ return TRUE;
+ }
+
+ /*
+ * Set line style ('solid' or 'dashed') for each data set.
+ * $which_ls : Array of keywords, or a single keyword to use for all data sets.
+ */
+ function SetLineStyles($which_ls=NULL)
+ {
+ if (is_array($which_ls)) {
+ $this->line_styles = $which_ls; // Use provided array
+ } elseif (!is_null($which_ls)) {
+ $this->line_styles = ($which_ls) ? array($which_ls) : array('solid');
+ }
+ return TRUE;
+ }
+
+/////////////////////////////////////////////
+////////////// TEXT and FONTS
+/////////////////////////////////////////////
+
+ /*
+ * Controls the line spacing of multi-line labels.
+ * $which_spc : Line spacing factor for text
+ * For GD text, this is the number of pixels between lines.
+ * For TTF text, it controls line spacing in proportion to the normal
+ * spacing defined by the font.
+ */
+ function SetLineSpacing($which_spc)
+ {
+ $this->line_spacing = $which_spc;
+ return TRUE;
+ }
+
+ /*
+ * Select the default font type to use.
+ * $which_ttf : True to default to TrueType, False to default to GD (fixed) fonts.
+ * This also resets all font settings to the defaults.
+ */
+ function SetUseTTF($which_ttf)
+ {
+ $this->use_ttf = $which_ttf;
+ return $this->SetDefaultFonts();
+ }
+
+ /*
+ * Sets the directory name to look into for TrueType fonts.
+ */
+ function SetTTFPath($which_path)
+ {
+ if (!is_dir($which_path) || !is_readable($which_path)) {
+ return $this->PrintError("SetTTFPath(): $which_path is not a valid path.");
+ }
+ $this->ttf_path = $which_path;
+ return TRUE;
+ }
+
+ /*
+ * Sets the default TrueType font and updates all fonts to that.
+ * The default font might be a full path, or relative to the TTFPath,
+ * so let SetFont check that it exists.
+ * Side effects: Enables use of TrueType fonts as the default font type,
+ * and resets all font settings.
+ */
+ function SetDefaultTTFont($which_font)
+ {
+ $this->default_ttfont = $which_font;
+ return $this->SetUseTTF(TRUE);
+ }
+
+ /*
+ * Return the default TrueType font name. If no default has been set,
+ * this tries some likely candidates for a font which can be loaded.
+ * If it finds one that works, that becomes the default TT font.
+ * If there is no default and it cannot find a working font, it falls
+ * back to the original PHPlot default (which will not likely work either).
+ */
+ protected function GetDefaultTTFont()
+ {
+ if (!isset($this->default_ttfont)) {
+ // No default font yet. Try some common sans-serif fonts.
+ $fonts = array('LiberationSans-Regular.ttf', // For Linux with a correct GD font search path
+ 'Verdana.ttf', 'Arial.ttf', 'Helvetica.ttf', // For Windows, maybe others
+ 'ttf-liberation/LiberationSans-Regular.ttf', // For Debian, Ubuntu, and friends
+ 'benjamingothic.ttf', // Original PHPlot default
+ );
+ foreach ($fonts as $font) {
+ // First try the font name alone, to see if GD can find and load it.
+ if (@imagettfbbox(10, 0, $font, "1") !== False)
+ break;
+ // If the font wasn't found, try it with the default TTF path in front.
+ $font_with_path = $this->ttf_path . DIRECTORY_SEPARATOR . $font;
+ if (@imagettfbbox(10, 0, $font_with_path, "1") !== False) {
+ $font = $font_with_path;
+ break;
+ }
+ }
+ // We either have a working font, or are using the last one regardless.
+ $this->default_ttfont = $font;
+ }
+ return $this->default_ttfont;
+ }
+
+ /*
+ * Sets fonts to their defaults
+ */
+ protected function SetDefaultFonts()
+ {
+ // TTF:
+ if ($this->use_ttf) {
+ return $this->SetFont('generic', '', 8)
+ && $this->SetFont('title', '', 14)
+ && $this->SetFont('legend', '', 8)
+ && $this->SetFont('x_label', '', 6)
+ && $this->SetFont('y_label', '', 6)
+ && $this->SetFont('x_title', '', 10)
+ && $this->SetFont('y_title', '', 10);
+ }
+ // Fixed GD Fonts:
+ return $this->SetFont('generic', 2)
+ && $this->SetFont('title', 5)
+ && $this->SetFont('legend', 2)
+ && $this->SetFont('x_label', 1)
+ && $this->SetFont('y_label', 1)
+ && $this->SetFont('x_title', 3)
+ && $this->SetFont('y_title', 3);
+ }
+
+ /*
+ * Select a fixed (GD) font for an element.
+ * This allows using a fixed font, even with SetUseTTF(True).
+ * $which_elem : The element whose font is to be changed.
+ * One of: title legend generic x_label y_label x_title y_title
+ * $which_font : A GD font number 1-5
+ * $which_spacing (optional) : Line spacing factor
+ */
+ function SetFontGD($which_elem, $which_font, $which_spacing = NULL)
+ {
+ if ($which_font < 1 || 5 < $which_font) {
+ return $this->PrintError(__FUNCTION__ . ': Font size must be 1, 2, 3, 4 or 5');
+ }
+ if (!$this->CheckOption($which_elem,
+ 'generic, title, legend, x_label, y_label, x_title, y_title',
+ __FUNCTION__)) {
+ return FALSE;
+ }
+
+ // Store the font parameters: name/size, char cell height and width.
+ $this->fonts[$which_elem] = array('ttf' => FALSE,
+ 'font' => $which_font,
+ 'height' => ImageFontHeight($which_font),
+ 'width' => ImageFontWidth($which_font),
+ 'line_spacing' => $which_spacing);
+ return TRUE;
+ }
+
+ /*
+ * Select a TrueType font for an element.
+ * This allows using a TrueType font, even with SetUseTTF(False).
+ * $which_elem : The element whose font is to be changed.
+ * One of: title legend generic x_label y_label x_title y_title
+ * $which_font : A TrueType font filename or pathname.
+ * $which_size : Font point size.
+ * $which_spacing (optional) : Line spacing factor
+ */
+ function SetFontTTF($which_elem, $which_font, $which_size = 12, $which_spacing = NULL)
+ {
+ if (!$this->CheckOption($which_elem,
+ 'generic, title, legend, x_label, y_label, x_title, y_title',
+ __FUNCTION__)) {
+ return FALSE;
+ }
+
+ // Empty font name means use the default font.
+ if (empty($which_font))
+ $which_font = $this->GetDefaultTTFont();
+ $path = $which_font;
+
+ // First try the font name directly, if not then try with path.
+ // Use GD imagettfbbox() to determine if this is a valid font.
+ // The return $bbox is used below, if valid.
+ if (($bbox = @imagettfbbox($which_size, 0, $path, "E")) === False) {
+ $path = $this->ttf_path . DIRECTORY_SEPARATOR . $which_font;
+ if (($bbox = @imagettfbbox($which_size, 0, $path, "E")) === False) {
+ return $this->PrintError(__FUNCTION__ . ": Can't find TrueType font $which_font");
+ }
+ }
+
+ // Calculate the font height and inherent line spacing. TrueType fonts have this information
+ // internally, but PHP/GD has no way to directly access it. So get the bounding box size of
+ // an upper-case character without descenders, and the baseline-to-baseline height.
+ // Note: In practice, $which_size = $height, maybe +/-1 . But which_size is in points,
+ // and height is in pixels, and someday GD may be able to tell the difference.
+ // The character width is saved too, but not used by the normal text drawing routines - it
+ // isn't necessarily a fixed-space font. It is used in DrawLegend.
+ $height = $bbox[1] - $bbox[5];
+ $width = $bbox[2] - $bbox[0];
+ $bbox = ImageTTFBBox($which_size, 0, $path, "E\nE");
+ $spacing = $bbox[1] - $bbox[5] - 2 * $height;
+
+ // Store the font parameters:
+ $this->fonts[$which_elem] = array('ttf' => TRUE,
+ 'font' => $path,
+ 'size' => $which_size,
+ 'height' => $height,
+ 'width' => $width,
+ 'spacing' => $spacing,
+ 'line_spacing' => $which_spacing);
+ return TRUE;
+ }
+
+ /*
+ * Select Fixed/TrueType font for an element. Which type of font is
+ * selected depends on the $use_ttf class variable (see SetUseTTF()).
+ * Before PHPlot supported mixing font types, only this function and
+ * SetUseTTF were available to select an overall font type, but now
+ * SetFontGD() and SetFontTTF() can be used for mixing font types.
+ * $which_elem : The element whose font is to be changed.
+ * One of: title legend generic x_label y_label x_title y_title
+ * $which_font : A number 1-5 for fixed fonts, or a TrueType font.
+ * $which_size : Ignored for Fixed fonts, point size for TrueType.
+ * $which_spacing (optional) : Line spacing factor
+ */
+ function SetFont($which_elem, $which_font, $which_size = 12, $line_spacing = NULL)
+ {
+ if ($this->use_ttf)
+ return $this->SetFontTTF($which_elem, $which_font, $which_size, $line_spacing);
+ return $this->SetFontGD($which_elem, $which_font, $line_spacing);
+ }
+
+ /*
+ * Return the inter-line spacing for a font.
+ * This is an internal function, used by ProcessText* and DrawLegend.
+ * $font : A font array variable.
+ * Returns: Spacing, in pixels, between text lines.
+ */
+ protected function GetLineSpacing($font)
+ {
+ // Use the per-font line spacing preference, if set, else the global value:
+ if (isset($font['line_spacing']))
+ $line_spacing = $font['line_spacing'];
+ else
+ $line_spacing = $this->line_spacing;
+
+ // For GD fonts, that is the spacing in pixels.
+ // For TTF, adjust based on the 'natural' font spacing (see SetFontTTF):
+ if ($font['ttf']) {
+ $line_spacing = (int)($line_spacing * $font['spacing'] / 6.0);
+ }
+ return $line_spacing;
+ }
+
+ /*
+ * Text drawing and sizing functions:
+ * ProcessText is meant for use only by DrawText and SizeText.
+ * ProcessText(True, ...) - Draw a block of text
+ * ProcessText(False, ...) - Just return ($width, $height) of
+ * the orthogonal bounding box containing the text.
+ * ProcessText is further split into separate functions for GD and TTF
+ * text, due to the size of the code.
+ *
+ * Horizontal and vertical alignment are relative to the drawing. That is:
+ * vertical text (90 deg) gets centered along Y position with
+ * v_align = 'center', and adjusted to the right of X position with
+ * h_align = 'right'. Another way to look at this is to say
+ * that text rotation happens first, then alignment.
+ *
+ * Original multiple lines code submitted by Remi Ricard.
+ * Original vertical code submitted by Marlin Viss.
+ *
+ * Text routines rewritten by ljb to fix alignment and position problems.
+ * Here is my explanation and notes. More information and pictures will be
+ * placed in the PHPlot Reference Manual.
+ *
+ * + Process TTF text one line at a time, not as a block. (See below)
+ * + Flipped top vs bottom vertical alignment. The usual interpretation
+ * is: bottom align means bottom of the text is at the specified Y
+ * coordinate. For some reason, PHPlot did left/right the correct way,
+ * but had top/bottom reversed. I fixed it, and left the default valign
+ * argument as bottom, but the meaning of the default value changed.
+ *
+ * For GD font text, only single-line text is handled by GD, and the
+ * basepoint is the upper left corner of each text line.
+ * For TTF text, multi-line text could be handled by GD, with the text
+ * basepoint at the lower left corner of the first line of text.
+ * (Behavior of TTF drawing routines on multi-line text is not documented.)
+ * But you cannot do left/center/right alignment on each line that way,
+ * or proper line spacing.
+ * Therefore, for either text type, we have to break up the text into
+ * lines and position each line independently.
+ *
+ * There are 9 alignment modes: Horizontal = left, center, or right, and
+ * Vertical = top, center, or bottom. Alignment is interpreted relative to
+ * the image, not as the text is read. This makes sense when you consider
+ * for example X axis labels. They need to be centered below the marks
+ * (center, top alignment) regardless of the text angle.
+ * 'Bottom' alignment really means baseline alignment.
+ *
+ * GD font text is supported (by libgd) at 0 degrees and 90 degrees only.
+ * Multi-line or single line text works with any of the 9 alignment modes.
+ *
+ * TTF text can be at any angle. The 9 alignment modes work for all angles,
+ * but the results might not be what you expect for multi-line text. See
+ * the PHPlot Reference Manual for pictures and details. In short, alignment
+ * applies to the orthogonal (aligned with X and Y axes) bounding box that
+ * contains the text, and to each line in the multi-line text box. Since
+ * alignment is relative to the image, 45 degree multi-line text aligns
+ * differently from 46 degree text.
+ *
+ * Note that PHPlot allows multi-line text for the 3 titles, and they
+ * are only drawn at 0 degrees (main and X titles) or 90 degrees (Y title).
+ * Data labels can also be multi-line, and they can be drawn at any angle.
+ * -ljb 2007-11-03
+ *
+ */
+
+ /*
+ * ProcessTextGD() - Draw or size GD fixed-font text.
+ * This is intended for use only by ProcessText().
+ * $draw_it : True to draw the text, False to just return the orthogonal width and height.
+ * $font : PHPlot font array (with 'ttf' = False) - see SetFontGD()
+ * $angle : Text angle in degrees. GD only supports 0 and 90. We treat >= 45 as 90, else 0.
+ * $x, $y : Reference point for the text (ignored if !$draw_it)
+ * $color : GD color index to use for drawing the text (ignored if !$draw_it)
+ * $text : The text to draw or size. Put a newline between lines.
+ * $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it)
+ * $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it)
+ * Returns: True, if drawing text, or an array of ($width, $height) if not.
+ */
+ protected function ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor)
+ {
+ // Extract font parameters:
+ $font_number = $font['font'];
+ $font_width = $font['width'];
+ $font_height = $font['height'];
+ $line_spacing = $this->GetLineSpacing($font);
+
+ // Break up the text into lines, trim whitespace, find longest line.
+ // Save the lines and length for drawing below.
+ $longest = 0;
+ foreach (explode("\n", $text) as $each_line) {
+ $lines[] = $line = trim($each_line);
+ $line_lens[] = $line_len = strlen($line);
+ if ($line_len > $longest) $longest = $line_len;
+ }
+ $n_lines = count($lines);
+
+ // Width, height are based on font size and longest line, line count respectively.
+ // These are relative to the text angle.
+ $total_width = $longest * $font_width;
+ $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing;
+
+ if (!$draw_it) {
+ if ($angle < 45) return array($total_width, $total_height);
+ return array($total_height, $total_width);
+ }
+
+ $interline_step = $font_height + $line_spacing; // Line-to-line step
+
+ if ($angle >= 45) {
+ // Vertical text (90 degrees):
+ // (Remember the alignment convention with vertical text)
+ // For 90 degree text, alignment factors change like this:
+ $temp = $v_factor;
+ $v_factor = $h_factor;
+ $h_factor = 1 - $temp;
+
+ $draw_func = 'ImageStringUp';
+
+ // Rotation matrix "R" for 90 degrees (with Y pointing down):
+ $r00 = 0; $r01 = 1;
+ $r10 = -1; $r11 = 0;
+
+ } else {
+ // Horizontal text (0 degrees):
+ $draw_func = 'ImageString';
+
+ // Rotation matrix "R" for 0 degrees:
+ $r00 = 1; $r01 = 0;
+ $r10 = 0; $r11 = 1;
+ }
+
+ // Adjust for vertical alignment (horizontal text) or horizontal alignment (vertical text):
+ $factor = (int)($total_height * $v_factor);
+ $xpos = $x - $r01 * $factor;
+ $ypos = $y - $r11 * $factor;
+
+ // Debug callback provides the bounding box:
+ if ($this->GetCallback('debug_textbox')) {
+ if ($angle >= 45) {
+ $bbox_width = $total_height;
+ $bbox_height = $total_width;
+ $px = $xpos;
+ $py = $ypos - (1 - $h_factor) * $total_width;
+ } else {
+ $bbox_width = $total_width;
+ $bbox_height = $total_height;
+ $px = $xpos - $h_factor * $total_width;
+ $py = $ypos;
+ }
+ $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height);
+ }
+
+ for ($i = 0; $i < $n_lines; $i++) {
+
+ // Adjust for alignment of this line within the text block:
+ $factor = (int)($line_lens[$i] * $font_width * $h_factor);
+ $x = $xpos - $r00 * $factor;
+ $y = $ypos - $r10 * $factor;
+
+ // Call ImageString or ImageStringUp:
+ $draw_func($this->img, $font_number, $x, $y, $lines[$i], $color);
+
+ // Step to the next line of text. This is a rotation of (x=0, y=interline_spacing)
+ $xpos += $r01 * $interline_step;
+ $ypos += $r11 * $interline_step;
+ }
+ return TRUE;
+ }
+
+ /*
+ * ProcessTextTTF() - Draw or size TTF text.
+ * This is intended for use only by ProcessText().
+ * $draw_it : True to draw the text, False to just return the orthogonal width and height.
+ * $font : PHPlot font array (with 'ttf' = True) - see SetFontTTF()
+ * $angle : Text angle in degrees.
+ * $x, $y : Reference point for the text (ignored if !$draw_it)
+ * $color : GD color index to use for drawing the text (ignored if !$draw_it)
+ * $text : The text to draw or size. Put a newline between lines.
+ * $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it)
+ * $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it)
+ * Returns: True, if drawing text, or an array of ($width, $height) if not.
+ */
+ protected function ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor)
+ {
+ // Extract font parameters (see SetFontTTF):
+ $font_file = $font['font'];
+ $font_size = $font['size'];
+ $font_height = $font['height'];
+ $line_spacing = $this->GetLineSpacing($font);
+
+ // Break up the text into lines, trim whitespace.
+ // Calculate the total width and height of the text box at 0 degrees.
+ // Save the trimmed lines and their widths for later when drawing.
+ // To get uniform spacing, don't use the actual line heights.
+ // Total height = Font-specific line heights plus inter-line spacing.
+ // Total width = width of widest line.
+ // Last Line Descent is the offset from the bottom to the text baseline.
+ // Note: For some reason, ImageTTFBBox uses (-1,-1) as the reference point.
+ // So 1+bbox[1] is the baseline to bottom distance.
+ $total_width = 0;
+ $lastline_descent = 0;
+ foreach (explode("\n", $text) as $each_line) {
+ $lines[] = $line = trim($each_line);
+ $bbox = ImageTTFBBox($font_size, 0, $font_file, $line);
+ $line_widths[] = $width = $bbox[2] - $bbox[0];
+ if ($width > $total_width) $total_width = $width;
+ $lastline_descent = 1 + $bbox[1];
+ }
+ $n_lines = count($lines);
+ $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing;
+
+ // Calculate the rotation matrix for the text's angle. Remember that GD points Y down,
+ // so the sin() terms change sign.
+ $theta = deg2rad($angle);
+ $cos_t = cos($theta);
+ $sin_t = sin($theta);
+ $r00 = $cos_t; $r01 = $sin_t;
+ $r10 = -$sin_t; $r11 = $cos_t;
+
+ // Make a bounding box of the right size, with upper left corner at (0,0).
+ // By convention, the point order is: LL, LR, UR, UL.
+ // Note this is still working with the text at 0 degrees.
+ // When sizing text (SizeText), use the overall size with descenders.
+ // This tells the caller how much room to leave for the text.
+ // When drawing text (DrawText), use the size without descenders - that
+ // is, down to the baseline. This is for accurate positioning.
+ $b[0] = 0;
+ if ($draw_it) {
+ $b[1] = $total_height;
+ } else {
+ $b[1] = $total_height + $lastline_descent;
+ }
+ $b[2] = $total_width; $b[3] = $b[1];
+ $b[4] = $total_width; $b[5] = 0;
+ $b[6] = 0; $b[7] = 0;
+
+ // Rotate the bounding box, then offset to the reference point:
+ for ($i = 0; $i < 8; $i += 2) {
+ $x_b = $b[$i];
+ $y_b = $b[$i+1];
+ $c[$i] = $x + $r00 * $x_b + $r01 * $y_b;
+ $c[$i+1] = $y + $r10 * $x_b + $r11 * $y_b;
+ }
+
+ // Get an orthogonal (aligned with X and Y axes) bounding box around it, by
+ // finding the min and max X and Y:
+ $bbox_ref_x = $bbox_max_x = $c[0];
+ $bbox_ref_y = $bbox_max_y = $c[1];
+ for ($i = 2; $i < 8; $i += 2) {
+ $x_b = $c[$i];
+ if ($x_b < $bbox_ref_x) $bbox_ref_x = $x_b;
+ elseif ($bbox_max_x < $x_b) $bbox_max_x = $x_b;
+ $y_b = $c[$i+1];
+ if ($y_b < $bbox_ref_y) $bbox_ref_y = $y_b;
+ elseif ($bbox_max_y < $y_b) $bbox_max_y = $y_b;
+ }
+ $bbox_width = $bbox_max_x - $bbox_ref_x;
+ $bbox_height = $bbox_max_y - $bbox_ref_y;
+
+ if (!$draw_it) {
+ // Return the bounding box, rounded up (so it always contains the text):
+ return array((int)ceil($bbox_width), (int)ceil($bbox_height));
+ }
+
+ $interline_step = $font_height + $line_spacing; // Line-to-line step
+
+ // Calculate the offsets from the supplied reference point to the
+ // upper-left corner of the text.
+ // Start at the reference point at the upper left corner of the bounding
+ // box (bbox_ref_x, bbox_ref_y) then adjust it for the 9 point alignment.
+ // h,v_factor are 0,0 for top,left, .5,.5 for center,center, 1,1 for bottom,right.
+ // $off_x = $bbox_ref_x + $bbox_width * $h_factor - $x;
+ // $off_y = $bbox_ref_y + $bbox_height * $v_factor - $y;
+ // Then use that offset to calculate back to the supplied reference point x, y
+ // to get the text base point.
+ // $qx = $x - $off_x;
+ // $qy = $y - $off_y;
+ // Reduces to:
+ $qx = 2 * $x - $bbox_ref_x - $bbox_width * $h_factor;
+ $qy = 2 * $y - $bbox_ref_y - $bbox_height * $v_factor;
+
+ // Check for debug callback. Don't calculate bounding box unless it is wanted.
+ if ($this->GetCallback('debug_textbox')) {
+ // Calculate the orthogonal bounding box coordinates for debug testing.
+
+ // qx, qy is upper left corner relative to the text.
+ // Calculate px,py: upper left corner (absolute) of the bounding box.
+ // There are 4 equation sets for this, depending on the quadrant:
+ if ($sin_t > 0) {
+ if ($cos_t > 0) {
+ // Quadrant: 0d - 90d:
+ $px = $qx; $py = $qy - $total_width * $sin_t;
+ } else {
+ // Quadrant: 90d - 180d:
+ $px = $qx + $total_width * $cos_t; $py = $qy - $bbox_height;
+ }
+ } else {
+ if ($cos_t < 0) {
+ // Quadrant: 180d - 270d:
+ $px = $qx - $bbox_width; $py = $qy + $total_height * $cos_t;
+ } else {
+ // Quadrant: 270d - 360d:
+ $px = $qx + $total_height * $sin_t; $py = $qy;
+ }
+ }
+ $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height);
+ }
+
+ // Since alignment is applied after rotation, which parameter is used
+ // to control alignment of each line within the text box varies with
+ // the angle.
+ // Angle (degrees): Line alignment controlled by:
+ // -45 < angle <= 45 h_align
+ // 45 < angle <= 135 reversed v_align
+ // 135 < angle <= 225 reversed h_align
+ // 225 < angle <= 315 v_align
+ if ($cos_t >= $sin_t) {
+ if ($cos_t >= -$sin_t) $line_align_factor = $h_factor;
+ else $line_align_factor = $v_factor;
+ } else {
+ if ($cos_t >= -$sin_t) $line_align_factor = 1-$v_factor;
+ else $line_align_factor = 1-$h_factor;
+ }
+
+ // Now we have the start point, spacing and in-line alignment factor.
+ // We are finally ready to start drawing the text, line by line.
+ for ($i = 0; $i < $n_lines; $i++) {
+
+ // For drawing TTF text, the reference point is the left edge of the
+ // text baseline (not the lower left corner of the bounding box).
+ // The following also adjusts for horizontal (relative to
+ // the text) alignment of the current line within the box.
+ // What is happening is rotation of this vector by the text angle:
+ // (x = (total_width - line_width) * factor, y = font_height)
+
+ $width_factor = ($total_width - $line_widths[$i]) * $line_align_factor;
+ $rx = $qx + $r00 * $width_factor + $r01 * $font_height;
+ $ry = $qy + $r10 * $width_factor + $r11 * $font_height;
+
+ // Finally, draw the text:
+ ImageTTFText($this->img, $font_size, $angle, $rx, $ry, $color, $font_file, $lines[$i]);
+
+ // Step to position of next line.
+ // This is a rotation of (x=0,y=height+line_spacing) by $angle:
+ $qx += $r01 * $interline_step;
+ $qy += $r11 * $interline_step;
+ }
+ return TRUE;
+ }
+
+ /*
+ * ProcessText() - Wrapper for ProcessTextTTF() and ProcessTextGD(). See notes above.
+ * This is intended for use from within PHPlot only, and only by DrawText() and SizeText().
+ * $draw_it : True to draw the text, False to just return the orthogonal width and height.
+ * $font : PHPlot font array, or NULL or empty string to use 'generic'
+ * $angle : Text angle in degrees
+ * $x, $y : Reference point for the text (ignored if !$draw_it)
+ * $color : GD color index to use for drawing the text (ignored if !$draw_it)
+ * $text : The text to draw or size. Put a newline between lines.
+ * $halign : Horizontal alignment: left, center, or right (ignored if !$draw_it)
+ * $valign : Vertical alignment: top, center, or bottom (ignored if !$draw_it)
+ * Note: Alignment is relative to the image, not the text.
+ * Returns: True, if drawing text, or an array of ($width, $height) if not.
+ */
+ protected function ProcessText($draw_it, $font, $angle, $x, $y, $color, $text, $halign, $valign)
+ {
+ // Empty text case:
+ if ($text === '') {
+ if ($draw_it) return TRUE;
+ return array(0, 0);
+ }
+
+ // Calculate width and height offset factors using the alignment args:
+ if ($valign == 'top') $v_factor = 0;
+ elseif ($valign == 'center') $v_factor = 0.5;
+ else $v_factor = 1.0; // 'bottom'
+ if ($halign == 'left') $h_factor = 0;
+ elseif ($halign == 'center') $h_factor = 0.5;
+ else $h_factor = 1.0; // 'right'
+
+ // Apply a default font. This is mostly for external (callback) users.
+ if (empty($font)) $font = $this->fonts['generic'];
+
+ if ($font['ttf']) {
+ return $this->ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text,
+ $h_factor, $v_factor);
+ }
+ return $this->ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor);
+ }
+
+ /*
+ * Draws a block of text. See comments above before ProcessText().
+ * $which_font : PHPlot font array, or NULL or empty string to use 'generic'
+ * $which_angle : Text angle in degrees
+ * $which_xpos, $which_ypos: Reference point for the text
+ * $which_color : GD color index to use for drawing the text
+ * $which_text : The text to draw, with newlines (\n) between lines.
+ * $which_halign : Horizontal (relative to the image) alignment: left, center, or right.
+ * $which_valign : Vertical (relative to the image) alignment: top, center, or bottom.
+ * Note: This function should be considered 'protected', and is not documented for public use.
+ */
+ function DrawText($which_font, $which_angle, $which_xpos, $which_ypos, $which_color, $which_text,
+ $which_halign = 'left', $which_valign = 'bottom')
+ {
+ return $this->ProcessText(TRUE,
+ $which_font, $which_angle, $which_xpos, $which_ypos,
+ $which_color, $which_text, $which_halign, $which_valign);
+ }
+
+ /*
+ * Returns the size of block of text. This is the orthogonal width and height of a bounding
+ * box aligned with the X and Y axes of the text. Only for angle=0 is this the actual
+ * width and height of the text block, but for any angle it is the amount of space needed
+ * to contain the text.
+ * $which_font : PHPlot font array, or NULL or empty string to use 'generic'
+ * $which_angle : Text angle in degrees
+ * $which_text : The text to draw, with newlines (\n) between lines.
+ * Returns a two element array with: $width, $height.
+ * This is just a wrapper for ProcessText() - see above.
+ * Note: This function should be considered 'protected', and is not documented for public use.
+ */
+ function SizeText($which_font, $which_angle, $which_text)
+ {
+ // Color, position, and alignment are not used when calculating the size.
+ return $this->ProcessText(FALSE,
+ $which_font, $which_angle, 0, 0, 1, $which_text, '', '');
+ }
+
+/////////////////////////////////////////////
+/////////// INPUT / OUTPUT CONTROL
+/////////////////////////////////////////////
+
+ /*
+ * Sets output file format to $format (jpg, png, ...)
+ */
+ function SetFileFormat($format)
+ {
+ $asked = $this->CheckOption($format, 'jpg, png, gif, wbmp', __FUNCTION__);
+ if (!$asked) return FALSE;
+ switch ($asked) {
+ case 'jpg':
+ $format_test = IMG_JPG;
+ break;
+ case 'png':
+ $format_test = IMG_PNG;
+ break;
+ case 'gif':
+ $format_test = IMG_GIF;
+ break;
+ case 'wbmp':
+ $format_test = IMG_WBMP;
+ break;
+ }
+ if (!(imagetypes() & $format_test)) {
+ return $this->PrintError("SetFileFormat(): File format '$format' not supported");
+ }
+ $this->file_format = $asked;
+ return TRUE;
+ }
+
+ /*
+ * Selects an input file to be used as graph background and scales or tiles this image
+ * to fit the sizes.
+ * $input_file : Path to the file to be used (jpeg, png and gif accepted)
+ * $mode : 'centeredtile', 'tile', or 'scale' (the image to the graph's size)
+ */
+ function SetBgImage($input_file, $mode='centeredtile')
+ {
+ $this->bgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
+ $this->bgimg = $input_file;
+ return (boolean)$this->bgmode;
+ }
+
+ /*
+ * Selects an input file to be used as plot area background and scales or tiles this image
+ * to fit the sizes.
+ * $input_file : Path to the file to be used (jpeg, png and gif accepted)
+ * $mode : 'centeredtile', 'tile', or 'scale' (the image to the graph's size)
+ */
+ function SetPlotAreaBgImage($input_file, $mode='tile')
+ {
+ $this->plotbgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__);
+ $this->plotbgimg = $input_file;
+ return (boolean)$this->plotbgmode;
+ }
+
+ /*
+ * Sets the name of the file to be used as output file.
+ */
+ function SetOutputFile($which_output_file)
+ {
+ $this->output_file = $which_output_file;
+ return TRUE;
+ }
+
+ /*
+ * Sets the output image as 'inline', that is: no Content-Type headers are sent
+ * to the browser. Needed if you want to embed the images.
+ */
+ function SetIsInline($which_ii)
+ {
+ $this->is_inline = (bool)$which_ii;
+ return TRUE;
+ }
+
+ /*
+ * Performs the actual outputting of the generated graph.
+ */
+ function PrintImage()
+ {
+ // Browser cache stuff submitted by Thiemo Nagel
+ if ( (! $this->browser_cache) && (! $this->is_inline)) {
+ header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT');
+ header('Cache-Control: no-cache, must-revalidate');
+ header('Pragma: no-cache');
+ }
+
+ switch ($this->file_format) {
+ case 'png':
+ $mime_type = 'image/png';
+ $output_f = 'imagepng';
+ break;
+ case 'jpg':
+ $mime_type = 'image/jpeg';
+ $output_f = 'imagejpeg';
+ break;
+ case 'gif':
+ $mime_type = 'image/gif';
+ $output_f = 'imagegif';
+ break;
+ case 'wbmp':
+ $mime_type = 'image/wbmp';
+ $output_f = 'imagewbmp';
+ break;
+ default:
+ return $this->PrintError('PrintImage(): Please select an image type!');
+ }
+ if (!$this->is_inline) {
+ Header("Content-type: $mime_type");
+ }
+ if ($this->is_inline && $this->output_file != '') {
+ $output_f($this->img, $this->output_file);
+ } else {
+ $output_f($this->img);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Error handling for 'fatal' errors:
+ * $error_message Text of the error message
+ * Standard output from PHPlot is expected to be an image file, such as
+ * when handling an <img> tag browser request. So it is not permitted to
+ * output text to standard output. (You should have display_errors=off)
+ * Here is how PHPlot handles fatal errors:
+ * + Write the error message into an image, and output the image.
+ * + If no image can be output, write nothing and produce an HTTP
+ * error header.
+ * + Trigger a user-level error containing the error message.
+ * If no error handler was set up, the script will log the
+ * error and exit with non-zero status.
+ *
+ * PrintError() and DrawError() are now equivalent. Both are provided for
+ * compatibility. (In earlier releases, PrintError sent the message to
+ * stdout only, and DrawError sent it in an image only.)
+ *
+ * This function does not return, unless the calling script has set up
+ * an error handler which does not exit. In that case, PrintError will
+ * return False. But not all of PHPlot will handle this correctly, so
+ * it is probably a bad idea for an error handler to return.
+ */
+ protected function PrintError($error_message)
+ {
+ // Be sure not to loop recursively, e.g. PrintError - PrintImage - PrintError.
+ if (isset($this->in_error)) return FALSE;
+ $this->in_error = TRUE;
+
+ // Output an image containing the error message:
+ if (!empty($this->img)) {
+ $ypos = $this->image_height/2;
+ $xpos = $this->image_width/2;
+ $bgcolor = ImageColorResolve($this->img, 255, 255, 255);
+ $fgcolor = ImageColorResolve($this->img, 0, 0, 0);
+ ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height, $bgcolor);
+
+ // Switch to built-in fonts, in case of error with TrueType fonts:
+ $this->SetUseTTF(FALSE);
+
+ $this->DrawText($this->fonts['generic'], 0, $xpos, $ypos, $fgcolor,
+ wordwrap($error_message), 'center', 'center');
+
+ $this->PrintImage();
+ } elseif (! $this->is_inline) {
+ Header('HTTP/1.0 500 Internal Server Error');
+ }
+ trigger_error($error_message, E_USER_ERROR);
+ unset($this->in_error);
+ return FALSE; // In case error handler returns, rather than doing exit().
+ }
+
+ /*
+ * Display an error message and exit.
+ * This is provided for backward compatibility only. Use PrintError() instead.
+ * $error_message Text of the error message
+ * $where_x, $where_y Ignored, provided for compatibility.
+ */
+ protected function DrawError($error_message, $where_x = NULL, $where_y = NULL)
+ {
+ return $this->PrintError($error_message);
+ }
+
+/////////////////////////////////////////////
+/////////// LABELS
+/////////////////////////////////////////////
+
+ /*
+ * Sets position for X data labels.
+ * For vertical plots, these are X axis data labels, showing label strings from the data array.
+ * Accepted positions are: plotdown, plotup, both, none.
+ * For horizontal plots (bar, stackedbar only), these are X data value labels, show the data values.
+ * Accepted positions are: plotin, plotstack, none.
+ */
+ function SetXDataLabelPos($which_xdlp)
+ {
+ $which_xdlp = $this->CheckOption($which_xdlp, 'plotdown, plotup, both, none, plotin, plotstack',
+ __FUNCTION__);
+ if (!$which_xdlp) return FALSE;
+ $this->x_data_label_pos = $which_xdlp;
+
+ return TRUE;
+ }
+
+ /*
+ * Sets position for Y data labels.
+ * For vertical plots (where available), these are Y data value labels, showing the data values.
+ * Accepted positions are: plotin, plotstack, none.
+ * For horizontal plots, these are Y axis data labels, showing label strings from the data array.
+ * Accepted positions are: plotleft, plotright, both, none.
+ */
+ function SetYDataLabelPos($which_ydlp)
+ {
+ $which_ydlp = $this->CheckOption($which_ydlp, 'plotleft, plotright, both, none, plotin, plotstack',
+ __FUNCTION__);
+ if (!$which_ydlp) return FALSE;
+ $this->y_data_label_pos = $which_ydlp;
+
+ return TRUE;
+ }
+
+ /*
+ * Set position for X tick labels.
+ */
+ function SetXTickLabelPos($which_xtlp)
+ {
+ $which_xtlp = $this->CheckOption($which_xtlp, 'plotdown, plotup, both, xaxis, none',
+ __FUNCTION__);
+ if (!$which_xtlp) return FALSE;
+ $this->x_tick_label_pos = $which_xtlp;
+
+ return TRUE;
+ }
+
+ /*
+ * Set position for Y tick labels.
+ */
+ function SetYTickLabelPos($which_ytlp)
+ {
+ $which_ytlp = $this->CheckOption($which_ytlp, 'plotleft, plotright, both, yaxis, none',
+ __FUNCTION__);
+ if (!$which_ytlp) return FALSE;
+ $this->y_tick_label_pos = $which_ytlp;
+
+ return TRUE;
+ }
+
+ /*
+ * Set formatting type for tick and data labels on X or Y axis.
+ * This implements the 4 functions Set[XY]LabelType() and Set[XY]DataLabelType().
+ * $mode : 'x', 'y', 'xd', or 'yd' - which type of label to configure.
+ * 'x' and 'y' set the type for tick labels, and the default type for data labels
+ * if they are not separately configured. 'xd' and 'yd' set the type for data labels.
+ * $args : Variable arguments, passed as an array.
+ * [0] = $type (required) : Label type. 'data', 'time', 'printf', or 'custom'.
+ * For type 'data':
+ * [1] = $precision (optional). Numeric precision. Can also be set by SetPrecision[XY]().
+ * [2] = $prefix (optional) - prefix string for labels.
+ * [3] = $suffix (optional) - suffix string for labels. This replaces data_units_text.
+ * For type 'time':
+ * [1] = $format for strftime (optional). Can also be set by Set[XY]TimeFormat().
+ * For type 'printf':
+ * [1] = $format (optional) for sprintf.
+ * For type 'custom':
+ * [1] = $callback (required) - Custom function or array of (instance,method) to call.
+ * [2] = $argument (optional) - Pass-through argument for the formatting function.
+ */
+ protected function SetLabelType($mode, $args)
+ {
+ if (!$this->CheckOption($mode, 'x, y, xd, yd', __FUNCTION__))
+ return FALSE;
+
+ $type = isset($args[0]) ? $args[0] : '';
+ $format =& $this->label_format[$mode]; // Shorthand reference to format storage variables
+ switch ($type) {
+ case 'data':
+ if (isset($args[1]))
+ $format['precision'] = $args[1];
+ elseif (!isset($format['precision']))
+ $format['precision'] = 1;
+ $format['prefix'] = isset($args[2]) ? $args[2] : '';
+ $format['suffix'] = isset($args[3]) ? $args[3] : '';
+ break;
+
+ case 'time':
+ if (isset($args[1]))
+ $format['time_format'] = $args[1];
+ elseif (!isset($format['time_format']))
+ $format['time_format'] = '%H:%M:%S';
+ break;
+
+ case 'printf':
+ if (isset($args[1]))
+ $format['printf_format'] = $args[1];
+ elseif (!isset($format['printf_format']))
+ $format['printf_format'] = '%e';
+ break;
+
+ case 'custom':
+ if (isset($args[1])) {
+ $format['custom_callback'] = $args[1];
+ $format['custom_arg'] = isset($args[2]) ? $args[2] : NULL;
+ } else {
+ $type = ''; // Error, 'custom' without a function, set to no-format mode.
+ }
+ break;
+
+ case '':
+ case 'title': // Retained for backwards compatibility?
+ break;
+
+ default:
+ $this->CheckOption($type, 'data, time, printf, custom', __FUNCTION__);
+ $type = '';
+ }
+ $format['type'] = $type;
+ return (boolean)$type;
+ }
+
+ /*
+ * Select label formating for X tick labels, and for X data labels
+ * (unless SetXDataLabelType was called).
+ * See SetLabelType() for details.
+ */
+ function SetXLabelType() // Variable arguments: $type, ...
+ {
+ $args = func_get_args();
+ return $this->SetLabelType('x', $args);
+ }
+
+ /*
+ * Select label formatting for X data labels, overriding SetXLabelType.
+ */
+ function SetXDataLabelType() // Variable arguments: $type, ...
+ {
+ $args = func_get_args();
+ return $this->SetLabelType('xd', $args);
+ }
+
+ /*
+ * Select label formating for Y tick labels, and for Y data labels
+ * (unless SetYDataLabelType was called).
+ * See SetLabelType() for details.
+ */
+ function SetYLabelType() // Variable arguments: $type, ...
+ {
+ $args = func_get_args();
+ return $this->SetLabelType('y', $args);
+ }
+
+ /*
+ * Select label formatting for Y data labels, overriding SetYLabelType.
+ */
+ function SetYDataLabelType() // Variable arguments: $type, ...
+ {
+ $args = func_get_args();
+ return $this->SetLabelType('yd', $args);
+ }
+
+ /*
+ * Set the date/time format code for X labels.
+ * Note: Use of SetXLabelType('time', $which_xtf) is preferred, because
+ * SetXTimeFormat does not also enable date/time formatting.
+ */
+ function SetXTimeFormat($which_xtf)
+ {
+ $this->label_format['x']['time_format'] = $which_xtf;
+ return TRUE;
+ }
+
+ /*
+ * Set the date/time format code for Y labels.
+ * Note: Use of SetYLabelType('time', $which_ytf) is preferred, because
+ * SetYTimeFormat does not also enable date/time formatting.
+ */
+ function SetYTimeFormat($which_ytf)
+ {
+ $this->label_format['y']['time_format'] = $which_ytf;
+ return TRUE;
+ }
+
+ /*
+ * Set number format parameters (decimal point and thousands separator) for
+ * 'data' mode label formatting, overriding the locale-defaults.
+ */
+ function SetNumberFormat($decimal_point, $thousands_sep)
+ {
+ $this->decimal_point = $decimal_point;
+ $this->thousands_sep = $thousands_sep;
+ return TRUE;
+ }
+
+ /*
+ * Set the text angle for X labels to $which_xla degrees.
+ */
+ function SetXLabelAngle($which_xla)
+ {
+ $this->x_label_angle = $which_xla;
+ return TRUE;
+ }
+
+ /*
+ * Set the text angle for Y labels to $which_xla degrees.
+ */
+ function SetYLabelAngle($which_yla)
+ {
+ $this->y_label_angle = $which_yla;
+ return TRUE;
+ }
+
+ /*
+ * Set the angle for X Data Labels to $which_xdla degrees.
+ * If not used, this defaults to the value set with SetXLabelAngle.
+ */
+ function SetXDataLabelAngle($which_xdla)
+ {
+ $this->x_data_label_angle = $which_xdla;
+ return TRUE;
+ }
+
+ /*
+ * Set the angle for Y Data Labels to $which_ydla degrees.
+ * If not used, this defaults to zero (unlike X data labels).
+ */
+ function SetYDataLabelAngle($which_ydla)
+ {
+ $this->y_data_label_angle = $which_ydla;
+ return TRUE;
+ }
+
+/////////////////////////////////////////////
+/////////// MISC
+/////////////////////////////////////////////
+
+ /*
+ * Checks the validity of an option.
+ * $which_opt String to check, such as the provided value of a function argument.
+ * $which_acc String of accepted choices. Must be lower-case, and separated
+ * by exactly ', ' (comma, space).
+ * $which_func Name of the calling function, for error messages.
+ * Returns the supplied option value, downcased and trimmed, if it is valid.
+ * Reports an error if the supplied option is not valid.
+ */
+ protected function CheckOption($which_opt, $which_acc, $which_func)
+ {
+ $asked = strtolower(trim($which_opt));
+
+ // Look for the supplied value in a comma/space separated list.
+ if (strpos(", $which_acc,", ", $asked,") !== FALSE)
+ return $asked;
+
+ $this->PrintError("$which_func(): '$which_opt' not in available choices: '$which_acc'.");
+ return NULL;
+ }
+
+ /*
+ * Checks the validity of an array of options.
+ * $opt Array or string to check.
+ * $acc String of accepted choices. Must be lower-case, and separated
+ * by exactly ', ' (comma, space).
+ * $func Name of the calling function, for error messages.
+ * Returns a array option value(s), downcased and trimmed, if all entries in $opt are valid.
+ * Reports an error if any supplied option is not valid. Returns NULL if the error handler returns.
+ */
+ protected function CheckOptionArray($opt, $acc, $func)
+ {
+ $opt_array = (array)$opt;
+ $result = array();
+ foreach ($opt_array as $option) {
+ $choice = $this->CheckOption($option, $acc, $func);
+ if (is_null($choice)) return NULL; // In case CheckOption error handler returns
+ $result[] = $choice;
+ }
+ return $result;
+ }
+
+ /*
+ * Check compatibility of a plot type and data type.
+ * This is called by the plot-type-specific drawing functions.
+ * $valid_types String of supported data types. Multiple values must be
+ * separated by exactly ', ' (comma, space).
+ * Returns True if the type is valid for this plot.
+ * Reports an error if the data type is not value. If the error is handled and
+ * the handler returns, this returns False.
+ */
+ protected function CheckDataType($valid_types)
+ {
+ if (strpos(", $valid_types,", ", $this->data_type,") !== FALSE)
+ return TRUE;
+
+ $this->PrintError("Data type '$this->data_type' is not valid for '$this->plot_type' plots."
+ . " Supported data type(s): '$valid_types'");
+ return FALSE;
+ }
+
+ /*
+ * Decode the data type into variables used to determine how to process a data array.
+ * The goal is minimize which functions understand the actual data type values.
+ * This sets the datatype_* variables for use by other member functions.
+ * datatype_implied : Implicit independent variable (e.g. text-data vs data-data)
+ * datatype_swapped_xy : Swapped X/Y (horizontal plot)
+ * datatype_error_bars : Data array has error bar data
+ * datatype_pie_single : Data array is for a pie chart with one row per slice
+ */
+ protected function DecodeDataType()
+ {
+ $dt = $this->data_type;
+
+ $this->datatype_implied = ($dt == 'text-data' || $dt == 'text-data-single'
+ || $dt == 'text-data-yx');
+ $this->datatype_swapped_xy = ($dt == 'text-data-yx' || $dt == 'data-data-yx');
+ $this->datatype_error_bars = ($dt == 'data-data-error');
+ $this->datatype_pie_single = ($dt == 'text-data-single');
+ }
+
+ /*
+ * Make sure the data array is populated, and calculate the number of columns.
+ * This is called from DrawGraph. Calculates data_columns, which is the
+ * maximum number of dependent variable values (usually Y) in the data array rows.
+ * (For pie charts, this is the number of slices.)
+ * This depends on the data_type, unlike records_per_group (which was
+ * previously used to pad style arrays, but is not accurate).
+ * Returns True if the data array is OK, else reports an error (and may return False).
+ * Note error messages refer to the caller, the public DrawGraph().
+ */
+ protected function CheckDataArray()
+ {
+ // Test for missing image, which really should never happen.
+ if (!$this->img) {
+ return $this->PrintError('DrawGraph(): No image resource allocated');
+ }
+
+ // Test for missing or empty data array:
+ if (empty($this->data) || !is_array($this->data)) {
+ return $this->PrintError("DrawGraph(): No data array");
+ }
+ if ($this->total_records == 0) {
+ return $this->PrintError('DrawGraph(): Empty data set');
+ }
+
+ // Decode the data type into functional flags.
+ $this->DecodeDataType();
+
+ // Calculate the maximum number of dependent values per independent value
+ // (e.g. Y for each X), or the number of pie slices.
+ if ($this->datatype_pie_single) {
+ $this->data_columns = $this->num_data_rows; // Special case for 1 type of pie chart.
+ } else {
+ $skip = $this->datatype_implied ? 1 : 2; // Skip data label and independent variable if used
+ $this->data_columns = $this->records_per_group - $skip;
+ if ($this->datatype_error_bars) // Each Y has +err and -err along with it
+ $this->data_columns = (int)($this->data_columns / 3);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Control headers for browser-side image caching.
+ * $which_browser_cache : True to allow browsers to cache the image.
+ */
+ function SetBrowserCache($which_browser_cache)
+ {
+ $this->browser_cache = $which_browser_cache;
+ return TRUE;
+ }
+
+ /*
+ * Set whether DrawGraph automatically outputs the image too.
+ * $which_pi : True to have DrawGraph call PrintImage at the end.
+ */
+ function SetPrintImage($which_pi)
+ {
+ $this->print_image = $which_pi;
+ return TRUE;
+ }
+
+ /*
+ * Set text to display in the graph's legend.
+ * $which_leg : Array of strings for the complete legend, or a single string
+ * to be appended to the legend.
+ * Or NULL (or an empty array) to cancel the legend.
+ */
+ function SetLegend($which_leg)
+ {
+ if (is_array($which_leg)) { // use array (or cancel, if empty array)
+ $this->legend = $which_leg;
+ } elseif (!is_null($which_leg)) { // append string
+ $this->legend[] = $which_leg;
+ } else {
+ $this->legend = ''; // Reinitialize to empty, meaning no legend.
+ }
+ return TRUE;
+ }
+
+ /*
+ * Specifies the position of the legend's upper/leftmost corner,
+ * in pixel (device) coordinates.
+ * Both X and Y must be provided, or both omitted (or use NULL) to restore auto-positioning.
+ */
+ function SetLegendPixels($which_x=NULL, $which_y=NULL)
+ {
+ $this->legend_x_pos = $which_x;
+ $this->legend_y_pos = $which_y;
+ // Make sure this is unset, meaning we have pixel coords:
+ unset($this->legend_xy_world);
+
+ return TRUE;
+ }
+
+ /*
+ * Specifies the position of the legend's upper/leftmost corner,
+ * in world (data space) coordinates.
+ */
+ function SetLegendWorld($which_x, $which_y)
+ {
+ // Since conversion from world to pixel coordinates is not yet available, just
+ // remember the coordinates and set a flag to indicate conversion is needed.
+ $this->legend_x_pos = $which_x;
+ $this->legend_y_pos = $which_y;
+ $this->legend_xy_world = TRUE;
+
+ return TRUE;
+ }
+
+ /*
+ * Set legend text alignment, color box alignment, and style options.
+ * $text_align : Alignment of the text, 'left' or 'right'.
+ * $colorbox_align : Alignment of the color boxes, 'left', 'right', 'none', or missing/empty.
+ * If missing or empty, the same alignment as $text_align is used. Color box is positioned first.
+ * $style : reserved for future use.
+ */
+ function SetLegendStyle($text_align, $colorbox_align = '', $style = '')
+ {
+ $this->legend_text_align = $this->CheckOption($text_align, 'left, right', __FUNCTION__);
+ if (empty($colorbox_align))
+ $this->legend_colorbox_align = $this->legend_text_align;
+ else
+ $this->legend_colorbox_align = $this->CheckOption($colorbox_align, 'left, right, none',
+ __FUNCTION__);
+ return ((boolean)$this->legend_text_align && (boolean)$this->legend_colorbox_align);
+ }
+
+ /*
+ * Set border for the plot area.
+ * Accepted values are: left, right, top, bottom, sides, none, full or an array of those.
+ */
+ function SetPlotBorderType($pbt)
+ {
+ $this->plot_border_type = $this->CheckOptionArray($pbt, 'left, right, top, bottom, sides, none, full',
+ __FUNCTION__);
+ return !empty($this->plot_border_type);
+ }
+
+ /*
+ * Set border style for the image.
+ * Accepted values are: raised, plain, solid, none
+ * 'solid' is the same as 'plain' except it fixes the color (see DrawImageBorder)
+ */
+ function SetImageBorderType($sibt)
+ {
+ $this->image_border_type = $this->CheckOption($sibt, 'raised, plain, solid, none', __FUNCTION__);
+ return (boolean)$this->image_border_type;
+ }
+
+ /*
+ * Set border width for the image to $width in pixels.
+ */
+ function SetImageBorderWidth($width)
+ {
+ $this->image_border_width = $width;
+ return TRUE;
+ }
+
+ /*
+ * Enable or disable drawing of the plot area background color.
+ */
+ function SetDrawPlotAreaBackground($dpab)
+ {
+ $this->draw_plot_area_background = (bool)$dpab;
+ return TRUE;
+ }
+
+ /*
+ * Enable or disable drawing of the X grid lines.
+ */
+ function SetDrawXGrid($dxg)
+ {
+ $this->draw_x_grid = (bool)$dxg;
+ return TRUE;
+ }
+
+ /*
+ * Enable or disable drawing of the Y grid lines.
+ */
+ function SetDrawYGrid($dyg)
+ {
+ $this->draw_y_grid = (bool)$dyg;
+ return TRUE;
+ }
+
+ /*
+ * Select dashed or solid grid lines.
+ * $ddg : True for dashed grid lines, false for solid grid lines.
+ */
+ function SetDrawDashedGrid($ddg)
+ {
+ $this->dashed_grid = (bool)$ddg;
+ return TRUE;
+ }
+
+ /*
+ * Enable or disable drawing of X Data Label Lines.
+ */
+ function SetDrawXDataLabelLines($dxdl)
+ {
+ $this->draw_x_data_label_lines = (bool)$dxdl;
+ return TRUE;
+ }
+
+ /*
+ * Set the main title text for the plot.
+ */
+ function SetTitle($which_title)
+ {
+ $this->title_txt = $which_title;
+ return TRUE;
+ }
+
+ /*
+ * Set the X axis title and position.
+ */
+ function SetXTitle($which_xtitle, $which_xpos = 'plotdown')
+ {
+ if ($which_xtitle == '')
+ $which_xpos = 'none';
+
+ $this->x_title_pos = $this->CheckOption($which_xpos, 'plotdown, plotup, both, none', __FUNCTION__);
+ if (!$this->x_title_pos) return FALSE;
+ $this->x_title_txt = $which_xtitle;
+ return TRUE;
+ }
+
+ /*
+ * Set the Y axis title and position.
+ */
+ function SetYTitle($which_ytitle, $which_ypos = 'plotleft')
+ {
+ if ($which_ytitle == '')
+ $which_ypos = 'none';
+
+ $this->y_title_pos = $this->CheckOption($which_ypos, 'plotleft, plotright, both, none', __FUNCTION__);
+ if (!$this->y_title_pos) return FALSE;
+ $this->y_title_txt = $which_ytitle;
+ return TRUE;
+ }
+
+ /*
+ * Set the size of the drop shadow for bar and pie charts.
+ * $which_s : Size of the drop shadow in pixels.
+ */
+ function SetShading($which_s)
+ {
+ $this->shading = (int)$which_s;
+ return TRUE;
+ }
+
+ /*
+ * Set the plot type (bars, points, ...)
+ */
+ function SetPlotType($which_pt)
+ {
+ $avail_plot_types = implode(', ', array_keys(PHPlot::$plots)); // List of known plot types
+ $this->plot_type = $this->CheckOption($which_pt, $avail_plot_types, __FUNCTION__);
+ return (boolean)$this->plot_type;
+ }
+
+ /*
+ * Set the position of the X axis.
+ * $pos : Axis position in world coordinates (as an integer).
+ */
+ function SetXAxisPosition($pos='')
+ {
+ $this->x_axis_position = ($pos === '') ? $pos : (int)$pos;
+ return TRUE;
+ }
+
+ /*
+ * Set the position of the Y axis.
+ * $pos : Axis position in world coordinates (as an integer).
+ */
+ function SetYAxisPosition($pos='')
+ {
+ $this->y_axis_position = ($pos === '') ? $pos : (int)$pos;
+ return TRUE;
+ }
+
+ /*
+ * Enable or disable drawing of the X axis line.
+ * $draw : True to draw the axis (default if not called), False to suppress it.
+ * This controls drawing of the axis line only, and not the ticks, labels, or grid.
+ */
+ function SetDrawXAxis($draw)
+ {
+ $this->suppress_x_axis = !$draw; // See DrawXAxis()
+ return TRUE;
+ }
+
+ /*
+ * Enable or disable drawing of the Y axis line.
+ * $draw : True to draw the axis (default if not called), False to suppress it.
+ * This controls drawing of the axis line only, and not the ticks, labels, or grid.
+ */
+ function SetDrawYAxis($draw)
+ {
+ $this->suppress_y_axis = !$draw; // See DrawYAxis()
+ return TRUE;
+ }
+
+ /*
+ * Select linear or log scale for the X axis.
+ */
+ function SetXScaleType($which_xst)
+ {
+ $this->xscale_type = $this->CheckOption($which_xst, 'linear, log', __FUNCTION__);
+ return (boolean)$this->xscale_type;
+ }
+
+ /*
+ * Select linear or log scale for the Y axis.
+ */
+ function SetYScaleType($which_yst)
+ {
+ $this->yscale_type = $this->CheckOption($which_yst, 'linear, log', __FUNCTION__);
+ return (boolean)$this->yscale_type;
+ }
+
+ /*
+ * Set the precision for numerically formatted X labels.
+ * $which_prec : Number of digits to display.
+ * Note: This is equivalent to: SetXLabelType('data', $which_prec)
+ */
+ function SetPrecisionX($which_prec)
+ {
+ return $this->SetXLabelType('data', $which_prec);
+ }
+
+ /*
+ * Set the precision for numerically formatted Y labels.
+ * $which_prec : Number of digits to display.
+ * Note: This is equivalent to: SetYLabelType('data', $which_prec)
+ */
+ function SetPrecisionY($which_prec)
+ {
+ return $this->SetYLabelType('data', $which_prec);
+ }
+
+ /*
+ * Set the line width (in pixels) for error bars.
+ */
+ function SetErrorBarLineWidth($which_seblw)
+ {
+ $this->error_bar_line_width = $which_seblw;
+ return TRUE;
+ }
+
+ /*
+ * Set the position for pie chart percentage labels.
+ * $which_blb : Real number between 0 and 1.
+ * Smaller values move the labels in towards the center.
+ */
+ function SetLabelScalePosition($which_blp)
+ {
+ $this->label_scale_position = $which_blp;
+ return TRUE;
+ }
+
+ /*
+ * Set the size (in pixels) of the "T" in error bars.
+ */
+ function SetErrorBarSize($which_ebs)
+ {
+ $this->error_bar_size = $which_ebs;
+ return TRUE;
+ }
+
+ /*
+ * Set the shape of the in error bars.
+ * $which_ebs : Error bar shape, 'tee' or 'line'.
+ */
+ function SetErrorBarShape($which_ebs)
+ {
+ $this->error_bar_shape = $this->CheckOption($which_ebs, 'tee, line', __FUNCTION__);
+ return (boolean)$this->error_bar_shape;
+ }
+
+ /*
+ * Synchronize the point shape and point size arrays.
+ * This is called just before drawing any plot that needs 'points'.
+ */
+ protected function CheckPointParams()
+ {
+ // Make both point_shapes and point_sizes the same size, by padding the smaller.
+ $ps = count($this->point_sizes);
+ $pt = count($this->point_shapes);
+
+ if ($ps < $pt) {
+ $this->pad_array($this->point_sizes, $pt);
+ $this->point_counts = $pt;
+ } elseif ($ps > $pt) {
+ $this->pad_array($this->point_shapes, $ps);
+ $this->point_counts = $ps;
+ } else {
+ $this->point_counts = $ps;
+ }
+
+ // Note: PHPlot used to check and adjust point_sizes to be an even number here,
+ // for all 'diamond' and 'triangle' shapes. The reason for this having been
+ // lost, and the current maintainer seeing no sense it doing this for only
+ // some shapes, the code has been removed. But see what DrawDot() does.
+ }
+
+ /*
+ * Set the point shape for each data set.
+ * $which_pt : Array (or single value) of valid point shapes. See also DrawDot() for valid shapes.
+ * The point shape and point sizes arrays are synchronized before drawing a graph
+ * that uses points. See CheckPointParams()
+ */
+ function SetPointShapes($which_pt)
+ {
+ $this->point_shapes = $this->CheckOptionArray($which_pt, 'halfline, line, plus, cross, rect,'
+ . ' circle, dot, diamond, triangle, trianglemid, delta, yield, star, hourglass,'
+ . ' bowtie, target, box, home, up, down, none', __FUNCTION__);
+ return !empty($this->point_shapes);
+ }
+
+ /*
+ * Set the point size for point plots.
+ * $which_ps : Array (or single value) of point sizes in pixels.
+ * The point shape and point sizes arrays are synchronized before drawing a graph
+ * that uses points. See CheckPointParams()
+ */
+ function SetPointSizes($which_ps)
+ {
+ if (is_array($which_ps)) {
+ // Use provided array:
+ $this->point_sizes = $which_ps;
+ } elseif (!is_null($which_ps)) {
+ // Make the single value into an array:
+ $this->point_sizes = array($which_ps);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Sets whether lines should be broken at missing data.
+ * $bl : True to break the lines, false to connect around missing data.
+ * This only works with 'lines' and 'squared' plots.
+ */
+ function SetDrawBrokenLines($bl)
+ {
+ $this->draw_broken_lines = (bool)$bl;
+ return TRUE;
+ }
+
+ /*
+ * Set the data type, which defines the structure of the data array
+ * text-data: ('label', y1, y2, y3, ...)
+ * text-data-single: ('label', data), for some pie charts.
+ * data-data: ('label', x, y1, y2, y3, ...)
+ * data-data-error: ('label', x1, y1, e1+, e2-, y2, e2+, e2-, y3, e3+, e3-, ...)
+ * data-data-yx: ('label', y, x1, x2, x3, ..)
+ * text-data-yx: ('label', x1, x2, x3, ...)
+ */
+ function SetDataType($which_dt)
+ {
+ //The next four lines are for past compatibility.
+ if ($which_dt == 'text-linear') $which_dt = 'text-data';
+ elseif ($which_dt == 'linear-linear') $which_dt = 'data-data';
+ elseif ($which_dt == 'linear-linear-error') $which_dt = 'data-data-error';
+ elseif ($which_dt == 'text-data-pie') $which_dt = 'text-data-single';
+
+ $this->data_type = $this->CheckOption($which_dt, 'text-data, text-data-single, '.
+ 'data-data, data-data-error, '.
+ 'data-data-yx, text-data-yx',
+ __FUNCTION__);
+ return (boolean)$this->data_type;
+ }
+
+ /*
+ * Copy the array passed as data values. We convert to numerical indexes, for its
+ * use for (or while) loops, which sometimes are faster. Performance improvements
+ * vary from 28% in DrawLines() to 49% in DrawArea() for plot drawing functions.
+ */
+ function SetDataValues($which_dv)
+ {
+ $this->num_data_rows = count($which_dv);
+ $this->total_records = 0;
+ $this->data = array();
+ $this->num_recs = array();
+ for ($i = 0; $i < $this->num_data_rows; $i++) {
+ $this->data[$i] = array_values($which_dv[$i]); // convert to numerical indices.
+
+ // Count size of each row, and total for the array.
+ $recs = count($this->data[$i]);
+ $this->total_records += $recs;
+ $this->num_recs[$i] = $recs;
+ }
+ // This is the size of the widest row in the data array
+ // Note records_per_group isn't used much anymore. See data_columns in CheckDataArray()
+ $this->records_per_group = max($this->num_recs);
+ return TRUE;
+ }
+
+ /*
+ * Pad styles arrays for later use by plot drawing functions:
+ * This removes the need for $max_data_colors, etc. and $color_index = $color_index % $max_data_colors
+ * in DrawBars(), DrawLines(), etc.
+ * The arrays are padded to data_columns which is the maximum number of data sets.
+ * See CheckDataArray() for the calculation.
+ */
+ protected function PadArrays()
+ {
+ $this->pad_array($this->line_widths, $this->data_columns);
+ $this->pad_array($this->line_styles, $this->data_columns);
+ $this->pad_array($this->ndx_data_colors, $this->data_columns);
+ $this->pad_array($this->ndx_data_border_colors, $this->data_columns);
+ // Other data color arrays are handled in the Need*Colors() functions.
+
+ return TRUE;
+ }
+
+ /*
+ * Pads an array with itself. This only works on 0-based sequential integer indexed arrays.
+ * $arr : The array (or scalar) to pad. This argument is modified.
+ * $size : Minimum size of the resulting array.
+ * If $arr is a scalar, it will be converted first to a single element array.
+ * If $arr has at least $size elements, it is unchanged.
+ * Otherwise, append elements of $arr to itself until it reaches $size elements.
+ */
+ protected function pad_array(&$arr, $size)
+ {
+ if (! is_array($arr)) {
+ $arr = array($arr);
+ }
+ $n = count($arr);
+ $base = 0;
+ while ($n < $size) $arr[$n++] = $arr[$base++];
+ }
+
+ /*
+ * Format a floating-point number.
+ * $number : A floating point number to format
+ * $decimals : Number of decimal places in the result
+ * Returns the formatted result.
+ * This is like PHP's number_format, but uses class variables for separators.
+ * The separators will default to locale-specific values, if available.
+ */
+ protected function number_format($number, $decimals=0)
+ {
+ if (!isset($this->decimal_point) || !isset($this->thousands_sep)) {
+ // Load locale-specific values from environment, unless disabled:
+ if (empty($this->locale_override))
+ @setlocale(LC_ALL, '');
+ // Fetch locale settings:
+ $locale = @localeconv();
+ if (isset($locale['decimal_point']) && isset($locale['thousands_sep'])) {
+ $this->decimal_point = $locale['decimal_point'];
+ $this->thousands_sep = $locale['thousands_sep'];
+ } else {
+ // Locale information not available.
+ $this->decimal_point = '.';
+ $this->thousands_sep = ',';
+ }
+ }
+ return number_format($number, $decimals, $this->decimal_point, $this->thousands_sep);
+ }
+
+ /*
+ * Register a callback (hook) function
+ * $reason : A pre-defined name where a callback can be defined.
+ * $function : The name of a function to register for callback, or an instance/method
+ * pair in an array (see 'callbacks' in the PHP reference manual).
+ * $arg : Optional argument to supply to the callback function when it is triggered.
+ * (Often called "clientData")
+ * Returns True if the callback reason is valid, else False.
+ */
+ function SetCallback($reason, $function, $arg = NULL)
+ {
+ // Use array_key_exists because valid reason keys have NULL as value.
+ if (!array_key_exists($reason, $this->callbacks))
+ return FALSE;
+ $this->callbacks[$reason] = array($function, $arg);
+ return TRUE;
+ }
+
+ /*
+ * Return the name of a function registered for callback. See SetCallBack.
+ * $reason - A pre-defined name where a callback can be defined.
+ * Returns the current callback function (name or array) for the given reason,
+ * or False if there was no active callback or the reason is not valid.
+ * Note you can safely test the return value with a simple 'if', as
+ * no valid function name evaluates to false.
+ */
+ function GetCallback($reason)
+ {
+ if (isset($this->callbacks[$reason]))
+ return $this->callbacks[$reason][0];
+ return FALSE;
+ }
+
+ /*
+ * Un-register (remove) a function registered for callback.
+ * $reason - A pre-defined name where a callback can be defined.
+ * Returns: True if it was a valid callback reason, else False.
+ * Note: Returns True whether or not there was a callback registered.
+ */
+ function RemoveCallback($reason)
+ {
+ if (!array_key_exists($reason, $this->callbacks))
+ return FALSE;
+ $this->callbacks[$reason] = NULL;
+ return TRUE;
+ }
+
+ /*
+ * Invoke a callback, if one is registered.
+ * Accepts a variable number of arguments >= 1:
+ * $reason : A string naming the callback.
+ * ... : Zero or more additional arguments to be passed to the
+ * callback function, after the passthru argument:
+ * callback_function($image, $passthru, ...)
+ * Returns: whatever value (if any) was returned by the callback.
+ */
+ protected function DoCallback() // Note: Variable arguments
+ {
+ $args = func_get_args();
+ $reason = $args[0];
+ if (!isset($this->callbacks[$reason]))
+ return;
+ list($function, $args[0]) = $this->callbacks[$reason];
+ array_unshift($args, $this->img);
+ // Now args[] looks like: img, passthru, extra args...
+ return call_user_func_array($function, $args);
+ }
+
+ /*
+ * Allocate colors for the plot.
+ * This is called by DrawGraph to allocate the colors needed for the plot. Each selectable
+ * color has already been validated, parsed into an array (r,g,b,a), and stored into a member
+ * variable. Now the GD color indexes are assigned and stored into the ndx_*_color variables.
+ * This is deferred here to avoid allocating unneeded colors and to avoid order dependencies,
+ * especially with the transparent color.
+ *
+ * For drawing data elements, only the main data colors and border colors are allocated here.
+ * Dark colors and error bar colors are allocated by Need*Color() functions.
+ * (Data border colors default to just black, so there is no cost to always allocating.)
+ *
+ * Data color allocation works as follows. If there is a data_color callback, then allocate all
+ * defined data colors (because the callback can use them however it wants). Otherwise, only allocate
+ * the number of colors that will be used. This is the larger of the number of data sets and the
+ * number of legend lines.
+ */
+ protected function SetColorIndexes()
+ {
+ $this->ndx_bg_color = $this->GetColorIndex($this->bg_color); // Background first
+ $this->ndx_plot_bg_color = $this->GetColorIndex($this->plot_bg_color);
+ if ($this->image_border_type != 'none') {
+ $this->ndx_i_border = $this->GetColorIndex($this->i_border);
+ $this->ndx_i_border_dark = $this->GetDarkColorIndex($this->i_border);
+ }
+
+ // Handle defaults for X and Y title colors.
+ $this->ndx_title_color = $this->GetColorIndex($this->title_color);
+ if (empty($this->x_title_color)) {
+ $this->ndx_x_title_color = $this->ndx_title_color;
+ } else {
+ $this->ndx_x_title_color = $this->GetColorIndex($this->x_title_color);
+ }
+ if (empty($this->y_title_color)) {
+ $this->ndx_y_title_color = $this->ndx_title_color;
+ } else {
+ $this->ndx_y_title_color = $this->GetColorIndex($this->y_title_color);
+ }
+
+ $this->ndx_text_color = $this->GetColorIndex($this->text_color);
+ $this->ndx_grid_color = $this->GetColorIndex($this->grid_color);
+ $this->ndx_light_grid_color = $this->GetColorIndex($this->light_grid_color);
+ $this->ndx_tick_color = $this->GetColorIndex($this->tick_color);
+
+ // Maximum number of data & border colors to allocate:
+ if ($this->GetCallback('data_color')) {
+ $n_data = count($this->data_colors); // Need all of them
+ $n_border = count($this->data_border_colors);
+ } else {
+ $n_data = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend));
+ $n_border = $n_data; // One border color per data color
+ }
+
+ // Allocate main data colors. For other colors used for data, see the functions which follow.
+ $this->ndx_data_colors = $this->GetColorIndexArray($this->data_colors, $n_data);
+ $this->ndx_data_border_colors = $this->GetColorIndexArray($this->data_border_colors, $n_border);
+
+ // Set up a color as transparent, if SetTransparentColor was used.
+ if (!empty($this->transparent_color)) {
+ imagecolortransparent($this->img, $this->GetColorIndex($this->transparent_color));
+ }
+ }
+
+ /*
+ * Allocate dark-shade data colors. Called if needed by graph drawing functions.
+ */
+ protected function NeedDataDarkColors()
+ {
+ // This duplicates the calculation in SetColorIndexes() for number of data colors to allocate.
+ if ($this->GetCallback('data_color')) {
+ $n_data = count($this->data_colors);
+ } else {
+ $n_data = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend));
+ }
+ $this->ndx_data_dark_colors = $this->GetDarkColorIndexArray($this->data_colors, $n_data);
+ $this->pad_array($this->ndx_data_dark_colors, $this->data_columns);
+ }
+
+ /*
+ * Allocate error bar colors. Called if needed by graph drawing functions.
+ */
+ protected function NeedErrorBarColors()
+ {
+ // This is similar to the calculation in SetColorIndexes() for number of data colors to allocate.
+ if ($this->GetCallback('data_color')) {
+ $n_err = count($this->error_bar_colors);
+ } else {
+ $n_err = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend));
+ }
+ $this->ndx_error_bar_colors = $this->GetColorIndexArray($this->error_bar_colors, $n_err);
+ $this->pad_array($this->ndx_error_bar_colors, $this->data_columns);
+ }
+
+ /*
+ * Determine if, and where, to draw Data Value Labels.
+ * $label_control : Label position control. Either x_data_label_pos or y_data_label_pos.
+ * &$x_adj, &$y_adj : Returns X,Y adjustments (offset in pixels) to the text position.
+ * &$h_align, &$v_align : Returns horizontal and vertical alignment for the label.
+ * The above 4 argument values should be passed to DrawDataValueLabel()
+ * Returns True if data value labels should be drawn (based on $label_control), else False.
+ * This is used for plot types other than bars/stackedbars (which have their own way of doing it).
+ * It uses two member variables (unset by default): data_value_label_angle and data_value_label_distance
+ * to define the vector to the label. Default is 90 degrees at 5 pixels.
+ */
+ protected function CheckDataValueLabels($label_control, &$x_adj, &$y_adj, &$h_align, &$v_align)
+ {
+ if ($label_control != 'plotin')
+ return FALSE; // No data value labels
+ $angle = deg2rad(isset($this->data_value_label_angle) ? $this->data_value_label_angle : 90);
+ $radius = isset($this->data_value_label_distance) ? $this->data_value_label_distance : 5;
+ $cos = cos($angle);
+ $sin = sin($angle);
+ $x_adj = (int)($radius * $cos);
+ $y_adj = -(int)($radius * $sin); // Y is reversed in device coordinates
+
+ // Choose from 8 (not 9, center/center can't happen) text alignments based on angle:
+ if ($sin >= 0.383) $v_align = 'bottom'; // 0.383 = sin(360deg / 16)
+ elseif ($sin >= -0.383) $v_align = 'center';
+ else $v_align = 'top';
+ if ($cos >= 0.383) $h_align = 'left';
+ elseif ($cos >= -0.383) $h_align = 'center';
+ else $h_align = 'right';
+ return TRUE;
+ }
+
+//////////////////////////////////////////////////////////
+/////////// DATA ANALYSIS, SCALING AND TRANSLATION
+//////////////////////////////////////////////////////////
+
+ /*
+ * Analyzes the data array and calculates the minimum and maximum values.
+ * In this function, IV refers to the independent variable, and DV the dependent variable.
+ * For most plots, IV is X and DV is Y. For swapped X/Y plots, IV is Y and DV is X.
+ * At the end of the function, IV and DV ranges get assigned into X or Y.
+ *
+ * The data type mostly determines the data array structure, but some plot types do special
+ * things such as sum the values in a row. This information is in the plots[] array.
+ *
+ * This calculates min_x, max_x, min_y, and max_y. It also calculates two arrays
+ * data_min[] and data_max[] with per-row min and max values. These are used for
+ * data label lines. For normal (unswapped) data, these are the Y range for each X.
+ * For swapped X/Y data, they are the X range for each Y.
+ */
+ protected function FindDataLimits()
+ {
+ // Does this plot type need special processing of the data values?
+ $sum_vals = !empty(PHPlot::$plots[$this->plot_type]['sum_vals']); // Add up values in each row
+ $abs_vals = !empty(PHPlot::$plots[$this->plot_type]['abs_vals']); // Take absolute values
+
+ // These need to be initialized in case there are multiple plots and missing data points.
+ $this->data_min = array();
+ $this->data_max = array();
+
+ // Independent values are in the data array or assumed?
+ if ($this->datatype_implied) {
+ $all_iv = array(0, $this->num_data_rows - 1);
+ } else {
+ $all_iv = array();
+ }
+
+ // Process all rows of data:
+ for ($i = 0; $i < $this->num_data_rows; $i++) {
+ $n_vals = $this->num_recs[$i];
+ $j = 1; // Skips label at [0]
+
+ if (!$this->datatype_implied) {
+ $all_iv[] = (double)$this->data[$i][$j++];
+ }
+
+ if ($sum_vals) {
+ $all_dv = array(0, 0); // One limit is 0, other calculated below
+ } else {
+ $all_dv = array();
+ }
+ while ($j < $n_vals) {
+ if (is_numeric($this->data[$i][$j])) {
+ $val = (double)$this->data[$i][$j++];
+
+ if ($this->datatype_error_bars) {
+ $all_dv[] = $val + (double)$this->data[$i][$j++];
+ $all_dv[] = $val - (double)$this->data[$i][$j++];
+ } else {
+ if ($abs_vals) {
+ $val = abs($val); // Use absolute values
+ }
+ if ($sum_vals) {
+ $all_dv[1] += $val; // Sum of values
+ } else {
+ $all_dv[] = $val; // List of all values
+ }
+ }
+ } else { // Missing DV value
+ $j++;
+ if ($this->datatype_error_bars) $j += 2;
+ }
+ }
+ if (!empty($all_dv)) {
+ $this->data_min[$i] = min($all_dv); // Store per-row DV range
+ $this->data_max[$i] = max($all_dv);
+ }
+ }
+
+ if ($this->datatype_swapped_xy) {
+ // Assign min and max for swapped X/Y plots: IV=Y and DV=X
+ $this->min_y = min($all_iv);
+ $this->max_y = max($all_iv);
+ if (empty($this->data_min)) { // Guard against regressive case: No X at all
+ $this->min_x = 0;
+ $this->max_x = 0;
+ } else {
+ $this->min_x = min($this->data_min); // Store global X range
+ $this->max_x = max($this->data_max);
+ }
+ } else {
+ // Assign min and max for normal plots: IV=X and DV=Y
+ $this->min_x = min($all_iv);
+ $this->max_x = max($all_iv);
+ if (empty($this->data_min)) { // Guard against regressive case: No Y at all
+ $this->min_y = 0;
+ $this->max_y = 0;
+ } else {
+ $this->min_y = min($this->data_min); // Store global Y range
+ $this->max_y = max($this->data_max);
+ }
+ }
+
+ if ($this->GetCallback('debug_scale')) {
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'min_x' => $this->min_x, 'min_y' => $this->min_y,
+ 'max_x' => $this->max_x, 'max_y' => $this->max_y));
+ }
+ return TRUE;
+ }
+
+ /*
+ * Calculates image margins on the fly from title positions and sizes,
+ * and tick labels positions and sizes.
+ *
+ * A picture of the locations of elements and spacing can be found in the
+ * PHPlot Reference Manual.
+ *
+ * Calculates the following (class variables unless noted):
+ *
+ * Plot area margins (see note below):
+ * y_top_margin
+ * y_bot_margin
+ * x_left_margin
+ * x_right_margin
+ *
+ * Title sizes (these are now local, not class variables, since they are not used elsewhere):
+ * title_height : Height of main title
+ * x_title_height : Height of X axis title, 0 if no X title
+ * y_title_width : Width of Y axis title, 0 if no Y title
+ *
+ * Tick/Data label offsets, relative to plot_area:
+ * x_label_top_offset, x_label_bot_offset, x_label_axis_offset
+ * y_label_left_offset, y_label_right_offset, y_label_axis_offset
+ *
+ * Title offsets, relative to plot area:
+ * x_title_top_offset, x_title_bot_offset
+ * y_title_left_offset, y_title_left_offset
+ * title_offset (for main title, relative to image edge)
+ *
+ * Note: The margins are calculated, but not stored, if margins or plot area were
+ * set by the user with SetPlotAreaPixels or SetMarginsPixels. The margin
+ * calculation is mixed in with the offset variables, so it doesn't seem worth the
+ * trouble to separate them.
+ *
+ * If the $maximize argument is true, we use the full image size, minus safe_margin
+ * and main title, for the plot. This is for pie charts which have no axes or X/Y titles.
+ */
+ protected function CalcMargins($maximize)
+ {
+ // This is the line-to-line or line-to-text spacing:
+ $gap = $this->safe_margin;
+ // Initial margin on each side takes into account a possible image border.
+ // For compatibility, if border is 1 or 2, don't increase the margins.
+ $base_margin = max($gap, $this->GetImageBorderWidth() + 3);
+ $this->title_offset = $base_margin; // For use in DrawTitle
+
+ // Minimum margin on each side. This reduces the chance that the
+ // right-most tick label (for example) will run off the image edge
+ // if there are no titles on that side.
+ $min_margin = 2 * $gap + $base_margin;
+
+ // Calculate the title sizes:
+ list($unused, $title_height) = $this->SizeText($this->fonts['title'], 0, $this->title_txt);
+ list($unused, $x_title_height) = $this->SizeText($this->fonts['x_title'], 0, $this->x_title_txt);
+ list($y_title_width, $unused) = $this->SizeText($this->fonts['y_title'], 90, $this->y_title_txt);
+
+ // Special case for maximum area usage with no X/Y titles or labels, only main title:
+ if ($maximize) {
+ if (!isset($this->x_left_margin))
+ $this->x_left_margin = $base_margin;
+ if (!isset($this->x_right_margin))
+ $this->x_right_margin = $base_margin;
+ if (!isset($this->y_top_margin)) {
+ $this->y_top_margin = $base_margin;
+ if ($title_height > 0)
+ $this->y_top_margin += $title_height + $gap;
+ }
+ if (!isset($this->y_bot_margin))
+ $this->y_bot_margin = $base_margin;
+
+ return TRUE;
+ }
+
+ // Make local variables for these. (They get used a lot and I'm tired of this, this, this.)
+ $x_tick_label_pos = $this->x_tick_label_pos;
+ $x_data_label_pos = $this->x_data_label_pos;
+ $x_tick_pos = $this->x_tick_pos;
+ $x_tick_len = $this->x_tick_length;
+ $y_tick_label_pos = $this->y_tick_label_pos;
+ $y_tick_pos = $this->y_tick_pos;
+ $y_tick_len = $this->y_tick_length;
+ $y_data_label_pos = $this->y_data_label_pos;
+
+ // For X/Y tick and label position of 'xaxis' or 'yaxis', determine if the axis happens to be
+ // on an edge of a plot. If it is, we need to account for the margins there.
+ if ($this->x_axis_position <= $this->plot_min_y)
+ $x_axis_pos = 'bottom';
+ elseif ($this->x_axis_position >= $this->plot_max_y)
+ $x_axis_pos = 'top';
+ else
+ $x_axis_pos = 'none';
+ if ($this->y_axis_position <= $this->plot_min_x)
+ $y_axis_pos = 'left';
+ elseif ($this->y_axis_position >= $this->plot_max_x)
+ $y_axis_pos = 'right';
+ else
+ $y_axis_pos = 'none';
+
+ // Calculate the heights for X tick and data labels, and the max (used if they are overlaid):
+ $x_data_label_height = ($x_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('x');
+ $x_tick_label_height = ($x_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('x');
+ $x_max_label_height = max($x_data_label_height, $x_tick_label_height);
+
+ // Calculate the space needed above and below the plot for X tick and X data labels:
+
+ // Above the plot:
+ $tick_labels_above = ($x_tick_label_pos == 'plotup' || $x_tick_label_pos == 'both'
+ || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'top'));
+ $data_labels_above = ($x_data_label_pos == 'plotup' || $x_data_label_pos == 'both');
+ if ($tick_labels_above) {
+ if ($data_labels_above) {
+ $label_height_above = $x_max_label_height;
+ } else {
+ $label_height_above = $x_tick_label_height;
+ }
+ } elseif ($data_labels_above) {
+ $label_height_above = $x_data_label_height;
+ } else {
+ $label_height_above = 0;
+ }
+
+ // Below the plot:
+ $tick_labels_below = ($x_tick_label_pos == 'plotdown' || $x_tick_label_pos == 'both'
+ || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'bottom'));
+ $data_labels_below = ($x_data_label_pos == 'plotdown' || $x_data_label_pos == 'both');
+ if ($tick_labels_below) {
+ if ($data_labels_below) {
+ $label_height_below = $x_max_label_height;
+ } else {
+ $label_height_below = $x_tick_label_height;
+ }
+ } elseif ($data_labels_below) {
+ $label_height_below = $x_data_label_height;
+ } else {
+ $label_height_below = 0;
+ }
+
+ // Calculate the width for Y tick and data labels, if on, and the max:
+ // Note CalcMaxDataLabelSize('y') returns 0 except for swapped X/Y plots.
+ $y_data_label_width = ($y_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('y');
+ $y_tick_label_width = ($y_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('y');
+ $y_max_label_width = max($y_data_label_width, $y_tick_label_width);
+
+ // Calculate the space needed left and right of the plot for Y tick and Y data labels:
+ // (Y data labels here are for swapped X/Y plots such has horizontal bars)
+
+ // Left of the plot:
+ $tick_labels_left = ($y_tick_label_pos == 'plotleft' || $y_tick_label_pos == 'both'
+ || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'left'));
+ $data_labels_left = ($y_data_label_pos == 'plotleft' || $y_data_label_pos == 'both');
+ if ($tick_labels_left) {
+ if ($data_labels_left) {
+ $label_width_left = $y_max_label_width;
+ } else {
+ $label_width_left = $y_tick_label_width;
+ }
+ } elseif ($data_labels_left) {
+ $label_width_left = $y_data_label_width;
+ } else {
+ $label_width_left = 0;
+ }
+
+ // Right of the plot:
+ $tick_labels_right = ($y_tick_label_pos == 'plotright' || $y_tick_label_pos == 'both'
+ || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'right'));
+ $data_labels_right = ($y_data_label_pos == 'plotright' || $y_data_label_pos == 'both');
+ if ($tick_labels_right) {
+ if ($data_labels_right) {
+ $label_width_right = $y_max_label_width;
+ } else {
+ $label_width_right = $y_tick_label_width;
+ }
+ } elseif ($data_labels_right) {
+ $label_width_right = $y_data_label_width;
+ } else {
+ $label_width_right = 0;
+ }
+
+ ///////// Calculate margins:
+
+ // Calculating Top and Bottom margins:
+ // y_top_margin: Main title, Upper X title, X ticks and tick labels, and X data labels:
+ // y_bot_margin: Lower title, ticks and tick labels, and data labels:
+ $top_margin = $base_margin;
+ $bot_margin = $base_margin;
+ $this->x_title_top_offset = $gap;
+ $this->x_title_bot_offset = $gap;
+
+ // Space for main title?
+ if ($title_height > 0)
+ $top_margin += $title_height + $gap;
+
+ // Space for X Title?
+ if ($x_title_height > 0) {
+ $pos = $this->x_title_pos;
+ if ($pos == 'plotup' || $pos == 'both')
+ $top_margin += $x_title_height + $gap;
+ if ($pos == 'plotdown' || $pos == 'both')
+ $bot_margin += $x_title_height + $gap;
+ }
+
+ // Space for X Labels above the plot?
+ if ($label_height_above > 0) {
+ $top_margin += $label_height_above + $gap;
+ $this->x_title_top_offset += $label_height_above + $gap;
+ }
+
+ // Space for X Labels below the plot?
+ if ($label_height_below > 0) {
+ $bot_margin += $label_height_below + $gap;
+ $this->x_title_bot_offset += $label_height_below + $gap;
+ }
+
+ // Space for X Ticks above the plot?
+ if ($x_tick_pos == 'plotup' || $x_tick_pos == 'both'
+ || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'top')) {
+ $top_margin += $x_tick_len;
+ $this->x_label_top_offset = $x_tick_len + $gap;
+ $this->x_title_top_offset += $x_tick_len;
+ } else {
+ // No X Ticks above the plot:
+ $this->x_label_top_offset = $gap;
+ }
+
+ // Space for X Ticks below the plot?
+ if ($x_tick_pos == 'plotdown' || $x_tick_pos == 'both'
+ || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'bottom')) {
+ $bot_margin += $x_tick_len;
+ $this->x_label_bot_offset = $x_tick_len + $gap;
+ $this->x_title_bot_offset += $x_tick_len;
+ } else {
+ // No X Ticks below the plot:
+ $this->x_label_bot_offset = $gap;
+ }
+ // Label offsets for on-axis ticks:
+ if ($x_tick_pos == 'xaxis') {
+ $this->x_label_axis_offset = $x_tick_len + $gap;
+ } else {
+ $this->x_label_axis_offset = $gap;
+ }
+
+ // Calculating Left and Right margins:
+ // x_left_margin: Left Y title, Y ticks and tick labels:
+ // x_right_margin: Right Y title, Y ticks and tick labels:
+ $left_margin = $base_margin;
+ $right_margin = $base_margin;
+ $this->y_title_left_offset = $gap;
+ $this->y_title_right_offset = $gap;
+
+ // Space for Y Title?
+ if ($y_title_width > 0) {
+ $pos = $this->y_title_pos;
+ if ($pos == 'plotleft' || $pos == 'both')
+ $left_margin += $y_title_width + $gap;
+ if ($pos == 'plotright' || $pos == 'both')
+ $right_margin += $y_title_width + $gap;
+ }
+
+ // Space for Y Labels left of the plot?
+ if ($label_width_left > 0) {
+ $left_margin += $label_width_left + $gap;
+ $this->y_title_left_offset += $label_width_left + $gap;
+ }
+
+ // Space for Y Labels right of the plot?
+ if ($label_width_right > 0) {
+ $right_margin += $label_width_right + $gap;
+ $this->y_title_right_offset += $label_width_right + $gap;
+ }
+
+ // Space for Y Ticks left of plot?
+ if ($y_tick_pos == 'plotleft' || $y_tick_pos == 'both'
+ || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'left')) {
+ $left_margin += $y_tick_len;
+ $this->y_label_left_offset = $y_tick_len + $gap;
+ $this->y_title_left_offset += $y_tick_len;
+ } else {
+ // No Y Ticks left of plot:
+ $this->y_label_left_offset = $gap;
+ }
+
+ // Space for Y Ticks right of plot?
+ if ($y_tick_pos == 'plotright' || $y_tick_pos == 'both'
+ || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'right')) {
+ $right_margin += $y_tick_len;
+ $this->y_label_right_offset = $y_tick_len + $gap;
+ $this->y_title_right_offset += $y_tick_len;
+ } else {
+ // No Y Ticks right of plot:
+ $this->y_label_right_offset = $gap;
+ }
+
+ // Label offsets for on-axis ticks:
+ if ($x_tick_pos == 'yaxis') {
+ $this->y_label_axis_offset = $y_tick_len + $gap;
+ } else {
+ $this->y_label_axis_offset = $gap;
+ }
+
+ // Apply the minimum margins and store in the object.
+ // Do not set margins which were user-defined (see note at top of function).
+ if (!isset($this->y_top_margin))
+ $this->y_top_margin = max($min_margin, $top_margin);
+ if (!isset($this->y_bot_margin))
+ $this->y_bot_margin = max($min_margin, $bot_margin);
+ if (!isset($this->x_left_margin))
+ $this->x_left_margin = max($min_margin, $left_margin);
+ if (!isset($this->x_right_margin))
+ $this->x_right_margin = max($min_margin, $right_margin);
+
+ if ($this->GetCallback('debug_scale')) {
+ // (Too bad compact() doesn't work on class member variables...)
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'label_height_above' => $label_height_above,
+ 'label_height_below' => $label_height_below,
+ 'label_width_left' => $label_width_left,
+ 'label_width_right' => $label_width_right,
+ 'x_tick_len' => $x_tick_len,
+ 'y_tick_len' => $y_tick_len,
+ 'x_left_margin' => $this->x_left_margin,
+ 'x_right_margin' => $this->x_right_margin,
+ 'y_top_margin' => $this->y_top_margin,
+ 'y_bot_margin' => $this->y_bot_margin,
+ 'x_label_top_offset' => $this->x_label_top_offset,
+ 'x_label_bot_offset' => $this->x_label_bot_offset,
+ 'y_label_left_offset' => $this->y_label_left_offset,
+ 'y_label_right_offset' => $this->y_label_right_offset,
+ 'x_title_top_offset' => $this->x_title_top_offset,
+ 'x_title_bot_offset' => $this->x_title_bot_offset,
+ 'y_title_left_offset' => $this->y_title_left_offset,
+ 'y_title_right_offset' => $this->y_title_right_offset));
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * Calculate the plot area (device coordinates) from the margins.
+ * (This used to be part of SetPlotAreaPixels.)
+ * The margins might come from SetMarginsPixels, SetPlotAreaPixels,
+ * or CalcMargins.
+ */
+ protected function CalcPlotAreaPixels()
+ {
+ $this->plot_area = array($this->x_left_margin, $this->y_top_margin,
+ $this->image_width - $this->x_right_margin,
+ $this->image_height - $this->y_bot_margin);
+ $this->plot_area_width = $this->plot_area[2] - $this->plot_area[0];
+ $this->plot_area_height = $this->plot_area[3] - $this->plot_area[1];
+
+ $this->DoCallback('debug_scale', __FUNCTION__, $this->plot_area);
+ return TRUE;
+ }
+
+ /*
+ * Set the margins in pixels (left, right, top, bottom)
+ * This determines the plot area, equivalent to SetPlotAreaPixels().
+ * Deferred calculations now occur in CalcPlotAreaPixels().
+ */
+ function SetMarginsPixels($which_lm = NULL, $which_rm = NULL, $which_tm = NULL, $which_bm = NULL)
+ {
+ $this->x_left_margin = $which_lm;
+ $this->x_right_margin = $which_rm;
+ $this->y_top_margin = $which_tm;
+ $this->y_bot_margin = $which_bm;
+
+ return TRUE;
+ }
+
+ /*
+ * Sets the limits for the plot area.
+ * This stores the margins, not the area. That may seem odd, but
+ * the idea is to make SetPlotAreaPixels and SetMarginsPixels two
+ * ways to accomplish the same thing, and the deferred calculations
+ * in CalcMargins and CalcPlotAreaPixels don't need to know which
+ * was used.
+ * (x1, y1) - Upper left corner of the plot area
+ * (x2, y2) - Lower right corner of the plot area
+ */
+ function SetPlotAreaPixels($x1 = NULL, $y1 = NULL, $x2 = NULL, $y2 = NULL)
+ {
+ $this->x_left_margin = $x1;
+ if (isset($x2)) $this->x_right_margin = $this->image_width - $x2;
+ else unset($this->x_right_margin);
+ $this->y_top_margin = $y1;
+ if (isset($y2)) $this->y_bot_margin = $this->image_height - $y2;
+ else unset($this->y_bot_margin);
+
+ return TRUE;
+ }
+
+ /*
+ * Calculate the World Coordinate limits of the plot area.
+ * This goes with SetPlotAreaWorld, but the calculations are
+ * deferred until the graph is being drawn.
+ * Uses and sets: plot_min_x, plot_max_x, plot_min_y, plot_max_y
+ * These can be user-supplied or NULL to auto-calculate.
+ * Pre-requisites: FindDataLimits() calculates min_x, max_x, min_y, max_y
+ * which are the limits of the data to be plotted.
+ *
+ * The general method is this:
+ * If any part of the range is user-defined (via SetPlotAreaWorld),
+ * use the user-defined value.
+ * Else, if this is an implicitly-defined independent variable,
+ * use the fixed range of 0 to (max+1).
+ * Else, if this is an explicitly-defined independent variable,
+ * use the exact data range (min to max).
+ * Else, this is the dependent variable, so define a range which
+ * includes and exceeds the data range by a bit.
+ */
+ protected function CalcPlotAreaWorld()
+ {
+ // Data array omits X or Y?
+ $implied_x = $this->datatype_implied && !$this->datatype_swapped_xy;
+ $implied_y = $this->datatype_implied && $this->datatype_swapped_xy;
+
+ if (isset($this->plot_min_x) && $this->plot_min_x !== '')
+ $xmin = $this->plot_min_x; // Use user-provided value
+ elseif ($implied_x)
+ $xmin = 0; // Implied X starts at zero
+ elseif ($this->datatype_swapped_xy)
+ // If X is the dependent variable, leave some room below.
+ $xmin = floor($this->min_x - abs($this->min_x) * 0.1);
+ else
+ $xmin = $this->min_x; // Otherwise just start at the min data X
+
+ if (isset($this->plot_max_x) && $this->plot_max_x !== '')
+ $xmax = $this->plot_max_x; // Use user-provided value
+ elseif ($implied_x)
+ $xmax = $this->max_x + 1; // Implied X ends after last value
+ elseif ($this->datatype_swapped_xy)
+ // If X is the dependent variable, leave some room above.
+ $xmax = ceil($this->max_x + abs($this->max_x) * 0.1);
+ else
+ $xmax = $this->max_x; // Otherwise just end at the max data X
+
+ if (isset($this->plot_min_y) && $this->plot_min_y !== '')
+ $ymin = $this->plot_min_y; // Use user-provided value
+ elseif ($implied_y)
+ $ymin = 0; // Implied Y starts at zero
+ elseif ($this->datatype_swapped_xy)
+ $ymin = $this->min_y; // Start at min data Y
+ else
+ // If Y is the dependent variable, leave some room below.
+ $ymin = floor($this->min_y - abs($this->min_y) * 0.1);
+
+ if (isset($this->plot_max_y) && $this->plot_max_y !== '')
+ $ymax = $this->plot_max_y; // Use user-provided value
+ elseif ($implied_y)
+ $ymax = $this->max_y + 1; // Implied Y ends after last value
+ elseif ($this->datatype_swapped_xy)
+ $ymax = $this->max_y; // End at max data Y
+ else
+ // If Y is the dependent variable, leave some room above.
+ $ymax = ceil($this->max_y + abs($this->max_y) * 0.1);
+
+ // Error checking
+
+ if ($ymin == $ymax)
+ $ymax++;
+ if ($xmin == $xmax)
+ $xmax++;
+
+ if ($this->yscale_type == 'log') {
+ if ($ymin <= 0) {
+ $ymin = 1;
+ }
+ if ($ymax <= 0) {
+ // Note: Error messages reference the user function, not this function.
+ return $this->PrintError('SetPlotAreaWorld(): Log plots need data greater than 0');
+ }
+ }
+
+ if ($ymax <= $ymin) {
+ return $this->PrintError('SetPlotAreaWorld(): Error in data - max not greater than min');
+ }
+
+ $this->plot_min_x = $xmin;
+ $this->plot_max_x = $xmax;
+ $this->plot_min_y = $ymin;
+ $this->plot_max_y = $ymax;
+ if ($this->GetCallback('debug_scale')) {
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'plot_min_x' => $this->plot_min_x, 'plot_min_y' => $this->plot_min_y,
+ 'plot_max_x' => $this->plot_max_x, 'plot_max_y' => $this->plot_max_y));
+ }
+ return TRUE;
+ }
+
+ /*
+ * Stores the desired World Coordinate range of the plot.
+ * The user calls this to force one or more of the range limits to
+ * specific values. Anything not set will be calculated in CalcPlotAreaWorld().
+ */
+ function SetPlotAreaWorld($xmin=NULL, $ymin=NULL, $xmax=NULL, $ymax=NULL)
+ {
+ $this->plot_min_x = $xmin;
+ $this->plot_max_x = $xmax;
+ $this->plot_min_y = $ymin;
+ $this->plot_max_y = $ymax;
+ return TRUE;
+ }
+
+ /*
+ * Calculate the width (or height) of bars for bar plots.
+ * $stacked : If true, this is a stacked bar plot (1 bar per group).
+ * $verticals : If false, this is a horizontal bar plot.
+ * This calculates:
+ * record_bar_width : Allocated width for each bar (including gaps)
+ * actual_bar_width : Actual drawn width of each bar
+ * bar_adjust_gap : Gap on each side of each bar (0 if they touch)
+ * For the case $verticals=False, horizontal bars are being drawn,
+ * but the same variable names are used. Think of "bar_width" as being
+ * the width if you are standing on the Y axis looking towards positive X.
+ */
+ protected function CalcBarWidths($stacked, $verticals)
+ {
+ // group_width is the width of a group, including padding
+ if ($verticals) {
+ $group_width = $this->plot_area_width / $this->num_data_rows;
+ } else {
+ $group_width = $this->plot_area_height / $this->num_data_rows;
+ }
+
+ // Actual number of bar spaces in the group. This includes the drawn bars, and
+ // 'bar_extra_space'-worth of extra bars.
+ if ($stacked) {
+ $num_spots = 1 + $this->bar_extra_space;
+ } else {
+ $num_spots = $this->data_columns + $this->bar_extra_space;
+ }
+
+ // record_bar_width is the width of each bar's allocated area.
+ // If bar_width_adjust=1 this is the width of the bar, otherwise
+ // the bar is centered inside record_bar_width.
+ // The equation is:
+ // group_frac_width * group_width = record_bar_width * num_spots
+ $this->record_bar_width = $this->group_frac_width * $group_width / $num_spots;
+
+ // Note that the extra space due to group_frac_width and bar_extra_space will be
+ // evenly divided on each side of the group: the drawn bars are centered in the group.
+
+ // Within each bar's allocated space, if bar_width_adjust=1 the bar fills the
+ // space, otherwise it is centered.
+ // This is the actual drawn bar width:
+ $this->actual_bar_width = $this->record_bar_width * $this->bar_width_adjust;
+ // This is the gap on each side of the bar (0 if bar_width_adjust=1):
+ $this->bar_adjust_gap = ($this->record_bar_width - $this->actual_bar_width) / 2;
+
+ if ($this->GetCallback('debug_scale')) {
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'record_bar_width' => $this->record_bar_width,
+ 'actual_bar_width' => $this->actual_bar_width,
+ 'bar_adjust_gap' => $this->bar_adjust_gap));
+ }
+ return TRUE;
+ }
+
+ /*
+ * Calculate X and Y Axis Positions, world coordinates.
+ * This needs the min/max x/y range set by CalcPlotAreaWorld.
+ * It adjusts or sets x_axis_position and y_axis_position per the data.
+ * Empty string means the values need to be calculated; otherwise they
+ * are supplied but need to be validated against the World area.
+ *
+ * Note: This used to be in CalcTranslation, but CalcMargins needs it too.
+ * This does not calculate the pixel values of the axes. That happens in
+ * CalcTranslation, after scaling is set up (which has to happen after
+ * margins are set up).
+ *
+ * For vertical plots, the X axis defaults to Y=0 if that is inside the plot range, else whichever
+ * of the top or bottom that has the smallest absolute value (that is, the value closest to 0).
+ * The Y axis defaults to the left edge. For horizontal plots, the axis roles and defaults are switched.
+ */
+ protected function CalcAxisPositions()
+ {
+ // Validate user-provided X axis position, or calculate a default if not provided:
+ if ($this->x_axis_position !== '') {
+ // Force user-provided X axis position to be within the plot range:
+ $this->x_axis_position = min(max($this->plot_min_y, $this->x_axis_position), $this->plot_max_y);
+ } elseif ($this->yscale_type == 'log') {
+ // Always use 1 for X axis position on log scale plots.
+ $this->x_axis_position = 1;
+ } elseif ($this->datatype_swapped_xy || $this->plot_min_y > 0) {
+ // Horizontal plot, or Vertical Plot with all Y > 0: Place X axis on the bottom.
+ $this->x_axis_position = $this->plot_min_y;
+ } elseif ($this->plot_max_y < 0) {
+ // Vertical plot with all Y < 0, so place the X axis at the top.
+ $this->x_axis_position = $this->plot_max_y;
+ } else {
+ // Vertical plot range includes Y=0, so place X axis at 0.
+ $this->x_axis_position = 0;
+ }
+
+ // Validate user-provided Y axis position, or calculate a default if not provided:
+ if ($this->y_axis_position !== '') {
+ // Force user-provided Y axis position to be within the plot range:
+ $this->y_axis_position = min(max($this->plot_min_x, $this->y_axis_position), $this->plot_max_x);
+ } elseif ($this->xscale_type == 'log') {
+ // Always use 1 for Y axis position on log scale plots.
+ $this->y_axis_position = 1;
+ } elseif (!$this->datatype_swapped_xy || $this->plot_min_x > 0) {
+ // Vertical plot, or Horizontal Plot with all X > 0: Place Y axis on left side.
+ $this->y_axis_position = $this->plot_min_x;
+ } elseif ($this->plot_max_x < 0) {
+ // Horizontal plot with all X < 0, so place the Y axis on the right side.
+ $this->y_axis_position = $this->plot_max_x;
+ } else {
+ // Horizontal plot range includes X=0: place Y axis at 0.
+ $this->y_axis_position = 0;
+ }
+
+ if ($this->GetCallback('debug_scale')) {
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'x_axis_position' => $this->x_axis_position,
+ 'y_axis_position' => $this->y_axis_position));
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * Calculates scaling stuff...
+ */
+ protected function CalcTranslation()
+ {
+ if ($this->plot_max_x - $this->plot_min_x == 0) { // Check for div by 0
+ $this->xscale = 0;
+ } else {
+ if ($this->xscale_type == 'log') {
+ $this->xscale = $this->plot_area_width /
+ (log10($this->plot_max_x) - log10($this->plot_min_x));
+ } else {
+ $this->xscale = $this->plot_area_width / ($this->plot_max_x - $this->plot_min_x);
+ }
+ }
+
+ if ($this->plot_max_y - $this->plot_min_y == 0) { // Check for div by 0
+ $this->yscale = 0;
+ } else {
+ if ($this->yscale_type == 'log') {
+ $this->yscale = $this->plot_area_height /
+ (log10($this->plot_max_y) - log10($this->plot_min_y));
+ } else {
+ $this->yscale = $this->plot_area_height / ($this->plot_max_y - $this->plot_min_y);
+ }
+ }
+ // GD defines x = 0 at left and y = 0 at TOP so -/+ respectively
+ if ($this->xscale_type == 'log') {
+ $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * log10($this->plot_min_x) );
+ } else {
+ $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * $this->plot_min_x);
+ }
+ if ($this->yscale_type == 'log') {
+ $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * log10($this->plot_min_y));
+ } else {
+ $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * $this->plot_min_y);
+ }
+
+ // Convert axis positions to device coordinates:
+ $this->y_axis_x_pixels = $this->xtr($this->y_axis_position);
+ $this->x_axis_y_pixels = $this->ytr($this->x_axis_position);
+
+ if ($this->GetCallback('debug_scale')) {
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'xscale' => $this->xscale, 'yscale' => $this->yscale,
+ 'plot_origin_x' => $this->plot_origin_x, 'plot_origin_y' => $this->plot_origin_y,
+ 'y_axis_x_pixels' => $this->y_axis_x_pixels,
+ 'x_axis_y_pixels' => $this->x_axis_y_pixels));
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * Translate X world coordinate into pixel coordinate
+ * See CalcTranslation() for calculation of xscale.
+ * Note: This function should be 'protected', but is left public for historical reasons.
+ * See GetDeviceXY() for a preferred public method.
+ */
+ function xtr($x_world)
+ {
+ if ($this->xscale_type == 'log') {
+ $x_pixels = $this->plot_origin_x + log10($x_world) * $this->xscale ;
+ } else {
+ $x_pixels = $this->plot_origin_x + $x_world * $this->xscale ;
+ }
+ return round($x_pixels);
+ }
+
+ /*
+ * Translate Y world coordinate into pixel coordinate.
+ * See CalcTranslation() for calculation of yscale.
+ * Note: This function should be 'protected', but is left public for historical reasons.
+ * See GetDeviceXY() for a preferred public method.
+ */
+ function ytr($y_world)
+ {
+ if ($this->yscale_type == 'log') {
+ //minus because GD defines y = 0 at top. doh!
+ $y_pixels = $this->plot_origin_y - log10($y_world) * $this->yscale ;
+ } else {
+ $y_pixels = $this->plot_origin_y - $y_world * $this->yscale ;
+ }
+ return round($y_pixels);
+ }
+
+ /* A public interface to xtr and ytr. Translates (x,y) in world coordinates
+ * to (x,y) in device coordinates and returns them as an array.
+ * Usage is: list($x_pixel, $y_pixel) = $plot->GetDeviceXY($x_world, $y_world)
+ */
+ function GetDeviceXY($x_world, $y_world)
+ {
+ if (!isset($this->xscale)) {
+ return $this->PrintError("GetDeviceXY() was called before translation factors were calculated");
+ }
+ return array($this->xtr($x_world), $this->ytr($y_world));
+ }
+
+ /*
+ * Calculate tick parameters: Start, end, and delta values. This is used
+ * by both DrawXTicks() and DrawYTicks().
+ * This currently uses the same simplistic method previously used by
+ * PHPlot (basically just range/10), but splitting this out into its
+ * own function is the first step in replacing the method.
+ * This is also used by CalcMaxTickSize() for CalcMargins().
+ *
+ * $which : 'x' or 'y' : Which tick parameters to calculate
+ *
+ * Returns an array of 3 elements: tick_start, tick_end, tick_step
+ */
+ protected function CalcTicks($which)
+ {
+ if ($which == 'x') {
+ $num_ticks = $this->num_x_ticks;
+ $tick_inc = $this->x_tick_inc;
+ $data_max = $this->plot_max_x;
+ $data_min = $this->plot_min_x;
+ $skip_lo = $this->skip_left_tick;
+ $skip_hi = $this->skip_right_tick;
+ } elseif ($which == 'y') {
+ $num_ticks = $this->num_y_ticks;
+ $tick_inc = $this->y_tick_inc;
+ $data_max = $this->plot_max_y;
+ $data_min = $this->plot_min_y;
+ $skip_lo = $this->skip_bottom_tick;
+ $skip_hi = $this->skip_top_tick;
+ } else {
+ return $this->PrintError("CalcTicks: Invalid usage ($which)");
+ }
+
+ if (!empty($tick_inc)) {
+ $tick_step = $tick_inc;
+ } elseif (!empty($num_ticks)) {
+ $tick_step = ($data_max - $data_min) / $num_ticks;
+ } else {
+ $tick_step = ($data_max - $data_min) / 10;
+ }
+
+ // NOTE: When working with floats, because of approximations when adding $tick_step,
+ // the value may not quite reach the end, or may exceed it very slightly.
+ // So apply a "fudge" factor.
+ $tick_start = (double)$data_min;
+ $tick_end = (double)$data_max + ($data_max - $data_min) / 10000.0;
+
+ if ($skip_lo)
+ $tick_start += $tick_step;
+
+ if ($skip_hi)
+ $tick_end -= $tick_step;
+
+ return array($tick_start, $tick_end, $tick_step);
+ }
+
+ /*
+ * Calculate the size of the biggest tick label. This is used by CalcMargins().
+ * For 'x' ticks, it returns the height . For 'y' ticks, it returns the width.
+ * This means height along Y, or width along X - not relative to the text angle.
+ * That is what we need to calculate the needed margin space.
+ * (Previous versions of PHPlot estimated this, using the maximum X or Y value,
+ * or maybe the longest string. That doesn't work. -10 is longer than 9, etc.
+ * So this gets the actual size of each label, slow as that may be.
+ */
+ protected function CalcMaxTickLabelSize($which)
+ {
+ list($tick_start, $tick_end, $tick_step) = $this->CalcTicks($which);
+
+ if ($which == 'x') {
+ $font = $this->fonts['x_label'];
+ $angle = $this->x_label_angle;
+ } elseif ($which == 'y') {
+ $font = $this->fonts['y_label'];
+ $angle = $this->y_label_angle;
+ } else {
+ return $this->PrintError("CalcMaxTickLabelSize: Invalid usage ($which)");
+ }
+
+ $max_width = 0;
+ $max_height = 0;
+
+ // Loop over ticks, same as DrawXTicks and DrawYTicks:
+ // Avoid cumulative round-off errors from $val += $delta
+ $n = 0;
+ $tick_val = $tick_start;
+ while ($tick_val <= $tick_end) {
+ $tick_label = $this->FormatLabel($which, $tick_val);
+ list($width, $height) = $this->SizeText($font, $angle, $tick_label);
+ if ($width > $max_width) $max_width = $width;
+ if ($height > $max_height) $max_height = $height;
+ $tick_val = $tick_start + ++$n * $tick_step;
+ }
+ if ($this->GetCallback('debug_scale')) {
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'which' => $which, 'height' => $max_height, 'width' => $max_width));
+ }
+
+ if ($which == 'x')
+ return $max_height;
+ return $max_width;
+ }
+
+ /*
+ * Calculate the size of the biggest data label. This is used by CalcMargins().
+ * For $which='x', it returns the height of labels along the top or bottom.
+ * For $which='y', it returns the width of labels along the left or right sides.
+ * There is only one set of data labels (the first position in each data record).
+ * They normally go along the top or bottom (or both). If the data type indicates
+ * X/Y swapping (which is used for horizontal bar charts), the data labels go
+ * along the sides instead. So CalcMaxDataLabelSize('x') returns 0 if the
+ * data is X/Y swapped, and CalcMaxDataLabelSize('y') returns 0 if the data is
+ * is not X/Y swapped.
+ */
+ protected function CalcMaxDataLabelSize($which = 'x')
+ {
+ if ($which == 'x') {
+ if ($this->datatype_swapped_xy)
+ return 0; // Shortcut: labels aren't on top/bottom.
+ $font = $this->fonts['x_label'];
+ $angle = $this->x_data_label_angle;
+ $format_code = 'xd';
+ } elseif ($which == 'y') {
+ if (!$this->datatype_swapped_xy)
+ return 0; // Shortcut: labels aren't on left/right.
+ $font = $this->fonts['y_label'];
+ $angle = $this->y_data_label_angle;
+ $format_code = 'yd';
+ } else {
+ return $this->PrintError("CalcMaxDataLabelSize: Invalid usage ($which)");
+ }
+ $max_width = 0;
+ $max_height = 0;
+
+ // Loop over all data labels and find the biggest:
+ for ($i = 0; $i < $this->num_data_rows; $i++) {
+ $label = $this->FormatLabel($format_code, $this->data[$i][0]);
+ list($width, $height) = $this->SizeText($font, $angle, $label);
+ if ($width > $max_width) $max_width = $width;
+ if ($height > $max_height) $max_height = $height;
+ }
+ if ($this->GetCallback('debug_scale')) {
+ $this->DoCallback('debug_scale', __FUNCTION__, array(
+ 'height' => $max_height, 'width' => $max_width));
+ }
+
+ if ($this->datatype_swapped_xy)
+ return $max_width;
+ return $max_height;
+ }
+
+ /*
+ * Set grid control defaults.
+ * X grid defaults off, Y grid defaults on, except the reverse is true
+ * with swapped graphs such as horizontal bars.
+ */
+ protected function CalcGridSettings()
+ {
+ if (!isset($this->draw_x_grid))
+ $this->draw_x_grid = $this->datatype_swapped_xy;
+ if (!isset($this->draw_y_grid))
+ $this->draw_y_grid = !$this->datatype_swapped_xy;
+ }
+
+ /*
+ * Helper for CheckLabels() - determine if there are any non-empty labels.
+ * Returns True if all data labels are empty, else False.
+ */
+ protected function CheckLabelsAllEmpty()
+ {
+ for ($i = 0; $i < $this->num_data_rows; $i++)
+ if ($this->data[$i][0] !== '') return FALSE;
+ return TRUE;
+ }
+
+ /*
+ * Check and set label parameters. This handles deferred processing for label
+ * positioning and other label-related parameters.
+ * Copy label_format from 'x' to 'xd', and 'y' to 'yd', if not already set.
+ * Set x_data_label_angle from x_label_angle, if not already set.
+ * Apply defaults to X and Y tick and data label positions.
+ * Note: the label strings in the data array are used as X data labels in
+ * the normal case, but as Y data labels in the swapped X/Y case.
+ */
+ protected function CheckLabels()
+ {
+ // The X and Y data labels are formatted the same as X and Y tick labels,
+ // unless overridden. Check and apply defaults for FormatLabel here:
+ if (empty($this->label_format['xd']) && !empty($this->label_format['x']))
+ $this->label_format['xd'] = $this->label_format['x'];
+ if (empty($this->label_format['yd']) && !empty($this->label_format['y']))
+ $this->label_format['yd'] = $this->label_format['y'];
+
+ // The X tick label angle setting controls X data label angles too,
+ // unless overridden. Check and apply the default here:
+ if (!isset($this->x_data_label_angle))
+ $this->x_data_label_angle = $this->x_label_angle;
+ // Note: Y data label angle defaults to zero, unlike X,
+ // for compatibility with older releases.
+
+ // X Label position fixups, for x_data_label_pos and x_tick_label_pos:
+ if ($this->datatype_swapped_xy) {
+ // Just apply defaults - there is no position conflict for X labels.
+ if (!isset($this->x_tick_label_pos))
+ $this->x_tick_label_pos = 'plotdown';
+ if (!isset($this->x_data_label_pos))
+ $this->x_data_label_pos = 'none';
+ } else {
+ // Apply defaults but do not allow conflict between tick and data labels.
+ if (isset($this->x_data_label_pos)) {
+ if (!isset($this->x_tick_label_pos)) {
+ // Case: data_label_pos is set, tick_label_pos needs a default:
+ if ($this->x_data_label_pos == 'none')
+ $this->x_tick_label_pos = 'plotdown';
+ else
+ $this->x_tick_label_pos = 'none';
+ }
+ } elseif (isset($this->x_tick_label_pos)) {
+ // Case: tick_label_pos is set, data_label_pos needs a default:
+ if ($this->x_tick_label_pos == 'none')
+ $this->x_data_label_pos = 'plotdown';
+ else
+ $this->x_data_label_pos = 'none';
+ } else {
+ // Case: Neither tick_label_pos nor data_label_pos is set.
+ // We do not want them to be both on (as PHPlot used to do in this case).
+ // Turn on data labels if any were supplied, else tick labels.
+ if ($this->CheckLabelsAllEmpty()) {
+ $this->x_data_label_pos = 'none';
+ $this->x_tick_label_pos = 'plotdown';
+ } else {
+ $this->x_data_label_pos = 'plotdown';
+ $this->x_tick_label_pos = 'none';
+ }
+ }
+ }
+
+ // Y Label position fixups, for y_data_label_pos and y_tick_label_pos:
+ if (!$this->datatype_swapped_xy) {
+ // Just apply defaults - there is no position conflict.
+ if (!isset($this->y_tick_label_pos))
+ $this->y_tick_label_pos = 'plotleft';
+ if (!isset($this->y_data_label_pos))
+ $this->y_data_label_pos = 'none';
+ } else {
+ // Apply defaults but do not allow conflict between tick and data labels.
+ if (isset($this->y_data_label_pos)) {
+ if (!isset($this->y_tick_label_pos)) {
+ // Case: data_label_pos is set, tick_label_pos needs a default:
+ if ($this->y_data_label_pos == 'none')
+ $this->y_tick_label_pos = 'plotleft';
+ else
+ $this->y_tick_label_pos = 'none';
+ }
+ } elseif (isset($this->y_tick_label_pos)) {
+ // Case: tick_label_pos is set, data_label_pos needs a default:
+ if ($this->y_tick_label_pos == 'none')
+ $this->y_data_label_pos = 'plotleft';
+ else
+ $this->y_data_label_pos = 'none';
+ } else {
+ // Case: Neither tick_label_pos nor data_label_pos is set.
+ // Turn on data labels if any were supplied, else tick labels.
+ if ($this->CheckLabelsAllEmpty()) {
+ $this->y_data_label_pos = 'none';
+ $this->y_tick_label_pos = 'plotleft';
+ } else {
+ $this->y_data_label_pos = 'plotleft';
+ $this->y_tick_label_pos = 'none';
+ }
+ }
+ }
+ return TRUE;
+ }
+
+ /*
+ * Formats a tick or data label.
+ * which_pos - 'x', 'xd', 'y', or 'yd', selects formatting controls.
+ * x, y are for tick labels; xd, yd are for data labels.
+ * which_lab - String to format as a label.
+ * Credits: Time formatting suggested by Marlin Viss
+ * Custom formatting suggested by zer0x333
+ * Notes:
+ * Type 'title' is obsolete and retained for compatibility.
+ * Class variable 'data_units_text' is retained as a suffix for 'data' type formatting for
+ * backward compatibility. Since there was never a function/method to set it, there
+ * could be somebody out there who sets it directly in the object.
+ */
+ protected function FormatLabel($which_pos, $which_lab)
+ {
+ // Assign a reference shortcut to the label format controls.
+ // Note CheckLabels() made sure the 'xd' and 'yd' arrays are set.
+ $format =& $this->label_format[$which_pos];
+
+ // Don't format empty strings (especially as time or numbers), or if no type was set.
+ if ($which_lab !== '' && !empty($format['type'])) {
+ switch ($format['type']) {
+ case 'title': // Note: This is obsolete
+ $which_lab = @ $this->data[$which_lab][0];
+ break;
+ case 'data':
+ $which_lab = $format['prefix']
+ . $this->number_format($which_lab, $format['precision'])
+ . $this->data_units_text // Obsolete
+ . $format['suffix'];
+ break;
+ case 'time':
+ $which_lab = strftime($format['time_format'], $which_lab);
+ break;
+ case 'printf':
+ $which_lab = sprintf($format['printf_format'], $which_lab);
+ break;
+ case 'custom':
+ $which_lab = call_user_func($format['custom_callback'], $which_lab, $format['custom_arg']);
+ break;
+
+ }
+ }
+ return $which_lab;
+ }
+
+/////////////////////////////////////////////
+/////////////// TICKS
+/////////////////////////////////////////////
+
+ /*
+ * Set the step (interval) between X ticks.
+ * Use either this or SetNumXTicks(), not both, to control the X tick marks.
+ */
+ function SetXTickIncrement($which_ti='')
+ {
+ $this->x_tick_inc = $which_ti;
+ if (!empty($which_ti)) {
+ $this->num_x_ticks = '';
+ }
+ return TRUE;
+ }
+
+ /*
+ * Set the step (interval) between Y ticks.
+ * Use either this or SetNumYTicks(), not both, to control the Y tick marks.
+ */
+ function SetYTickIncrement($which_ti='')
+ {
+ $this->y_tick_inc = $which_ti;
+ if (!empty($which_ti)) {
+ $this->num_y_ticks = '';
+ }
+ return TRUE;
+ }
+
+ /*
+ * Set the number of X tick marks.
+ * Use either this or SetXTickIncrement(), not both, to control the X tick marks.
+ */
+ function SetNumXTicks($which_nt='')
+ {
+ $this->num_x_ticks = $which_nt;
+ if (!empty($which_nt)) {
+ $this->x_tick_inc = '';
+ }
+ return TRUE;
+ }
+
+ /*
+ * Set the number of Y tick marks.
+ * Use either this or SetYTickIncrement(), not both, to control the Y tick marks.
+ */
+ function SetNumYTicks($which_nt='')
+ {
+ $this->num_y_ticks = $which_nt;
+ if (!empty($which_nt)) {
+ $this->y_tick_inc = ''; //either use num_y_ticks or y_tick_inc, not both
+ }
+ return TRUE;
+ }
+
+ /*
+ * Set the position for the X tick marks.
+ * These can be above the plot, below, both positions, at the X axis, or suppressed.
+ */
+ function SetXTickPos($which_tp)
+ {
+ $this->x_tick_pos = $this->CheckOption($which_tp, 'plotdown, plotup, both, xaxis, none',
+ __FUNCTION__);
+ return (boolean)$this->x_tick_pos;
+ }
+
+ /*
+ * Set the position for the Y tick marks.
+ * These can be left of the plot, right, both positions, at the Y axis, or suppressed.
+ */
+ function SetYTickPos($which_tp)
+ {
+ $this->y_tick_pos = $this->CheckOption($which_tp, 'plotleft, plotright, both, yaxis, none',
+ __FUNCTION__);
+ return (boolean)$this->y_tick_pos;
+ }
+
+ /*
+ * Skip the top-most Y axis tick mark and label if $skip is true.
+ */
+ function SetSkipTopTick($skip)
+ {
+ $this->skip_top_tick = (bool)$skip;
+ return TRUE;
+ }
+
+ /*
+ * Skip the bottom-most Y axis tick mark and label if $skip is true.
+ */
+ function SetSkipBottomTick($skip)
+ {
+ $this->skip_bottom_tick = (bool)$skip;
+ return TRUE;
+ }
+
+ /*
+ * Skip the left-most X axis tick mark and label if $skip is true.
+ */
+ function SetSkipLeftTick($skip)
+ {
+ $this->skip_left_tick = (bool)$skip;
+ return TRUE;
+ }
+
+ /*
+ * Skip the right-most X axis tick mark and label if $skip is true.
+ */
+ function SetSkipRightTick($skip)
+ {
+ $this->skip_right_tick = (bool)$skip;
+ return TRUE;
+ }
+
+ /*
+ * Set the outer length of X tick marks to $which_xln pixels.
+ * This is the part of the tick mark that sticks out from the plot area.
+ */
+ function SetXTickLength($which_xln)
+ {
+ $this->x_tick_length = $which_xln;
+ return TRUE;
+ }
+
+ /*
+ * Set the outer length of Y tick marks to $which_yln pixels.
+ * This is the part of the tick mark that sticks out from the plot area.
+ */
+ function SetYTickLength($which_yln)
+ {
+ $this->y_tick_length = $which_yln;
+ return TRUE;
+ }
+
+ /*
+ * Set the crossing length of X tick marks to $which_xc pixels.
+ * This is the part of the tick mark that sticks into the plot area.
+ */
+ function SetXTickCrossing($which_xc)
+ {
+ $this->x_tick_cross = $which_xc;
+ return TRUE;
+ }
+
+ /*
+ * Set the crossing length of Y tick marks to $which_yc pixels.
+ * This is the part of the tick mark that sticks into the plot area.
+ */
+ function SetYTickCrossing($which_yc)
+ {
+ $this->y_tick_cross = $which_yc;
+ return TRUE;
+ }
+
+/////////////////////////////////////////////
+//////////////////// GENERIC DRAWING
+/////////////////////////////////////////////
+
+ /*
+ * Fill the image background, with a tiled image file or solid color.
+ */
+ protected function DrawBackground()
+ {
+ // Don't draw this twice if drawing two plots on one image
+ if (empty($this->done['background'])) {
+ if (isset($this->bgimg)) { // If bgimg is defined, use it
+ $this->tile_img($this->bgimg, 0, 0, $this->image_width, $this->image_height, $this->bgmode);
+ } else { // Else use solid color
+ ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height,
+ $this->ndx_bg_color);
+ }
+ $this->done['background'] = TRUE;
+ }
+ return TRUE;
+ }
+
+ /*
+ * Fill the plot area background, with a tiled image file or solid color.
+ */
+ protected function DrawPlotAreaBackground()
+ {
+ if (isset($this->plotbgimg)) {
+ $this->tile_img($this->plotbgimg, $this->plot_area[0], $this->plot_area[1],
+ $this->plot_area_width, $this->plot_area_height, $this->plotbgmode);
+ } elseif ($this->draw_plot_area_background) {
+ ImageFilledRectangle($this->img, $this->plot_area[0], $this->plot_area[1],
+ $this->plot_area[2], $this->plot_area[3], $this->ndx_plot_bg_color);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Tiles an image at some given coordinates.
+ * $file : Filename of the picture to be used as tile.
+ * $xorig : X device coordinate of where the tile is to begin.
+ * $yorig : Y device coordinate of where the tile is to begin.
+ * $width : Width of the area to be tiled.
+ * $height : Height of the area to be tiled.
+ * $mode : Tiling mode. One of 'centeredtile', 'tile', 'scale'.
+ */
+ protected function tile_img($file, $xorig, $yorig, $width, $height, $mode)
+ {
+ $im = $this->GetImage($file, $tile_width, $tile_height);
+ if (!$im)
+ return FALSE; // GetImage already produced an error message.
+
+ if ($mode == 'scale') {
+ imagecopyresampled($this->img, $im, $xorig, $yorig, 0, 0, $width, $height,
+ $tile_width, $tile_height);
+ return TRUE;
+ }
+
+ if ($mode == 'centeredtile') {
+ $x0 = - floor($tile_width/2); // Make the tile look better
+ $y0 = - floor($tile_height/2);
+ } else { // Accept anything else as $mode == 'tile'
+ $x0 = 0;
+ $y0 = 0;
+ }
+
+ // Draw the tile onto a temporary image first.
+ $tmp = imagecreate($width, $height);
+ if (! $tmp)
+ return $this->PrintError('tile_img(): Could not create image resource.');
+
+ for ($x = $x0; $x < $width; $x += $tile_width)
+ for ($y = $y0; $y < $height; $y += $tile_height)
+ imagecopy($tmp, $im, $x, $y, 0, 0, $tile_width, $tile_height);
+
+ // Copy the temporary image onto the final one.
+ imagecopy($this->img, $tmp, $xorig, $yorig, 0,0, $width, $height);
+
+ // Free resources
+ imagedestroy($tmp);
+ imagedestroy($im);
+
+ return TRUE;
+ }
+
+ /*
+ * Return the image border width.
+ * This is used by CalcMargins() and DrawImageBorder().
+ */
+ protected function GetImageBorderWidth()
+ {
+ if ($this->image_border_type == 'none')
+ return 0; // No border
+ if (!empty($this->image_border_width))
+ return $this->image_border_width; // Specified border width
+ if ($this->image_border_type == 'raised')
+ return 2; // Default for raised border is 2 pixels.
+ return 1; // Default for other border types is 1 pixel.
+ }
+
+ /*
+ * Draws a border around the final image.
+ * Note: 'plain' draws a flat border using the dark shade of the border color.
+ * This probably should have been written to use the actual border color, but
+ * it is too late to fix it without changing plot appearances. Therefore a
+ * new type 'solid' was added to use the SetImageBorderColor color.
+ */
+ protected function DrawImageBorder()
+ {
+ // Do nothing if already drawn, or if no border has been set.
+ if ($this->image_border_type == 'none' || !empty($this->done['border']))
+ return TRUE;
+ $width = $this->GetImageBorderWidth();
+ $color1 = $this->ndx_i_border;
+ $color2 = $this->ndx_i_border_dark;
+ $ex = $this->image_width - 1;
+ $ey = $this->image_height - 1;
+ switch ($this->image_border_type) {
+ case 'raised':
+ // Top and left lines use border color, right and bottom use the darker shade.
+ // Drawing order matters in the upper right and lower left corners.
+ for ($i = 0; $i < $width; $i++, $ex--, $ey--) {
+ imageline($this->img, $i, $i, $ex, $i, $color1); // Top
+ imageline($this->img, $ex, $i, $ex, $ey, $color2); // Right
+ imageline($this->img, $i, $i, $i, $ey, $color1); // Left
+ imageline($this->img, $i, $ey, $ex, $ey, $color2); // Bottom
+ }
+ break;
+ case 'plain': // See note above re colors
+ $color1 = $color2;
+ // Fall through
+ case 'solid':
+ for ($i = 0; $i < $width; $i++, $ex--, $ey--) {
+ imagerectangle($this->img, $i, $i, $ex, $ey, $color1);
+ }
+ break;
+ default:
+ return $this->PrintError(
+ "DrawImageBorder(): unknown image_border_type: '$this->image_border_type'");
+ }
+ $this->done['border'] = TRUE; // Border should only be drawn once per image.
+ return TRUE;
+ }
+
+ /*
+ * Draws the main title on the graph.
+ * The title must not be drawn more than once (in the case of multiple plots
+ * on the image), because TTF text antialiasing makes it look bad.
+ */
+ protected function DrawTitle()
+ {
+ if (!empty($this->done['title']) || $this->title_txt === '')
+ return TRUE;
+
+ // Center of the image:
+ $xpos = $this->image_width / 2;
+
+ // Place it at almost at the top
+ $ypos = $this->title_offset;
+
+ $this->DrawText($this->fonts['title'], 0, $xpos, $ypos,
+ $this->ndx_title_color, $this->title_txt, 'center', 'top');
+
+ $this->done['title'] = TRUE;
+ return TRUE;
+ }
+
+ /*
+ * Draws the X-Axis Title
+ */
+ protected function DrawXTitle()
+ {
+ if ($this->x_title_pos == 'none')
+ return TRUE;
+
+ // Center of the plot
+ $xpos = ($this->plot_area[2] + $this->plot_area[0]) / 2;
+
+ // Upper title
+ if ($this->x_title_pos == 'plotup' || $this->x_title_pos == 'both') {
+ $ypos = $this->plot_area[1] - $this->x_title_top_offset;
+ $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_x_title_color,
+ $this->x_title_txt, 'center', 'bottom');
+ }
+ // Lower title
+ if ($this->x_title_pos == 'plotdown' || $this->x_title_pos == 'both') {
+ $ypos = $this->plot_area[3] + $this->x_title_bot_offset;
+ $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_x_title_color,
+ $this->x_title_txt, 'center', 'top');
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draws the Y-Axis Title
+ */
+ protected function DrawYTitle()
+ {
+ if ($this->y_title_pos == 'none')
+ return TRUE;
+
+ // Center the title vertically to the plot area
+ $ypos = ($this->plot_area[3] + $this->plot_area[1]) / 2;
+
+ if ($this->y_title_pos == 'plotleft' || $this->y_title_pos == 'both') {
+ $xpos = $this->plot_area[0] - $this->y_title_left_offset;
+ $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_y_title_color,
+ $this->y_title_txt, 'right', 'center');
+ }
+ if ($this->y_title_pos == 'plotright' || $this->y_title_pos == 'both') {
+ $xpos = $this->plot_area[2] + $this->y_title_right_offset;
+ $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_y_title_color,
+ $this->y_title_txt, 'left', 'center');
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * Draw the X axis, including ticks and labels, and X (vertical) grid lines.
+ */
+ protected function DrawXAxis()
+ {
+ // Draw ticks, labels and grid
+ $this->DrawXTicks();
+
+ //Draw X Axis at Y = x_axis_y_pixels, unless suppressed (See SetXAxisPosition)
+ if (empty($this->suppress_x_axis)) {
+ ImageLine($this->img, $this->plot_area[0]+1, $this->x_axis_y_pixels,
+ $this->plot_area[2]-1, $this->x_axis_y_pixels, $this->ndx_grid_color);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw the Y axis, including ticks and labels, and Y (horizontal) grid lines.
+ * Horizontal grid lines overwrite horizontal axis with y=0, so call this first, then DrawXAxis()
+ */
+ protected function DrawYAxis()
+ {
+ // Draw ticks, labels and grid
+ $this->DrawYTicks();
+
+ // Draw Y axis at X = y_axis_x_pixels, unless suppressed (See SetYAxisPosition)
+ if (empty($this->suppress_y_axis)) {
+ ImageLine($this->img, $this->y_axis_x_pixels, $this->plot_area[1],
+ $this->y_axis_x_pixels, $this->plot_area[3], $this->ndx_grid_color);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw one X tick mark and its tick label.
+ * $which_xlab : Formatted X value for the label.
+ * $which_xpix : X device coordinate for this tick mark.
+ */
+ protected function DrawXTick($which_xlab, $which_xpix)
+ {
+ // Ticks on X axis
+ if ($this->x_tick_pos == 'xaxis') {
+ ImageLine($this->img, $which_xpix, $this->x_axis_y_pixels - $this->x_tick_cross,
+ $which_xpix, $this->x_axis_y_pixels + $this->x_tick_length, $this->ndx_tick_color);
+ }
+
+ // Ticks on top of the Plot Area
+ if ($this->x_tick_pos == 'plotup' || $this->x_tick_pos == 'both') {
+ ImageLine($this->img, $which_xpix, $this->plot_area[1] - $this->x_tick_length,
+ $which_xpix, $this->plot_area[1] + $this->x_tick_cross, $this->ndx_tick_color);
+ }
+
+ // Ticks on bottom of Plot Area
+ if ($this->x_tick_pos == 'plotdown' || $this->x_tick_pos == 'both') {
+ ImageLine($this->img, $which_xpix, $this->plot_area[3] + $this->x_tick_length,
+ $which_xpix, $this->plot_area[3] - $this->x_tick_cross, $this->ndx_tick_color);
+ }
+
+ // Label on X axis
+ if ($this->x_tick_label_pos == 'xaxis') {
+ $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
+ $which_xpix, $this->x_axis_y_pixels + $this->x_label_axis_offset,
+ $this->ndx_text_color, $which_xlab, 'center', 'top');
+ }
+
+ // Label on top of the Plot Area
+ if ($this->x_tick_label_pos == 'plotup' || $this->x_tick_label_pos == 'both') {
+ $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
+ $which_xpix, $this->plot_area[1] - $this->x_label_top_offset,
+ $this->ndx_text_color, $which_xlab, 'center', 'bottom');
+ }
+
+ // Label on bottom of the Plot Area
+ if ($this->x_tick_label_pos == 'plotdown' || $this->x_tick_label_pos == 'both') {
+ $this->DrawText($this->fonts['x_label'], $this->x_label_angle,
+ $which_xpix, $this->plot_area[3] + $this->x_label_bot_offset,
+ $this->ndx_text_color, $which_xlab, 'center', 'top');
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw one Y tick mark and its tick label. Called from DrawYTicks() and DrawXAxis()
+ * $which_ylab : Formatted Y value for the label.
+ * $which_ypix : Y device coordinate for this tick mark.
+ */
+ protected function DrawYTick($which_ylab, $which_ypix)
+ {
+ // Ticks on Y axis
+ if ($this->y_tick_pos == 'yaxis') {
+ ImageLine($this->img, $this->y_axis_x_pixels - $this->y_tick_length, $which_ypix,
+ $this->y_axis_x_pixels + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
+ }
+
+ // Ticks to the left of the Plot Area
+ if (($this->y_tick_pos == 'plotleft') || ($this->y_tick_pos == 'both') ) {
+ ImageLine($this->img, $this->plot_area[0] - $this->y_tick_length, $which_ypix,
+ $this->plot_area[0] + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
+ }
+
+ // Ticks to the right of the Plot Area
+ if (($this->y_tick_pos == 'plotright') || ($this->y_tick_pos == 'both') ) {
+ ImageLine($this->img, $this->plot_area[2] + $this->y_tick_length, $which_ypix,
+ $this->plot_area[2] - $this->y_tick_cross, $which_ypix, $this->ndx_tick_color);
+ }
+
+ // Labels on Y axis
+ if ($this->y_tick_label_pos == 'yaxis') {
+ $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
+ $this->y_axis_x_pixels - $this->y_label_axis_offset, $which_ypix,
+ $this->ndx_text_color, $which_ylab, 'right', 'center');
+ }
+
+ // Labels to the left of the plot area
+ if ($this->y_tick_label_pos == 'plotleft' || $this->y_tick_label_pos == 'both') {
+ $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
+ $this->plot_area[0] - $this->y_label_left_offset, $which_ypix,
+ $this->ndx_text_color, $which_ylab, 'right', 'center');
+ }
+ // Labels to the right of the plot area
+ if ($this->y_tick_label_pos == 'plotright' || $this->y_tick_label_pos == 'both') {
+ $this->DrawText($this->fonts['y_label'], $this->y_label_angle,
+ $this->plot_area[2] + $this->y_label_right_offset, $which_ypix,
+ $this->ndx_text_color, $which_ylab, 'left', 'center');
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draws Grid, Ticks and Tick Labels along X-Axis
+ * Ticks and tick labels can be down of plot only, up of plot only,
+ * both on up and down of plot, or crossing a user defined X-axis
+ *
+ * Original vertical code submitted by Marlin Viss
+ */
+ protected function DrawXTicks()
+ {
+ // Sets the line style for IMG_COLOR_STYLED lines (grid)
+ if ($this->dashed_grid) {
+ $this->SetDashedStyle($this->ndx_light_grid_color);
+ $style = IMG_COLOR_STYLED;
+ } else {
+ $style = $this->ndx_light_grid_color;
+ }
+
+ // Calculate the tick start, end, and step:
+ list($x_start, $x_end, $delta_x) = $this->CalcTicks('x');
+
+ // Loop, avoiding cumulative round-off errors from $x_tmp += $delta_x
+ $n = 0;
+ $x_tmp = $x_start;
+ while ($x_tmp <= $x_end) {
+ $xlab = $this->FormatLabel('x', $x_tmp);
+ $x_pixels = $this->xtr($x_tmp);
+
+ // Vertical grid lines
+ if ($this->draw_x_grid) {
+ ImageLine($this->img, $x_pixels, $this->plot_area[1], $x_pixels, $this->plot_area[3], $style);
+ }
+
+ // Draw tick mark(s)
+ $this->DrawXTick($xlab, $x_pixels);
+
+ // Step to next X, without accumulating error
+ $x_tmp = $x_start + ++$n * $delta_x;
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw the grid, ticks, and tick labels along the Y axis.
+ * Ticks and tick labels can be left of plot only, right of plot only,
+ * both on the left and right of plot, or crossing a user defined Y-axis
+ */
+ protected function DrawYTicks()
+ {
+ // Sets the line style for IMG_COLOR_STYLED lines (grid)
+ if ($this->dashed_grid) {
+ $this->SetDashedStyle($this->ndx_light_grid_color);
+ $style = IMG_COLOR_STYLED;
+ } else {
+ $style = $this->ndx_light_grid_color;
+ }
+
+ // Calculate the tick start, end, and step:
+ list($y_start, $y_end, $delta_y) = $this->CalcTicks('y');
+
+ // Loop, avoiding cumulative round-off errors from $y_tmp += $delta_y
+ $n = 0;
+ $y_tmp = $y_start;
+ while ($y_tmp <= $y_end) {
+ $ylab = $this->FormatLabel('y', $y_tmp);
+ $y_pixels = $this->ytr($y_tmp);
+
+ // Horizontal grid line
+ if ($this->draw_y_grid) {
+ ImageLine($this->img, $this->plot_area[0]+1, $y_pixels, $this->plot_area[2]-1,
+ $y_pixels, $style);
+ }
+
+ // Draw tick mark(s)
+ $this->DrawYTick($ylab, $y_pixels);
+
+ // Step to next Y, without accumulating error
+ $y_tmp = $y_start + ++$n * $delta_y;
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw a border around the plot area. See SetPlotBorderType.
+ * Note: SetPlotBorderType sets plot_border_type to an array, but
+ * it won't be an array if it defaults or is set directly (backward compatibility).
+ */
+ protected function DrawPlotBorder()
+ {
+ $pbt = (array)$this->plot_border_type;
+ $sides = 0; // Bitmap: 1=left 2=top 4=right 8=bottom
+ $map = array('left' => 1, 'plotleft' => 1, 'right' => 4, 'plotright' => 4, 'top' => 2,
+ 'bottom' => 8, 'both' => 5, 'sides' => 5, 'full' => 15, 'none' => 0);
+ foreach ($pbt as $option) $sides |= $map[$option];
+ if ($sides == 15) { // Border on all 4 sides
+ imagerectangle($this->img, $this->plot_area[0], $this->plot_area[1],
+ $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
+ } else {
+ if ($sides & 1) // Left
+ imageline($this->img, $this->plot_area[0], $this->plot_area[1],
+ $this->plot_area[0], $this->plot_area[3], $this->ndx_grid_color);
+ if ($sides & 2) // Top
+ imageline($this->img, $this->plot_area[0], $this->plot_area[1],
+ $this->plot_area[2], $this->plot_area[1], $this->ndx_grid_color);
+ if ($sides & 4) // Right
+ imageline($this->img, $this->plot_area[2], $this->plot_area[1],
+ $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
+ if ($sides & 8) // Bottom
+ imageline($this->img, $this->plot_area[0], $this->plot_area[3],
+ $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw the data value label associated with a point in the plot.
+ * These are labels that show the value (dependent variable, usually Y) of the data point,
+ * and are drawn within the plot area (not to be confused with axis data labels).
+ *
+ * $x_or_y : Specify 'x' or 'y' labels. This selects font, angle, and formatting.
+ * $x_world, $y_world : World coordinates of the text (see also x/y_adjustment).
+ * $text : The text to draw, after formatting with FormatLabel().
+ * $halign, $valign : Selects from 9-point text alignment.
+ * $x_adjustment, $y_adjustment : Text position offsets, in device coordinates.
+ * $min_width, $min_height : If supplied, suppress the text if it will not fit.
+ * Returns True, if the text was drawn, or False, if it will not fit.
+ */
+ protected function DrawDataValueLabel($x_or_y, $x_world, $y_world, $text, $halign, $valign,
+ $x_adjustment=0, $y_adjustment=0, $min_width=NULL, $min_height=NULL)
+ {
+ if ($x_or_y == 'x') {
+ $angle = $this->x_data_label_angle;
+ $font = $this->fonts['x_label'];
+ $formatted_text = $this->FormatLabel('xd', $text);
+ } else { // Assumed 'y'
+ $angle = $this->y_data_label_angle;
+ $font = $this->fonts['y_label'];
+ $formatted_text = $this->FormatLabel('yd', $text);
+ }
+ $color = $this->ndx_title_color; // Currently this is the same for X and Y labels
+
+ // Check to see if the text fits in the available space, if requested.
+ if (isset($min_width) || isset($min_height)) {
+ list($width, $height) = $this->SizeText($font, $angle, $formatted_text);
+ if ((isset($min_width) && ($min_width - $width) < 2)
+ || (isset($min_height) && ($min_height - $height) < 2))
+ return FALSE;
+ }
+
+ $this->DrawText($font, $angle, $this->xtr($x_world) + $x_adjustment,
+ $this->ytr($y_world) + $y_adjustment,
+ $color, $formatted_text, $halign, $valign);
+ return TRUE;
+ }
+
+ /*
+ * Draws the axis data label associated with a point in the plot.
+ * This is different from x_labels drawn by DrawXTicks() and care
+ * should be taken not to draw both, as they'd probably overlap.
+ * Calling of this function in DrawLines(), etc is decided after x_data_label_pos value.
+ * Leave the last parameter out, to avoid the drawing of vertical lines, no matter
+ * what the setting is (for plots that need it, like DrawSquared())
+ */
+ protected function DrawXDataLabel($xlab, $xpos, $row=FALSE)
+ {
+ $xlab = $this->FormatLabel('xd', $xlab);
+
+ // Labels below the plot area
+ if ($this->x_data_label_pos == 'plotdown' || $this->x_data_label_pos == 'both')
+ $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle,
+ $xpos, $this->plot_area[3] + $this->x_label_bot_offset,
+ $this->ndx_text_color, $xlab, 'center', 'top');
+
+ // Labels above the plot area
+ if ($this->x_data_label_pos == 'plotup' || $this->x_data_label_pos == 'both')
+ $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle,
+ $xpos, $this->plot_area[1] - $this->x_label_top_offset,
+ $this->ndx_text_color, $xlab, 'center', 'bottom');
+
+ // $row=0 means this is the first row. $row=FALSE means don't do any rows.
+ if ($row !== FALSE && $this->draw_x_data_label_lines)
+ $this->DrawXDataLine($xpos, $row);
+ return TRUE;
+ }
+
+ /*
+ * Draw a data label along the Y axis or side.
+ * This is used by horizontal plots.
+ */
+ protected function DrawYDataLabel($ylab, $ypos)
+ {
+ $ylab = $this->FormatLabel('yd', $ylab);
+
+ // Labels left of the plot area
+ if ($this->y_data_label_pos == 'plotleft' || $this->y_data_label_pos == 'both')
+ $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle,
+ $this->plot_area[0] - $this->y_label_left_offset, $ypos,
+ $this->ndx_text_color, $ylab, 'right', 'center');
+
+ // Labels right of the plot area
+ if ($this->y_data_label_pos == 'plotright' || $this->y_data_label_pos == 'both')
+ $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle,
+ $this->plot_area[2] + $this->y_label_right_offset, $ypos,
+ $this->ndx_text_color, $ylab, 'left', 'center');
+ return TRUE;
+ }
+
+ /*
+ * Draws Vertical lines from data points up and down.
+ * Which lines are drawn depends on the value of x_data_label_pos,
+ * and whether this is at all done or not, on draw_x_data_label_lines
+ *
+ * $xpos : position in pixels of the line.
+ * $row : index of the data row being drawn.
+ */
+ protected function DrawXDataLine($xpos, $row)
+ {
+ // Sets the line style for IMG_COLOR_STYLED lines (grid)
+ if ($this->dashed_grid) {
+ $this->SetDashedStyle($this->ndx_light_grid_color);
+ $style = IMG_COLOR_STYLED;
+ } else {
+ $style = $this->ndx_light_grid_color;
+ }
+
+ if ($this->x_data_label_pos == 'both') {
+ // Lines from the bottom up
+ ImageLine($this->img, $xpos, $this->plot_area[3], $xpos, $this->plot_area[1], $style);
+ } elseif ($this->x_data_label_pos == 'plotdown' && isset($this->data_max[$row])) {
+ // Lines from the bottom of the plot up to the max Y value at this X:
+ $ypos = $this->ytr($this->data_max[$row]);
+ ImageLine($this->img, $xpos, $ypos, $xpos, $this->plot_area[3], $style);
+ } elseif ($this->x_data_label_pos == 'plotup' && isset($this->data_min[$row])) {
+ // Lines from the top of the plot down to the min Y value at this X:
+ $ypos = $this->ytr($this->data_min[$row]);
+ ImageLine($this->img, $xpos, $this->plot_area[1], $xpos, $ypos, $style);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draws the graph legend
+ * This is called by DrawGraph only if $this->legend is not empty.
+ * Base code submitted by Marlin Viss
+ */
+ protected function DrawLegend()
+ {
+ $font = &$this->fonts['legend'];
+
+ // Find maximum legend label line width.
+ $max_width = 0;
+ foreach ($this->legend as $line) {
+ list($width, $unused) = $this->SizeText($font, 0, $line);
+ if ($width > $max_width) $max_width = $width;
+ }
+
+ // Use the font parameters to size the color boxes:
+ $char_w = $font['width'];
+ $char_h = $font['height'];
+ $line_spacing = $this->GetLineSpacing($font);
+
+ // Normalize text alignment and colorbox alignment variables:
+ $text_align = isset($this->legend_text_align) ? $this->legend_text_align : 'right';
+ $colorbox_align = isset($this->legend_colorbox_align) ? $this->legend_colorbox_align : 'right';
+
+ // Sizing parameters:
+ $v_margin = $char_h/2; // Between vertical borders and labels
+ $dot_height = $char_h + $line_spacing; // Height of the small colored boxes
+ // Color boxes are $char_w wide, but can be adjusted using legend_colorbox_width:
+ $colorbox_width = $char_w;
+ if (isset($this->legend_colorbox_width))
+ $colorbox_width *= $this->legend_colorbox_width;
+
+ // Overall legend box width e.g.: | space colorbox space text space |
+ // where each space adds $char_w, and colorbox adds $char_w * its width adjustment.
+ if (($draw_colorbox = ($colorbox_align != 'none'))) {
+ $width = $max_width + 3 * $char_w + $colorbox_width;
+ } else {
+ $width = $max_width + 2 * $char_w;
+ }
+
+ //////// Calculate box position
+ // User-defined position specified?
+ if ( !isset($this->legend_x_pos) || !isset($this->legend_y_pos)) {
+ // No, use default
+ $box_start_x = $this->plot_area[2] - $width - $this->safe_margin;
+ $box_start_y = $this->plot_area[1] + $this->safe_margin;
+ } elseif (isset($this->legend_xy_world)) {
+ // User-defined position in world-coordinates (See SetLegendWorld).
+ $box_start_x = $this->xtr($this->legend_x_pos);
+ $box_start_y = $this->ytr($this->legend_y_pos);
+ } else {
+ // User-defined position in pixel coordinates.
+ $box_start_x = $this->legend_x_pos;
+ $box_start_y = $this->legend_y_pos;
+ }
+
+ // Lower right corner
+ $box_end_y = $box_start_y + $dot_height*(count($this->legend)) + 2*$v_margin;
+ $box_end_x = $box_start_x + $width;
+
+ // Draw outer box
+ ImageFilledRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y,
+ $this->ndx_bg_color);
+ ImageRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y,
+ $this->ndx_grid_color);
+
+ $color_index = 0;
+ $max_color_index = count($this->ndx_data_colors) - 1;
+
+ // Calculate color box and text horizontal positions.
+ if (!$draw_colorbox) {
+ if ($text_align == 'left')
+ $x_pos = $box_start_x + $char_w;
+ else
+ $x_pos = $box_end_x - $char_w;
+ } elseif ($colorbox_align == 'left') {
+ $dot_left_x = $box_start_x + $char_w;
+ $dot_right_x = $dot_left_x + $colorbox_width;
+ if ($text_align == 'left')
+ $x_pos = $dot_right_x + $char_w;
+ else
+ $x_pos = $box_end_x - $char_w;
+ } else { // $colorbox_align == 'right'
+ $dot_right_x = $box_end_x - $char_w;
+ $dot_left_x = $dot_right_x - $colorbox_width;
+ if ($text_align == 'left')
+ $x_pos = $box_start_x + $char_w;
+ else
+ $x_pos = $dot_left_x - $char_w;
+ }
+
+ // Calculate starting position of first text line. The bottom of each color box
+ // lines up with the bottom (baseline) of its text line.
+ $y_pos = $box_start_y + $v_margin + $dot_height;
+
+ foreach ($this->legend as $leg) {
+ // Draw text with requested alignment:
+ $this->DrawText($font, 0, $x_pos, $y_pos, $this->ndx_text_color, $leg, $text_align, 'bottom');
+ if ($draw_colorbox) {
+ // Draw a box in the data color
+ $y1 = $y_pos - $dot_height + 1;
+ $y2 = $y_pos - 1;
+ ImageFilledRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2,
+ $this->ndx_data_colors[$color_index]);
+ // Draw a rectangle around the box
+ ImageRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2,
+ $this->ndx_text_color);
+ }
+ $y_pos += $dot_height;
+
+ $color_index++;
+ if ($color_index > $max_color_index)
+ $color_index = 0;
+ }
+ return TRUE;
+ }
+
+/////////////////////////////////////////////
+//////////////////// PLOT DRAWING HELPERS
+/////////////////////////////////////////////
+
+ /*
+ * Get data color to use for plotting.
+ * $row, $idx : Index arguments for the current data point.
+ * &$vars : Variable storage. Caller makes an empty array, and this function uses it.
+ * &$data_color : Returned result - Color index for the data point.
+ * $extra : Extra info flag passed through to data color callback.
+ */
+ protected function GetDataColor($row, $idx, &$vars, &$data_color, $extra = 0)
+ {
+ // Initialize or extract variables:
+ if (empty($vars)) {
+ $custom_color = (bool)$this->GetCallback('data_color');
+ $num_data_colors = count($this->ndx_data_colors);
+ $vars = compact('custom_color', 'num_data_colors');
+ } else {
+ extract($vars);
+ }
+
+ // Select the colors.
+ if ($custom_color) {
+ $col_i = $this->DoCallback('data_color', $row, $idx, $extra); // Custom color index
+ $data_color = $this->ndx_data_colors[$col_i % $num_data_colors];
+ } else {
+ $data_color = $this->ndx_data_colors[$idx];
+ }
+ }
+
+ /*
+ * Get data color and error bar color to use for plotting.
+ * $row, $idx : Index arguments for the current bar.
+ * &$vars : Variable storage. Caller makes an empty array, and this function uses it.
+ * &$data_color : Returned result - Color index for the data (bar fill)
+ * &$error_color : Returned result - Color index for the error bars
+ * $extra : Extra info flag passed through to data color callback.
+ */
+ protected function GetDataErrorColors($row, $idx, &$vars, &$data_color, &$error_color, $extra = 0)
+ {
+ // Initialize or extract variables:
+ if (empty($vars)) {
+ $this->NeedErrorBarColors(); // This plot needs error bar colors.
+ $custom_color = (bool)$this->GetCallback('data_color');
+ $num_data_colors = count($this->ndx_data_colors);
+ $num_error_colors = count($this->ndx_error_bar_colors);
+ $vars = compact('custom_color', 'num_data_colors', 'num_error_colors');
+ } else {
+ extract($vars);
+ }
+
+ // Select the colors.
+ if ($custom_color) {
+ $col_i = $this->DoCallback('data_color', $row, $idx, $extra); // Custom color index
+ $data_color = $this->ndx_data_colors[$col_i % $num_data_colors];
+ $error_color = $this->ndx_error_bar_colors[$col_i % $num_error_colors];
+ } else {
+ $data_color = $this->ndx_data_colors[$idx];
+ $error_color = $this->ndx_error_bar_colors[$idx];
+ }
+ }
+
+ /*
+ * Get colors to use for a bar chart. There is a data color, and either a border color
+ * or a shading color (data dark color).
+ * $row, $idx : Index arguments for the current bar.
+ * &$vars : Variable storage. Caller makes an empty array, and this function uses it.
+ * &$data_color : Returned result - Color index for the data (bar fill).
+ * &$alt_color : Returned result - Color index for the shading or outline.
+ */
+ protected function GetBarColors($row, $idx, &$vars, &$data_color, &$alt_color)
+ {
+ // Initialize or extract variables:
+ if (empty($vars)) {
+ if ($this->shading > 0) // This plot needs dark colors if shading is on.
+ $this->NeedDataDarkColors();
+ $custom_color = (bool)$this->GetCallback('data_color');
+ $num_data_colors = count($this->ndx_data_colors);
+ $num_border_colors = count($this->ndx_data_border_colors);
+ $vars = compact('custom_color', 'num_data_colors', 'num_border_colors');
+ } else {
+ extract($vars);
+ }
+
+ // Select the colors.
+ if ($custom_color) {
+ $col_i = $this->DoCallback('data_color', $row, $idx); // Custom color index
+ $i_data = $col_i % $num_data_colors; // Index for data colors and dark colors
+ $i_border = $col_i % $num_border_colors; // Index for data borders (if used)
+ } else {
+ $i_data = $i_border = $idx;
+ }
+ $data_color = $this->ndx_data_colors[$i_data];
+ if ($this->shading > 0) {
+ $alt_color = $this->ndx_data_dark_colors[$i_data];
+ } else {
+ $alt_color = $this->ndx_data_border_colors[$i_border];
+ }
+ }
+
+ /*
+ * Draws a styled dot. Uses world coordinates.
+ * The list of supported shapes can also be found in SetPointShapes().
+ * All shapes are drawn using a 3x3 grid, centered on the data point.
+ * The center is (x_mid, y_mid) and the corners are (x1, y1) and (x2, y2).
+ * $record is the 0-based index that selects the shape and size.
+ */
+ protected function DrawDot($x_world, $y_world, $record, $color)
+ {
+ $index = $record % $this->point_counts;
+ $point_size = $this->point_sizes[$index];
+
+ $half_point = (int)($point_size / 2);
+
+ $x_mid = $this->xtr($x_world);
+ $y_mid = $this->ytr($y_world);
+
+ $x1 = $x_mid - $half_point;
+ $x2 = $x_mid + $half_point;
+ $y1 = $y_mid - $half_point;
+ $y2 = $y_mid + $half_point;
+
+ switch ($this->point_shapes[$index]) {
+ case 'halfline':
+ ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color);
+ break;
+ case 'line':
+ ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
+ break;
+ case 'plus':
+ ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
+ ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color);
+ break;
+ case 'cross':
+ ImageLine($this->img, $x1, $y1, $x2, $y2, $color);
+ ImageLine($this->img, $x1, $y2, $x2, $y1, $color);
+ break;
+ case 'circle':
+ ImageArc($this->img, $x_mid, $y_mid, $point_size, $point_size, 0, 360, $color);
+ break;
+ case 'dot':
+ ImageFilledEllipse($this->img, $x_mid, $y_mid, $point_size, $point_size, $color);
+ break;
+ case 'diamond':
+ $arrpoints = array( $x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2);
+ ImageFilledPolygon($this->img, $arrpoints, 4, $color);
+ break;
+ case 'triangle':
+ $arrpoints = array( $x1, $y_mid, $x2, $y_mid, $x_mid, $y2);
+ ImageFilledPolygon($this->img, $arrpoints, 3, $color);
+ break;
+ case 'trianglemid':
+ $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y_mid);
+ ImageFilledPolygon($this->img, $arrpoints, 3, $color);
+ break;
+ case 'yield':
+ $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y2);
+ ImageFilledPolygon($this->img, $arrpoints, 3, $color);
+ break;
+ case 'delta':
+ $arrpoints = array( $x1, $y2, $x2, $y2, $x_mid, $y1);
+ ImageFilledPolygon($this->img, $arrpoints, 3, $color);
+ break;
+ case 'star':
+ ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color);
+ ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color);
+ ImageLine($this->img, $x1, $y1, $x2, $y2, $color);
+ ImageLine($this->img, $x1, $y2, $x2, $y1, $color);
+ break;
+ case 'hourglass':
+ $arrpoints = array( $x1, $y1, $x2, $y1, $x1, $y2, $x2, $y2);
+ ImageFilledPolygon($this->img, $arrpoints, 4, $color);
+ break;
+ case 'bowtie':
+ $arrpoints = array( $x1, $y1, $x1, $y2, $x2, $y1, $x2, $y2);
+ ImageFilledPolygon($this->img, $arrpoints, 4, $color);
+ break;
+ case 'target':
+ ImageFilledRectangle($this->img, $x1, $y1, $x_mid, $y_mid, $color);
+ ImageFilledRectangle($this->img, $x_mid, $y_mid, $x2, $y2, $color);
+ ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color);
+ break;
+ case 'box':
+ ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color);
+ break;
+ case 'home': /* As in: "home plate" (baseball), also looks sort of like a house. */
+ $arrpoints = array( $x1, $y2, $x2, $y2, $x2, $y_mid, $x_mid, $y1, $x1, $y_mid);
+ ImageFilledPolygon($this->img, $arrpoints, 5, $color);
+ break;
+ case 'up':
+ ImagePolygon($this->img, array($x_mid, $y1, $x2, $y2, $x1, $y2), 3, $color);
+ break;
+ case 'down':
+ ImagePolygon($this->img, array($x_mid, $y2, $x1, $y1, $x2, $y1), 3, $color);
+ break;
+ case 'none': /* Special case, no point shape here */
+ break;
+ default: /* Also 'rect' */
+ ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color);
+ break;
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw a bar (or segment of a bar), with optional shading or border.
+ * This is used by the bar and stackedbar plots, vertical and horizontal.
+ * $x1, $y1 : One corner of the bar.
+ * $x2, $y2 : Other corner of the bar.
+ * $data_color : Color index to use for the bar fill.
+ * $alt_color : Color index to use for the shading (if shading is on), else for the border.
+ * Note the same color is NOT used for shading and border - just the same argument.
+ * See GetBarColors() for where these arguments come from.
+ * $shade_top : Shade the top? (Suppressed for downward stack segments except first.)
+ * $shade_side : Shade the right side? (Suppressed for leftward stack segments except first.)
+ * Only one of $shade_top or $shade_side can be FALSE. Both default to TRUE.
+ */
+ protected function DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color,
+ $shade_top = TRUE, $shade_side = TRUE)
+ {
+ // Sort the points so x1,y1 is upper left and x2,y2 is lower right. This
+ // is needed in order to get the shading right, and imagerectangle may require it.
+ if ($x1 > $x2) {
+ $t = $x1; $x1 = $x2; $x2 = $t;
+ }
+ if ($y1 > $y2) {
+ $t = $y1; $y1 = $y2; $y2 = $t;
+ }
+
+ // Draw the bar
+ ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $data_color);
+
+ // Draw a shade, or a border.
+ if (($shade = $this->shading) > 0) {
+ if ($shade_top && $shade_side) {
+ $npts = 6;
+ $pts = array($x1, $y1, $x1 + $shade, $y1 - $shade, $x2 + $shade, $y1 - $shade,
+ $x2 + $shade, $y2 - $shade, $x2, $y2, $x2, $y1);
+ } else {
+ $npts = 4;
+ if ($shade_top) { // Suppress side shading
+ $pts = array($x1, $y1, $x1 + $shade, $y1 - $shade, $x2 + $shade, $y1 - $shade, $x2, $y1);
+ } else { // Suppress top shading
+ $pts = array($x2, $y2, $x2, $y1, $x2 + $shade, $y1 - $shade, $x2 + $shade, $y2 - $shade);
+ }
+ }
+ ImageFilledPolygon($this->img, $pts, $npts, $alt_color);
+ } else {
+ ImageRectangle($this->img, $x1, $y1, $x2,$y2, $alt_color);
+ }
+ }
+
+ /*
+ * Draw an Error Bar set. Used by DrawDotsError and DrawLinesError
+ */
+ protected function DrawYErrorBar($x_world, $y_world, $error_height, $error_bar_type, $color)
+ {
+ $x1 = $this->xtr($x_world);
+ $y1 = $this->ytr($y_world);
+ $y2 = $this->ytr($y_world+$error_height) ;
+
+ ImageSetThickness($this->img, $this->error_bar_line_width);
+ ImageLine($this->img, $x1, $y1 , $x1, $y2, $color);
+ if ($error_bar_type == 'tee') {
+ ImageLine($this->img, $x1-$this->error_bar_size, $y2, $x1+$this->error_bar_size, $y2, $color);
+ }
+ ImageSetThickness($this->img, 1);
+ return TRUE;
+ }
+
+/////////////////////////////////////////////
+//////////////////// PLOT DRAWING
+/////////////////////////////////////////////
+
+ /*
+ * Draws a pie chart. Data is 'text-data', 'data-data', or 'text-data-single'.
+ *
+ * For text-data-single, the data array contains records with an ignored label,
+ * and one Y value. Each record defines a sector of the pie, as a portion of
+ * the sum of all Y values.
+ *
+ * For text-data and data-data, the data array contains records with an ignored label,
+ * an ignored X value (for data-data only), and N (N>=1) Y values per record.
+ * The pie chart will be produced with N segments. The relative size of the first
+ * sector of the pie is the sum of the first Y data value in each record, etc.
+ *
+ * Note: With text-data-single, the data labels could be used, but are not currently.
+ *
+ * If there are no valid data points > 0 at all, just draw nothing. It may seem more correct to
+ * raise an error, but all of the other plot types handle it this way implicitly. DrawGraph
+ * checks for an empty data array, but this is different: a non-empty data array with no Y values,
+ * or all Y=0.
+ */
+ protected function DrawPieChart()
+ {
+ if (!$this->CheckDataType('text-data, text-data-single, data-data'))
+ return FALSE;
+
+ // Allocate dark colors only if they will be used for shading.
+ if ($this->shading > 0)
+ $this->NeedDataDarkColors();
+
+ $xpos = $this->plot_area[0] + $this->plot_area_width/2;
+ $ypos = $this->plot_area[1] + $this->plot_area_height/2;
+ $diameter = min($this->plot_area_width, $this->plot_area_height);
+ $radius = $diameter/2;
+
+ $num_slices = $this->data_columns; // See CheckDataArray which calculates this for us.
+ if ($num_slices < 1) return TRUE; // Give up early if there is no data at all.
+ $sumarr = array_fill(0, $num_slices, 0);
+
+ if ($this->datatype_pie_single) {
+ // text-data-single: One data column per row, one pie slice per row.
+ for ($i = 0; $i < $num_slices; $i++) {
+ // $legend[$i] = $this->data[$i][0]; // Note: Labels are not used yet
+ if (is_numeric($this->data[$i][1]))
+ $sumarr[$i] = abs($this->data[$i][1]);
+ }
+ } else {
+ // text-data: Sum each column (skipping label), one pie slice per column.
+ // data-data: Sum each column (skipping X value and label), one pie slice per column.
+ $skip = ($this->datatype_implied) ? 1 : 2; // Leading values to skip in each row.
+ for ($i = 0; $i < $this->num_data_rows; $i++) {
+ for ($j = $skip; $j < $this->num_recs[$i]; $j++) {
+ if (is_numeric($this->data[$i][$j]))
+ $sumarr[$j-$skip] += abs($this->data[$i][$j]);
+ }
+ }
+ }
+
+ $total = array_sum($sumarr);
+
+ if ($total == 0) {
+ // There are either no valid data points, or all are 0.
+ // See top comment about why not to make this an error.
+ return TRUE;
+ }
+
+ if ($this->shading) {
+ $diam2 = $diameter / 2;
+ } else {
+ $diam2 = $diameter;
+ }
+ $max_data_colors = count($this->ndx_data_colors);
+
+ // Use the Y label format precision, with default value:
+ if (isset($this->label_format['y']['precision']))
+ $precision = $this->label_format['y']['precision'];
+ else
+ $precision = 1;
+
+ for ($h = $this->shading; $h >= 0; $h--) {
+ $color_index = 0;
+ $start_angle = 0;
+ $end_angle = 0;
+ for ($j = 0; $j < $num_slices; $j++) {
+ $val = $sumarr[$j];
+
+ // For shaded pies: the last one (at the top of the "stack") has a brighter color:
+ if ($h == 0)
+ $slicecol = $this->ndx_data_colors[$color_index];
+ else
+ $slicecol = $this->ndx_data_dark_colors[$color_index];
+
+ $label_txt = $this->number_format(($val / $total * 100), $precision) . '%';
+ $val = 360 * ($val / $total);
+
+ // NOTE that imagefilledarc measures angles CLOCKWISE (go figure why),
+ // so the pie chart would start clockwise from 3 o'clock, would it not be
+ // for the reversal of start and end angles in imagefilledarc()
+ // Also note ImageFilledArc only takes angles in integer degrees, and if the
+ // the start and end angles match then you get a full circle not a zero-width
+ // pie. This is bad. So skip any zero-size wedge. On the other hand, we cannot
+ // let cumulative error from rounding to integer result in missing wedges. So
+ // keep the running total as a float, and round the angles. It should not
+ // be necessary to check that the last wedge ends at 360 degrees.
+ $start_angle = $end_angle;
+ $end_angle += $val;
+ // This method of conversion to integer - truncate after reversing it - was
+ // chosen to match the implicit method of PHPlot<=5.0.4 to get the same slices.
+ $arc_start_angle = (int)(360 - $start_angle);
+ $arc_end_angle = (int)(360 - $end_angle);
+
+ if ($arc_start_angle > $arc_end_angle) {
+ $mid_angle = deg2rad($end_angle - ($val / 2));
+
+ // Draw the slice
+ ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
+ $arc_end_angle, $arc_start_angle,
+ $slicecol, IMG_ARC_PIE);
+
+ // Draw the labels only once
+ if ($h == 0) {
+ // Draw the outline
+ if (! $this->shading)
+ ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2,
+ $arc_end_angle, $arc_start_angle, $this->ndx_grid_color,
+ IMG_ARC_PIE | IMG_ARC_EDGED |IMG_ARC_NOFILL);
+
+ // The '* 1.2' trick is to get labels out of the pie chart so there are more
+ // chances they can be seen in small sectors.
+ $label_x = $xpos + ($diameter * 1.2 * cos($mid_angle)) * $this->label_scale_position;
+ $label_y = $ypos+$h - ($diam2 * 1.2 * sin($mid_angle)) * $this->label_scale_position;
+
+ $this->DrawText($this->fonts['generic'], 0, $label_x, $label_y, $this->ndx_grid_color,
+ $label_txt, 'center', 'center');
+ }
+ }
+ if (++$color_index >= $max_data_colors)
+ $color_index = 0;
+ } // end for
+ } // end for
+ return TRUE;
+ }
+
+ /*
+ * Draw the points and errors bars for an error plot of types points and linepoints
+ * Supports only data-data-error format, with each row of the form
+ * array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...)
+ * This is called from DrawDots, with data type already checked.
+ * $paired is true for linepoints error plots, to make sure elements are
+ * only drawn once. If true, data labels are drawn by DrawLinesError, and error
+ * bars are drawn by DrawDotsError. (This choice is for backwards compatibility.)
+ */
+ protected function DrawDotsError($paired = FALSE)
+ {
+ // Adjust the point shapes and point sizes arrays:
+ $this->CheckPointParams();
+
+ $gcvars = array(); // For GetDataErrorColors, which initializes and uses this.
+ // Special flag for data color callback to indicate the 'points' part of 'linepoints':
+ $alt_flag = $paired ? 1 : 0;
+
+ for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (title)
+
+ $x_now = $this->data[$row][$record++]; // Read it, advance record index
+
+ $x_now_pixels = $this->xtr($x_now); // Absolute coordinates.
+
+ // Draw X Data labels?
+ if ($this->x_data_label_pos != 'none' && !$paired)
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+ // Now go for Y, E+, E-
+ for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
+ if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
+
+ // Select the colors:
+ $this->GetDataErrorColors($row, $idx, $gcvars, $data_color, $error_color, $alt_flag);
+
+ // Y:
+ $y_now = $this->data[$row][$record++];
+ $this->DrawDot($x_now, $y_now, $idx, $data_color);
+
+ // Error +
+ $val = $this->data[$row][$record++];
+ $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape, $error_color);
+ // Error -
+ $val = $this->data[$row][$record++];
+ $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape, $error_color);
+ } else {
+ $record += 3; // Skip over missing Y and its error values
+ }
+ }
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw a points plot, or the points for a linepoints plot
+ * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
+ * Points plot with error bars (data-data-error format) is redirected to DrawDotsError.
+ * $paired is true for linepoints plots, to make sure elements are only drawn once.
+ */
+ protected function DrawDots($paired = FALSE)
+ {
+ if (!$this->CheckDataType('text-data, data-data, data-data-error'))
+ return FALSE;
+ if ($this->datatype_error_bars)
+ return $this->DrawDotsError($paired); // Redirect for points+errorbars plot
+
+ // Adjust the point shapes and point sizes arrays:
+ $this->CheckPointParams();
+
+ $gcvars = array(); // For GetDataColor, which initializes and uses this.
+ // Special flag for data color callback to indicate the 'points' part of 'linepoints':
+ $alt_flag = $paired ? 1 : 0;
+
+ // Data Value Labels? (Skip if doing the points from a linepoints plot)
+ $do_dvls = !$paired && $this->CheckDataValueLabels($this->y_data_label_pos,
+ $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align);
+
+ for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+ $rec = 1; // Skip record #0 (data label)
+
+ if ($this->datatype_implied) // Implied X values?
+ $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
+ else
+ $x_now = $this->data[$row][$rec++]; // Read it, advance record index
+
+ $x_now_pixels = $this->xtr($x_now);
+
+ // Draw X Data labels?
+ if (!$paired && $this->x_data_label_pos != 'none')
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+ // Proceed with Y values
+ for ($idx = 0;$rec < $this->num_recs[$row]; $rec++, $idx++) {
+ if (is_numeric($this->data[$row][$rec])) { // Allow for missing Y data
+ $y_now = (double)$this->data[$row][$rec];
+
+ // Select the color:
+ $this->GetDataColor($row, $idx, $gcvars, $data_color, $alt_flag);
+ // Draw the marker:
+ $this->DrawDot($x_now, $y_now, $idx, $data_color);
+
+ // Draw data value labels?
+ if ($do_dvls) {
+ $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align,
+ $dvl_x_off, $dvl_y_off);
+ }
+ }
+ }
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw a Thin Bar Line plot, also known as an Impulse plot.
+ * A clean, fast routine for when you just want charts like stock volume charts.
+ * Supports data-data and text-data formats for vertical plots,
+ * and data-data-yx and text-data-yx for horizontal plots.
+ * Note that although this plot type supports multiple data sets, it rarely makes
+ * sense to have more than 1, because the lines will overlay.
+ * This one function does both vertical and horizontal plots. "iv" is used for the
+ * independent variable (X for vertical plots, Y for horizontal) and "dv" is used
+ * for the dependent variable (Y for vertical plots, X for horizontal).
+ */
+ protected function DrawThinBarLines()
+ {
+ if (!$this->CheckDataType('text-data, data-data, text-data-yx, data-data-yx'))
+ return FALSE;
+
+ $gcvars = array(); // For GetDataColor, which initializes and uses this.
+
+ for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+ $rec = 1; // Skip record #0 (data label)
+
+ if ($this->datatype_implied) // Implied independent variable values?
+ $iv_now = 0.5 + $cnt++; // Place text-data at 0.5, 1.5, 2.5, etc...
+ else
+ $iv_now = $this->data[$row][$rec++]; // Read it, advance record index
+
+ if ($this->datatype_swapped_xy) {
+ $y_now_pixels = $this->ytr($iv_now);
+ // Draw Y Data labels?
+ if ($this->y_data_label_pos != 'none')
+ $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels);
+ } else {
+ $x_now_pixels = $this->xtr($iv_now);
+ // Draw X Data labels?
+ if ($this->x_data_label_pos != 'none')
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+ }
+
+ // Proceed with dependent values
+ for ($idx = 0; $rec < $this->num_recs[$row]; $rec++, $idx++) {
+ if (is_numeric($this->data[$row][$rec])) { // Allow for missing data
+ $dv = $this->data[$row][$rec];
+ ImageSetThickness($this->img, $this->line_widths[$idx]);
+
+ // Select the color:
+ $this->GetDataColor($row, $idx, $gcvars, $data_color);
+
+ if ($this->datatype_swapped_xy) {
+ // Draw a line from user defined y axis position right (or left) to xtr($dv)
+ ImageLine($this->img, $this->y_axis_x_pixels, $y_now_pixels,
+ $this->xtr($dv), $y_now_pixels, $data_color);
+ } else {
+ // Draw a line from user defined x axis position up (or down) to ytr($dv)
+ ImageLine($this->img, $x_now_pixels, $this->x_axis_y_pixels,
+ $x_now_pixels, $this->ytr($dv), $data_color);
+ }
+ }
+ }
+ }
+
+ ImageSetThickness($this->img, 1);
+ return TRUE;
+ }
+
+ /*
+ * Draw an 'area' or 'stacked area' plot.
+ * Both of these fill the area between lines, but in the stacked area graph the Y values
+ * are accumulated for each X, same as stacked bars. In the regular area graph, the areas
+ * are filled in order from the X axis up to each Y (so the Y values for each X need to be
+ * in decreasing order in this case).
+ * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
+ * Notes:
+ * All Y values must be >= 0. (If any Y<0 the absolute value is used.)
+ * Missing data points are NOT handled. (They are counted as 0.)
+ * All rows must have the same number of Y points, or an error image will be produced.
+ */
+ protected function DrawArea($do_stacked = FALSE)
+ {
+ if (!$this->CheckDataType('text-data, data-data'))
+ return FALSE;
+
+ $n = $this->num_data_rows; // Number of X values
+
+ // These arrays store the device X and Y coordinates for all lines:
+ $xd = array();
+ $yd = array();
+
+ // Make sure each row has the same number of values. Note records_per_group is max(num_recs).
+ if ($this->records_per_group != min($this->num_recs)) {
+ return $this->PrintError("DrawArea(): Data array must contain the same number"
+ . " of Y values for each X");
+ }
+
+ // Calculate the Y value for each X, and store the device
+ // coordinates into the xd and yd arrays.
+ // For stacked area plots, the Y values accumulate.
+ for ($row = 0; $row < $n; $row++) {
+ $rec = 1; // Skip record #0 (data label)
+
+ if ($this->datatype_implied) // Implied X values?
+ $x_now = 0.5 + $row; // Place text-data at X = 0.5, 1.5, 2.5, etc...
+ else
+ $x_now = $this->data[$row][$rec++]; // Read it, advance record index
+
+ $x_now_pixels = $this->xtr($x_now);
+
+ if ($this->x_data_label_pos != 'none') // Draw X Data labels?
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+
+ // Store the X value.
+ // There is an artificial Y value at the axis. For 'area' it goes
+ // at the end; for stackedarea it goes before the start.
+ $xd[$row] = $x_now_pixels;
+ $yd[$row] = array();
+ if ($do_stacked)
+ $yd[$row][] = $this->x_axis_y_pixels;
+
+ // Store the Y values for this X.
+ // All Y values are clipped to the x axis which should be zero but can be moved.
+ $y = 0;
+ while ($rec < $this->records_per_group) {
+ if (is_numeric($this->data[$row][$rec])) { // Treat missing values as 0.
+ $y += abs($this->data[$row][$rec]);
+ }
+ $yd[$row][] = $this->ytr(max($this->x_axis_position, $y));
+ if (!$do_stacked) $y = 0;
+ $rec++;
+ }
+
+ if (!$do_stacked)
+ $yd[$row][] = $this->x_axis_y_pixels;
+ }
+
+ // Now draw the filled polygons.
+ // Note data_columns is the number of Y points (columns excluding label and X), and the
+ // number of entries in the yd[] arrays is data_columns+1.
+ $prev_row = 0;
+ for ($row = 1; $row <= $this->data_columns; $row++) { // 1 extra for X axis artificial row
+ $pts = array();
+ // Previous data set forms top (for area) or bottom (for stackedarea):
+ for ($j = 0; $j < $n; $j++) {
+ $pts[] = $xd[$j];
+ $pts[] = $yd[$j][$prev_row];
+ }
+ // Current data set forms bottom (for area) or top (for stackedarea):
+ for ($j = $n- 1; $j >= 0; $j--) {
+ $pts[] = $xd[$j];
+ $pts[] = $yd[$j][$row];
+ }
+ // Draw it:
+ ImageFilledPolygon($this->img, $pts, $n * 2, $this->ndx_data_colors[$prev_row]);
+
+ $prev_row = $row;
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw a line plot, or the lines part of a linepoints plot
+ * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
+ * Line plot with error bars (data-data-error format) is redirected to DrawLinesError.
+ * $paired is true for linepoints plots, to make sure elements are only drawn once.
+ */
+ protected function DrawLines($paired = FALSE)
+ {
+ if (!$this->CheckDataType('text-data, data-data, data-data-error'))
+ return FALSE;
+ if ($this->datatype_error_bars)
+ return $this->DrawLinesError($paired); // Redirect for lines+errorbar plot
+
+ // Flag array telling if the current point is valid, one element per plot line.
+ // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point.
+ $start_lines = array_fill(0, $this->data_columns, FALSE);
+
+ $gcvars = array(); // For GetDataColor, which initializes and uses this.
+
+ // Data Value Labels?
+ $do_dvls = $this->CheckDataValueLabels($this->y_data_label_pos,
+ $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align);
+
+ for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ if ($this->datatype_implied) // Implied X values?
+ $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
+ else
+ $x_now = $this->data[$row][$record++]; // Read it, advance record index
+
+ $x_now_pixels = $this->xtr($x_now); // Absolute coordinates
+
+ if ($this->x_data_label_pos != 'none') // Draw X Data labels?
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+ for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+ if (($line_style = $this->line_styles[$idx]) == 'none')
+ continue; //Allow suppressing entire line, useful with linepoints
+ if (is_numeric($this->data[$row][$record])) { //Allow for missing Y data
+ $y_now = (double)$this->data[$row][$record];
+ $y_now_pixels = $this->ytr($y_now);
+
+ if ($start_lines[$idx]) {
+ // Set line width, revert it to normal at the end
+ ImageSetThickness($this->img, $this->line_widths[$idx]);
+
+ // Select the color:
+ $this->GetDataColor($row, $idx, $gcvars, $data_color);
+
+ if ($line_style == 'dashed') {
+ $this->SetDashedStyle($data_color);
+ $data_color = IMG_COLOR_STYLED;
+ }
+ ImageLine($this->img, $x_now_pixels, $y_now_pixels,
+ $lastx[$idx], $lasty[$idx], $data_color);
+ }
+
+ // Draw data value labels?
+ if ($do_dvls) {
+ $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align,
+ $dvl_x_off, $dvl_y_off);
+ }
+
+ $lasty[$idx] = $y_now_pixels;
+ $lastx[$idx] = $x_now_pixels;
+ $start_lines[$idx] = TRUE;
+ } elseif ($this->draw_broken_lines) { // Y data missing, leave a gap.
+ $start_lines[$idx] = FALSE;
+ }
+ } // end for
+ } // end for
+
+ ImageSetThickness($this->img, 1); // Revert to original state for lines to be drawn later.
+ return TRUE;
+ }
+
+ /*
+ * Draw lines with error bars for an error plot of types lines and linepoints
+ * Supports only data-data-error format, with each row of the form
+ * array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...)
+ * This is called from DrawLines, with data type already checked.
+ * $paired is true for linepoints error plots, to make sure elements are
+ * only drawn once. If true, data labels are drawn by DrawLinesError, and error
+ * bars are drawn by DrawDotsError. (This choice is for backwards compatibility.)
+ */
+ protected function DrawLinesError($paired = FALSE)
+ {
+ $start_lines = array_fill(0, $this->data_columns, FALSE);
+
+ $gcvars = array(); // For GetDataErrorColors, which initializes and uses this.
+
+ for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ $x_now = $this->data[$row][$record++]; // Read X value, advance record index
+
+ $x_now_pixels = $this->xtr($x_now); // Absolute coordinates.
+
+ if ($this->x_data_label_pos != 'none') // Draw X Data labels?
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+ // Now go for Y, E+, E-
+ for ($idx = 0; $record < $this->num_recs[$row]; $idx++) {
+ if (($line_style = $this->line_styles[$idx]) == 'none')
+ continue; //Allow suppressing entire line, useful with linepoints
+ if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
+
+ // Select the colors:
+ $this->GetDataErrorColors($row, $idx, $gcvars, $data_color, $error_color);
+
+ // Y
+ $y_now = $this->data[$row][$record++];
+ $y_now_pixels = $this->ytr($y_now);
+
+ if ($start_lines[$idx]) {
+ ImageSetThickness($this->img, $this->line_widths[$idx]);
+
+ if ($line_style == 'dashed') {
+ $this->SetDashedStyle($data_color);
+ $data_color = IMG_COLOR_STYLED;
+ }
+ ImageLine($this->img, $x_now_pixels, $y_now_pixels,
+ $lastx[$idx], $lasty[$idx], $data_color);
+ }
+
+ if ($paired) {
+ $record += 2; // Skip error bars - done in the 'points' part of 'linepoints'.
+ } else {
+ // Error+
+ $val = $this->data[$row][$record++];
+ $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape, $error_color);
+
+ // Error-
+ $val = $this->data[$row][$record++];
+ $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape, $error_color);
+ }
+
+ // Update indexes:
+ $start_lines[$idx] = TRUE; // Tells us if we already drew the first column of points,
+ // thus having $lastx and $lasty ready for the next column.
+ $lastx[$idx] = $x_now_pixels;
+ $lasty[$idx] = $y_now_pixels;
+
+ } else {
+ $record += 3; // Skip over missing Y and its error values
+ if ($this->draw_broken_lines) {
+ $start_lines[$idx] = FALSE;
+ }
+ }
+ } // end for
+ } // end for
+
+ ImageSetThickness($this->img, 1); // Revert to original state for lines to be drawn later.
+ return TRUE;
+ }
+
+ /*
+ * Draw a Lines+Points plot (linepoints).
+ * This just uses DrawLines and DrawDots. They handle the error-bar case themselves.
+ */
+ protected function DrawLinePoints()
+ {
+ // This check is redundant, as DrawLines and DrawDots do it, but left here as insurance.
+ if (!$this->CheckDataType('text-data, data-data, data-data-error'))
+ return FALSE;
+ $this->DrawLines(TRUE);
+ $this->DrawDots(TRUE);
+ return TRUE;
+ }
+
+ /*
+ * Draw a Squared Line plot.
+ * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...)
+ * This is based on DrawLines(), with one more line drawn for each point.
+ */
+ protected function DrawSquared()
+ {
+ if (!$this->CheckDataType('text-data, data-data'))
+ return FALSE;
+
+ // Flag array telling if the current point is valid, one element per plot line.
+ // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point.
+ $start_lines = array_fill(0, $this->data_columns, FALSE);
+
+ $gcvars = array(); // For GetDataColor, which initializes and uses this.
+
+ // Data Value Labels?
+ $do_dvls = $this->CheckDataValueLabels($this->y_data_label_pos,
+ $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align);
+
+ for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ if ($this->datatype_implied) // Implied X values?
+ $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
+ else
+ $x_now = $this->data[$row][$record++]; // Read it, advance record index
+
+ $x_now_pixels = $this->xtr($x_now); // Absolute coordinates
+
+ if ($this->x_data_label_pos != 'none') // Draw X Data labels?
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); // notice there is no last param.
+
+ // Draw Lines
+ for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+ if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
+ $y_now = (double)$this->data[$row][$record];
+ $y_now_pixels = $this->ytr($y_now);
+
+ if ($start_lines[$idx]) {
+ // Set line width, revert it to normal at the end
+ ImageSetThickness($this->img, $this->line_widths[$idx]);
+
+ // Select the color:
+ $this->GetDataColor($row, $idx, $gcvars, $data_color);
+
+ if ($this->line_styles[$idx] == 'dashed') {
+ $this->SetDashedStyle($data_color);
+ $data_color = IMG_COLOR_STYLED;
+ }
+ ImageLine($this->img, $lastx[$idx], $lasty[$idx],
+ $x_now_pixels, $lasty[$idx], $data_color);
+ ImageLine($this->img, $x_now_pixels, $lasty[$idx],
+ $x_now_pixels, $y_now_pixels, $data_color);
+ }
+
+ // Draw data value labels?
+ if ($do_dvls) {
+ $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align,
+ $dvl_x_off, $dvl_y_off);
+ }
+
+ $lastx[$idx] = $x_now_pixels;
+ $lasty[$idx] = $y_now_pixels;
+ $start_lines[$idx] = TRUE;
+ } elseif ($this->draw_broken_lines) { // Y data missing, leave a gap.
+ $start_lines[$idx] = FALSE;
+ }
+ }
+ } // end while
+
+ ImageSetThickness($this->img, 1);
+ return TRUE;
+ }
+
+ /*
+ * Draw a Bar chart
+ * Supports text-data format, with each row in the form array(label, y1, y2, y3, ...)
+ * Horizontal bars (text-data-yx format) are sent to DrawHorizBars() instead.
+ */
+ protected function DrawBars()
+ {
+ if (!$this->CheckDataType('text-data, text-data-yx'))
+ return FALSE;
+ if ($this->datatype_swapped_xy)
+ return $this->DrawHorizBars();
+ $this->CalcBarWidths(FALSE, TRUE); // Calculate bar widths for unstacked, vertical
+
+ // This is the X offset from the bar group's label center point to the left side of the first bar
+ // in the group. See also CalcBarWidths above.
+ $x_first_bar = ($this->data_columns * $this->record_bar_width) / 2 - $this->bar_adjust_gap;
+
+ $gcvars = array(); // For GetBarColors, which initializes and uses this.
+
+ for ($row = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ $x_now_pixels = $this->xtr(0.5 + $row); // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+ if ($this->x_data_label_pos != 'none') // Draw X Data labels?
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+
+ // Lower left X of first bar in the group:
+ $x1 = $x_now_pixels - $x_first_bar;
+
+ // Draw the bars in the group:
+ for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+ if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data
+ $y = $this->data[$row][$record];
+ $x2 = $x1 + $this->actual_bar_width;
+
+ if (($upgoing_bar = $y >= $this->x_axis_position)) {
+ $y1 = $this->ytr($y);
+ $y2 = $this->x_axis_y_pixels;
+ } else {
+ $y1 = $this->x_axis_y_pixels;
+ $y2 = $this->ytr($y);
+ }
+
+ // Select the colors:
+ $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
+
+ // Draw the bar, and the shade or border:
+ $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color);
+
+ // Draw optional data labels above the bars (or below, for negative values).
+ if ( $this->y_data_label_pos == 'plotin') {
+ if ($upgoing_bar) {
+ $v_align = 'bottom';
+ $y_offset = -5 - $this->shading;
+ } else {
+ $v_align = 'top';
+ $y_offset = 2;
+ }
+ $this->DrawDataValueLabel('y', $row+0.5, $y, $y, 'center', $v_align,
+ ($idx + 0.5) * $this->record_bar_width - $x_first_bar, $y_offset);
+ }
+ }
+ // Step to next bar in group:
+ $x1 += $this->record_bar_width;
+ } // end for
+ } // end for
+ return TRUE;
+ }
+
+ /*
+ * Draw a Horizontal Bar chart
+ * Supports only text-data-yx format, with each row in the form array(label, x1, x2, x3, ...)
+ * Note that the data values are X not Y, and the bars are drawn horizontally.
+ * This is called from DrawBars, which has already checked the data type.
+ */
+ protected function DrawHorizBars()
+ {
+ $this->CalcBarWidths(FALSE, FALSE); // Calculate bar widths for unstacked, vertical
+
+ // This is the Y offset from the bar group's label center point to the bottom of the first bar
+ // in the group. See also CalcBarWidths above.
+ $y_first_bar = ($this->data_columns * $this->record_bar_width) / 2 - $this->bar_adjust_gap;
+
+ $gcvars = array(); // For GetBarColors, which initializes and uses this.
+
+ for ($row = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ $y_now_pixels = $this->ytr(0.5 + $row); // Place bars at Y=0.5, 1.5, 2.5, etc...
+
+ if ($this->y_data_label_pos != 'none') // Draw Y Data Labels?
+ $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels);
+
+ // Lower left Y of first bar in the group:
+ $y1 = $y_now_pixels + $y_first_bar;
+
+ // Draw the bars in the group:
+ for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+ if (is_numeric($this->data[$row][$record])) { // Allow for missing X data
+ $x = $this->data[$row][$record];
+ $y2 = $y1 - $this->actual_bar_width;
+
+ if (($rightwards_bar = $x >= $this->y_axis_position)) {
+ $x1 = $this->xtr($x);
+ $x2 = $this->y_axis_x_pixels;
+ } else {
+ $x1 = $this->y_axis_x_pixels;
+ $x2 = $this->xtr($x);
+ }
+
+ // Select the colors:
+ $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
+
+ // Draw the bar, and the shade or border:
+ $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color);
+
+ // Draw optional data labels to the right of the bars (or left, if the bar
+ // goes left of the Y axis line).
+ if ($this->x_data_label_pos == 'plotin') {
+ if ($rightwards_bar) {
+ $h_align = 'left';
+ $x_offset = 5 + $this->shading;
+ } else {
+ $h_align = 'right';
+ $x_offset = -2;
+ }
+ $this->DrawDataValueLabel('x', $x, $row+0.5, $x, $h_align, 'center',
+ $x_offset, $y_first_bar - ($idx + 0.5) * $this->record_bar_width);
+ }
+
+ }
+ // Step to next bar in group:
+ $y1 -= $this->record_bar_width;
+ } // end for
+ } // end for
+
+ return TRUE;
+ }
+
+ /*
+ * Draw a Stacked Bar chart
+ * Supports text-data format, with each row in the form array(label, y1, y2, y3, ...)
+ * Horizontal stacked bars (text-data-yx format) are sent to DrawHorizStackedBars() instead.
+ * Original stacked bars idea by Laurent Kruk < lolok at users.sourceforge.net >
+ */
+ protected function DrawStackedBars()
+ {
+ if (!$this->CheckDataType('text-data, text-data-yx'))
+ return FALSE;
+ if ($this->datatype_swapped_xy)
+ return $this->DrawHorizStackedBars();
+ $this->CalcBarWidths(TRUE, TRUE); // Calculate bar widths for stacked, vertical
+
+ // This is the X offset from the bar's label center point to the left side of the bar.
+ $x_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap;
+
+ $gcvars = array(); // For GetBarColors, which initializes and uses this.
+
+ // Determine if any data labels are on:
+ $data_labels_within = ($this->y_data_label_pos == 'plotstack');
+ $data_labels_end = $data_labels_within || ($this->y_data_label_pos == 'plotin');
+ $data_label_y_offset = -5 - $this->shading; // For upward labels only.
+
+ for ($row = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ $x_now_pixels = $this->xtr(0.5 + $row); // Place text-data at X = 0.5, 1.5, 2.5, etc...
+
+ if ($this->x_data_label_pos != 'none') // Draw X Data labels?
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels);
+
+ // Lower left and lower right X of the bars in this stack:
+ $x1 = $x_now_pixels - $x_first_bar;
+ $x2 = $x1 + $this->actual_bar_width;
+
+ // Draw the bar segments in this stack.
+ $wy1 = 0; // World coordinates Y1, current sum of values
+ $wy2 = $this->x_axis_position; // World coordinates Y2, last drawn value
+ $first = TRUE;
+
+ for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+
+ // Skip missing Y values, and ignore Y=0 values.
+ if (is_numeric($this->data[$row][$record])
+ && ($this_y = $this->data[$row][$record]) != 0) {
+
+ // First non-zero value sets the direction, $upward. Note this compares to 0,
+ // not the axis position. Segments are based at 0 but clip to the axis.
+ if ($first)
+ $upward = ($this_y > 0);
+
+ $wy1 += $this_y; // Keep the running total for this bar stack
+
+ // Draw nothing if this segment would not increase the bar height.
+ // Upward bars: draw if wy1>wy2. Downward bars: Draw if wy1<wy2.
+ if (($wy1 < $wy2) XOR $upward) {
+
+ $y1 = $this->ytr($wy1); // Convert to device coordinates. $y1 is outermost value.
+ $y2 = $this->ytr($wy2); // $y2 is innermost (closest to axis).
+
+ // Select the colors:
+ $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
+
+ // Draw the bar, and the shade or border:
+ $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color,
+ // Only shade the top for upward bars, or the first segment of downward bars:
+ $upward || $first, TRUE);
+
+ // Draw optional data label for this bar segment just inside the end.
+ // Text value is the current Y, but position is the cumulative Y.
+ // The label is only drawn if it fits in the segment height |y2-y1|.
+ if ($data_labels_within) {
+ $this->DrawDataValueLabel('y', $row+0.5, $wy1, $this_y,
+ 'center', $upward ? 'top' : 'bottom',
+ 0, $upward ? 3 : -3, NULL, abs($y1 - $y2));
+ }
+ // Mark the new end of the bar, conditional on segment height > 0.
+ $wy2 = $wy1;
+ }
+ $first = FALSE;
+ }
+ } // end for
+
+ // Draw optional data label above the bar with the total value.
+ // Value is wy1 (total value), but position is wy2 (end of the bar stack).
+ // These differ only with wrong-direction segments, or a stack completely clipped by the axis.
+ if ($data_labels_end) {
+ $this->DrawDataValueLabel('y', $row+0.5, $wy2, $wy1, 'center', $upward ? 'bottom' : 'top',
+ 0, $upward ? $data_label_y_offset : 5);
+ }
+ } // end for
+ return TRUE;
+ }
+
+ /*
+ * Draw a Horizontal Stacked Bar chart
+ * Supports only text-data-yx format, with each row in the form array(label, x1, x2, x3, ...)
+ * Note that the data values are X not Y, and the bars are drawn horizontally.
+ * This is called from DrawStackedBars, which has already checked the data type.
+ */
+ protected function DrawHorizStackedBars()
+ {
+ $this->CalcBarWidths(TRUE, FALSE); // Calculate bar widths for stacked, horizontal
+
+ // This is the Y offset from the bar's label center point to the bottom of the bar
+ $y_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap;
+
+ $gcvars = array(); // For GetBarColors, which initializes and uses this.
+
+ // Determine if any data labels are on:
+ $data_labels_within = ($this->x_data_label_pos == 'plotstack');
+ $data_labels_end = $data_labels_within || ($this->x_data_label_pos == 'plotin');
+ $data_label_x_offset = 5 + $this->shading; // For rightward labels only
+
+ for ($row = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ $y_now_pixels = $this->ytr(0.5 + $row); // Place bars at Y=0.5, 1.5, 2.5, etc...
+
+ if ($this->y_data_label_pos != 'none') // Draw Y Data labels?
+ $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels);
+
+ // Lower left and upper left Y of the bars in this stack:
+ $y1 = $y_now_pixels + $y_first_bar;
+ $y2 = $y1 - $this->actual_bar_width;
+
+ // Draw the bar segments in this stack:
+ $wx1 = 0; // World coordinates X1, current sum of values
+ $wx2 = $this->y_axis_position; // World coordinates X2, last drawn value
+ $first = TRUE;
+
+ for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) {
+
+ // Skip missing X values, and ignore X<0 values.
+ if (is_numeric($this->data[$row][$record])
+ && ($this_x = $this->data[$row][$record]) != 0) {
+
+ // First non-zero value sets the direction, $rightward. Note this compares to 0,
+ // not the axis position. Segments are based at 0 but clip to the axis.
+ if ($first)
+ $rightward = ($this_x > 0);
+
+ $wx1 += $this_x; // Keep the running total for this bar stack
+
+ // Draw nothing if this segment would not increase the bar length.
+ // Rightward bars: draw if wx1>wx2. Leftward bars: Draw if wx1<wx2.
+ if (($wx1 < $wx2) XOR $rightward) {
+
+ $x1 = $this->xtr($wx1); // Convert to device coordinates. $x1 is outermost value.
+ $x2 = $this->xtr($wx2); // $x2 is innermost (closest to axis).
+
+ // Select the colors:
+ $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color);
+
+ // Draw the bar, and the shade or border:
+ $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color,
+ // Only shade the side for rightward bars, or the first segment of leftward bars:
+ TRUE, $rightward || $first);
+ // Draw optional data label for this bar segment just inside the end.
+ // Text value is the current X, but position is the cumulative X.
+ // The label is only drawn if it fits in the segment width |x2-x1|.
+ if ($data_labels_within) {
+ $this->DrawDataValueLabel('x', $wx1, $row+0.5, $this_x,
+ $rightward ? 'right' : 'left', 'center',
+ $rightward ? -3 : 3, 0, abs($x1 - $x2), NULL);
+ }
+ // Mark the new end of the bar, conditional on segment width > 0.
+ $wx2 = $wx1;
+ }
+ $first = FALSE;
+ }
+ } // end for
+
+ // Draw optional data label right of the bar with the total value.
+ // Value is wx1 (total value), but position is wx2 (end of the bar stack).
+ // These differ only with wrong-direction segments, or a stack completely clipped by the axis.
+ if ($data_labels_end) {
+ $this->DrawDataValueLabel('x', $wx2, $row+0.5, $wx1, $rightward ? 'left' : 'right', 'center',
+ $rightward ? $data_label_x_offset : -5, 0);
+ }
+ } // end for
+ return TRUE;
+ }
+
+ /*
+ * Draw a financial "Open/High/Low/Close" (OHLC) plot, including candlestick plots.
+ * Data format can be text-data (label, Yo, Yh, Yl, Yc) or data-data (label, X, Yo, Yh, Yl, Yc).
+ * Yo="Opening price", Yc="Closing price", Yl="Low price", Yh="High price".
+ * Each row must have exactly 4 Y values. No multiple data sets, no missing values.
+ * There are 3 subtypes, selected by $draw_candles and $always_fill.
+ * $draw_candles $always_fill Description:
+ * FALSE N/A A basic OHLC chart with a vertical line for price range, horizontal
+ * tick marks on left for opening price and right for closing price.
+ * TRUE FALSE A candlestick plot with filled body indicating close down, outline
+ * for closing up, and vertical wicks for low and high prices.
+ * TRUE TRUE A candlestick plot where the candle bodies are always filled.
+ * These map to 3 plot types per the $plots[] array.
+ *
+ * Data color usage: If closes down: If closes up or unchanged:
+ * Candlestick body, ohlc range line: color 0 color 1
+ * Candlestick wicks, ohlc tick marks: color 2 color 3
+ * There are three member variables that control the width (candlestick body or tick marks):
+ * ohlc_max_width, ohlc_min_width, ohlc_frac_width
+ * (There is no API to change them at this time.)
+ */
+ protected function DrawOHLC($draw_candles, $always_fill = FALSE)
+ {
+ if (!$this->CheckDataType('text-data, data-data'))
+ return FALSE;
+
+ // Assign name of GD function to draw candlestick bodies for stocks that close up.
+ $draw_body_close_up = $always_fill ? 'imagefilledrectangle' : 'imagerectangle';
+
+ // These 3 variables control the calculation of the half-width of the candle body, or length of
+ // the tick marks. This is scaled based on the plot density, but within tight limits.
+ $min_width = isset($this->ohlc_min_width) ? $this->ohlc_min_width : 2;
+ $max_width = isset($this->ohlc_max_width) ? $this->ohlc_max_width : 8;
+ $width_factor = isset($this->ohlc_frac_width) ? $this->ohlc_frac_width : 0.3;
+ $dw = max($min_width, min($max_width,
+ (int)($width_factor * $this->plot_area_width / $this->num_data_rows)));
+
+ // Get line widths to use: index 0 for body/stroke, 1 for wick/tick.
+ list($body_thickness, $wick_thickness) = $this->line_widths;
+
+ $gcvars = array(); // For GetDataColor, which initializes and uses this.
+
+ for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) {
+ $record = 1; // Skip record #0 (data label)
+
+ if ($this->datatype_implied) // Implied X values?
+ $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc...
+ else
+ $x_now = $this->data[$row][$record++]; // Read it, advance record index
+
+ $x_now_pixels = $this->xtr($x_now); // Convert X to device coordinates
+ $x_left = $x_now_pixels - $dw;
+ $x_right = $x_now_pixels + $dw;
+
+ if ($this->x_data_label_pos != 'none') // Draw X Data labels?
+ $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row);
+
+ // Require and use 4 numeric values in each row.
+ if ($this->num_recs[$row] - $record != 4
+ || !is_numeric($yo = $this->data[$row][$record++])
+ || !is_numeric($yh = $this->data[$row][$record++])
+ || !is_numeric($yl = $this->data[$row][$record++])
+ || !is_numeric($yc = $this->data[$row][$record++])) {
+ return $this->PrintError("DrawOHLC: row $row must have 4 values.");
+ }
+
+ // Set device coordinates for each value and direction flag:
+ $yh_pixels = $this->ytr($yh);
+ $yl_pixels = $this->ytr($yl);
+ $yc_pixels = $this->ytr($yc);
+ $yo_pixels = $this->ytr($yo);
+ $closed_up = $yc >= $yo;
+
+ // Get data colors and line thicknesses:
+ if ($closed_up) {
+ $this->GetDataColor($row, 1, $gcvars, $body_color); // Color 1 for body, closing up
+ $this->GetDataColor($row, 3, $gcvars, $ext_color); // Color 3 for wicks/ticks
+ } else {
+ $this->GetDataColor($row, 0, $gcvars, $body_color); // Color 0 for body, closing down
+ $this->GetDataColor($row, 2, $gcvars, $ext_color); // Color 2 for wicks/ticks
+ }
+ imagesetthickness($this->img, $body_thickness);
+
+ if ($draw_candles) {
+ // Note: Unlike ImageFilledRectangle, ImageRectangle 'requires' its arguments in
+ // order with upper left corner first.
+ if ($closed_up) {
+ $yb1_pixels = $yc_pixels; // Upper body Y
+ $yb2_pixels = $yo_pixels; // Lower body Y
+ $draw_body = $draw_body_close_up;
+ // Avoid a PHP/GD bug resulting in "T"-shaped ends to zero height unfilled rectangle:
+ if ($yb1_pixels == $yb2_pixels)
+ $draw_body = 'imagefilledrectangle';
+ } else {
+ $yb1_pixels = $yo_pixels;
+ $yb2_pixels = $yc_pixels;
+ $draw_body = 'imagefilledrectangle';
+ }
+
+ // Draw candle body
+ $draw_body($this->img, $x_left, $yb1_pixels, $x_right, $yb2_pixels, $body_color);
+
+ // Draw upper and lower wicks, if they have height. (In device coords, that's dY<0)
+ imagesetthickness($this->img, $wick_thickness);
+ if ($yh_pixels < $yb1_pixels) {
+ imageline($this->img, $x_now_pixels, $yb1_pixels, $x_now_pixels, $yh_pixels, $ext_color);
+ }
+ if ($yl_pixels > $yb2_pixels) {
+ imageline($this->img, $x_now_pixels, $yb2_pixels, $x_now_pixels, $yl_pixels, $ext_color);
+ }
+ } else {
+ // Basic OHLC
+ imageline($this->img, $x_now_pixels, $yl_pixels, $x_now_pixels, $yh_pixels, $body_color);
+ imagesetthickness($this->img, $wick_thickness);
+ imageline($this->img, $x_left, $yo_pixels, $x_now_pixels, $yo_pixels, $ext_color);
+ imageline($this->img, $x_right, $yc_pixels, $x_now_pixels, $yc_pixels, $ext_color);
+ }
+ imagesetthickness($this->img, 1);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Draw the graph.
+ * This is the function that performs the actual drawing, after all
+ * the parameters and data are set up.
+ * It also outputs the finished image, unless told not to.
+ * Note: It is possible for this to be called multiple times.
+ */
+ function DrawGraph()
+ {
+ // Test for missing image, missing data, empty data:
+ if (!$this->CheckDataArray())
+ return FALSE; // Error message already reported.
+
+ // Set defaults then import plot type configuration:
+ $draw_axes = TRUE;
+ $draw_arg = array(); // Default is: no arguments to the drawing function
+ extract(PHPlot::$plots[$this->plot_type]);
+
+ // Allocate colors for the plot:
+ $this->SetColorIndexes();
+
+ // Get maxima and minima for scaling:
+ if (!$this->FindDataLimits())
+ return FALSE;
+
+ // Set plot area world values (plot_max_x, etc.):
+ if (!$this->CalcPlotAreaWorld())
+ return FALSE;
+
+ // Calculate X and Y axis positions in World Coordinates:
+ $this->CalcAxisPositions();
+
+ // Process label-related parameters:
+ $this->CheckLabels();
+
+ // Apply grid defaults:
+ $this->CalcGridSettings();
+
+ // Calculate the plot margins, if needed.
+ // For pie charts, set the $maximize argument to maximize space usage.
+ $this->CalcMargins(!$draw_axes);
+
+ // Calculate the actual plot area in device coordinates:
+ $this->CalcPlotAreaPixels();
+
+ // Calculate the mapping between world and device coordinates:
+ $this->CalcTranslation();
+
+ // Pad color and style arrays to fit records per group:
+ $this->PadArrays();
+ $this->DoCallback('draw_setup');
+
+ $this->DrawBackground();
+ $this->DrawImageBorder();
+ $this->DoCallback('draw_image_background');
+
+ $this->DrawPlotAreaBackground();
+ $this->DoCallback('draw_plotarea_background', $this->plot_area);
+
+ $this->DrawTitle();
+ if ($draw_axes) { // If no axes (pie chart), no axis titles either
+ $this->DrawXTitle();
+ $this->DrawYTitle();
+ }
+ $this->DoCallback('draw_titles');
+
+ if ($draw_axes && ! $this->grid_at_foreground) { // Usually one wants grids to go back, but...
+ $this->DrawYAxis(); // Y axis must be drawn before X axis (see DrawYAxis())
+ $this->DrawXAxis();
+ $this->DoCallback('draw_axes');
+ }
+
+ // Call the plot-type drawing method:
+ call_user_func_array(array($this, $draw_method), $draw_arg);
+ $this->DoCallback('draw_graph', $this->plot_area);
+
+ if ($draw_axes && $this->grid_at_foreground) { // Usually one wants grids to go back, but...
+ $this->DrawYAxis(); // Y axis must be drawn before X axis (see DrawYAxis())
+ $this->DrawXAxis();
+ $this->DoCallback('draw_axes');
+ }
+
+ if ($draw_axes) {
+ $this->DrawPlotBorder();
+ $this->DoCallback('draw_border');
+ }
+
+ if ($this->legend) {
+ $this->DrawLegend();
+ $this->DoCallback('draw_legend');
+ }
+ $this->DoCallback('draw_all', $this->plot_area);
+
+ if ($this->print_image && !$this->PrintImage())
+ return FALSE;
+
+ return TRUE;
+ }
+
+/////////////////////////////////////////////
+////////////////// DEPRECATED METHODS
+/////////////////////////////////////////////
+
+ /*
+ * Note on deprecated methods - as these pre-date the PHPlot Reference
+ * Manual, and there is minimal documentation about them, I have neither
+ * removed them nor changed them. They are not tested or documented, and
+ * should not be used.
+ */
+
+ /*
+ * Deprecated, use SetYTickPos()
+ */
+ function SetDrawVertTicks($which_dvt)
+ {
+ if ($which_dvt != 1)
+ $this->SetYTickPos('none');
+ return TRUE;
+ }
+
+ /*
+ * Deprecated, use SetXTickPos()
+ */
+ function SetDrawHorizTicks($which_dht)
+ {
+ if ($which_dht != 1)
+ $this->SetXTickPos('none');
+ return TRUE;
+ }
+
+ /*
+ * Deprecated - use SetNumXTicks()
+ */
+ function SetNumHorizTicks($n)
+ {
+ return $this->SetNumXTicks($n);
+ }
+
+ /*
+ * Deprecated - use SetNumYTicks()
+ */
+ function SetNumVertTicks($n)
+ {
+ return $this->SetNumYTicks($n);
+ }
+
+ /*
+ * Deprecated - use SetXTickIncrement()
+ */
+ function SetHorizTickIncrement($inc)
+ {
+ return $this->SetXTickIncrement($inc);
+ }
+
+ /*
+ * Deprecated - use SetYTickIncrement()
+ */
+ function SetVertTickIncrement($inc)
+ {
+ return $this->SetYTickIncrement($inc);
+ }
+
+ /*
+ * Deprecated - use SetYTickPos()
+ */
+ function SetVertTickPosition($which_tp)
+ {
+ return $this->SetYTickPos($which_tp);
+ }
+
+ /*
+ * Deprecated - use SetXTickPos()
+ */
+ function SetHorizTickPosition($which_tp)
+ {
+ return $this->SetXTickPos($which_tp);
+ }
+
+ /*
+ * Deprecated - use SetFont()
+ */
+ function SetTitleFontSize($which_size)
+ {
+ return $this->SetFont('title', $which_size);
+ }
+
+ /*
+ * Deprecated - use SetFont()
+ */
+ function SetAxisFontSize($which_size)
+ {
+ $this->SetFont('x_label', $which_size);
+ $this->SetFont('y_label', $which_size);
+ }
+
+ /*
+ * Deprecated - use SetFont()
+ */
+ function SetSmallFontSize($which_size)
+ {
+ return $this->SetFont('generic', $which_size);
+ }
+
+ /*
+ * Deprecated - use SetFont()
+ */
+ function SetXLabelFontSize($which_size)
+ {
+ return $this->SetFont('x_title', $which_size);
+ }
+
+ /*
+ * Deprecated - use SetFont()
+ */
+ function SetYLabelFontSize($which_size)
+ {
+ return $this->SetFont('y_title', $which_size);
+ }
+
+ /*
+ * Deprecated - use SetXTitle()
+ */
+ function SetXLabel($which_xlab)
+ {
+ return $this->SetXTitle($which_xlab);
+ }
+
+ /*
+ * Deprecated - use SetYTitle()
+ */
+ function SetYLabel($which_ylab)
+ {
+ return $this->SetYTitle($which_ylab);
+ }
+
+ /*
+ * Deprecated - use SetXTickLength() and SetYTickLength() instead.
+ */
+ function SetTickLength($which_tl)
+ {
+ $this->SetXTickLength($which_tl);
+ $this->SetYTickLength($which_tl);
+ return TRUE;
+ }
+
+ /*
+ * Deprecated - use SetYLabelType()
+ */
+ function SetYGridLabelType($which_yglt)
+ {
+ return $this->SetYLabelType($which_yglt);
+ }
+
+ /*
+ * Deprecated - use SetXLabelType()
+ */
+ function SetXGridLabelType($which_xglt)
+ {
+ return $this->SetXLabelType($which_xglt);
+ }
+ /*
+ * Deprecated - use SetYTickLabelPos()
+ */
+ function SetYGridLabelPos($which_yglp)
+ {
+ return $this->SetYTickLabelPos($which_yglp);
+ }
+ /*
+ * Deprecated - use SetXTickLabelPos()
+ */
+ function SetXGridLabelPos($which_xglp)
+ {
+ return $this->SetXTickLabelPos($which_xglp);
+ }
+
+ /*
+ * Deprecated - use SetXtitle()
+ */
+ function SetXTitlePos($xpos)
+ {
+ $this->x_title_pos = $xpos;
+ return TRUE;
+ }
+
+ /*
+ * Deprecated - use SetYTitle()
+ */
+ function SetYTitlePos($xpos)
+ {
+ $this->y_title_pos = $xpos;
+ return TRUE;
+ }
+
+ /*
+ * Deprecated - use SetXDataLabelPos()
+ */
+ function SetDrawXDataLabels($which_dxdl)
+ {
+ if ($which_dxdl == '1' )
+ $this->SetXDataLabelPos('plotdown');
+ else
+ $this->SetXDataLabelPos('none');
+ }
+
+ /*
+ * Deprecated - use SetPlotAreaPixels()
+ */
+ function SetNewPlotAreaPixels($x1, $y1, $x2, $y2)
+ {
+ return $this->SetPlotAreaPixels($x1, $y1, $x2, $y2);
+ }
+
+ /*
+ * Deprecated - use SetLineWidths().
+ */
+ function SetLineWidth($which_lw)
+ {
+
+ $this->SetLineWidths($which_lw);
+
+ if (!$this->error_bar_line_width) {
+ $this->SetErrorBarLineWidth($which_lw);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Deprecated - use SetPointShapes().
+ */
+ function SetPointShape($which_pt)
+ {
+ $this->SetPointShapes($which_pt);
+ return TRUE;
+ }
+
+ /*
+ * Deprecated - use SetPointSizes().
+ */
+ function SetPointSize($which_ps)
+ {
+ $this->SetPointSizes($which_ps);
+ return TRUE;
+ }
+}
+
+/*
+ * The PHPlot_truecolor class extends PHPlot to use GD truecolor images.
+ */
+
+class PHPlot_truecolor extends PHPlot
+{
+ /*
+ * PHPlot Truecolor variation constructor: Create a PHPlot_truecolor object and initialize it.
+ * Note this does NOT call the parent (PHPlot) constructor. It duplicates the code here.
+ * Everything is the same as the PHPlot constructor except for imagecreatetruecolor.
+ *
+ * Parameters are the same as PHPlot:
+ * $which_width : Image width in pixels.
+ * $which_height : Image height in pixels.
+ * $which_output_file : Filename for output.
+ * $which_input_file : Path to a file to be used as background.
+ */
+ function __construct($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL)
+ {
+ $this->SetRGBArray($this->color_array);
+
+ if ($which_output_file)
+ $this->SetOutputFile($which_output_file);
+
+ if ($which_input_file) {
+ $this->SetInputFile($which_input_file);
+ } else {
+ $this->image_width = $which_width;
+ $this->image_height = $which_height;
+
+ $this->img = imagecreatetruecolor($this->image_width, $this->image_height);
+ if (! $this->img)
+ return $this->PrintError('PHPlot_truecolor(): Could not create image resource.');
+ }
+
+ $this->SetDefaultStyles();
+ $this->SetDefaultFonts();
+ }
+}
--- /dev/null
+<?php
+/* $Id: rgb.inc.php,v 1.2 2009/06/12 01:58:35 lbayuk Exp $ */
+/*
+ * This is a large color map which can be used by PHPlot via
+ * $plot->SetRGBArray('large')
+ * For more information on PHPlot see http://sourceforge.net/projects/phplot/
+ *
+ * rgb.inc.php comes with PHPlot but is derived from the X11 rgb.txt color
+ * database file, which contains no specific copyright notice. It may be
+ * covered by X.Org, XFree86, or MIT/X11 copyright and license, all of which
+ * allow redistribution on terms which are less strict than the LGPL which
+ * covers PHPlot.
+ */
+$ColorArray = array(
+ "snow" => array(255, 250, 250),
+ "ghost white" => array(248, 248, 255),
+ "GhostWhite" => array(248, 248, 255),
+ "white smoke" => array(245, 245, 245),
+ "WhiteSmoke" => array(245, 245, 245),
+ "gainsboro" => array(220, 220, 220),
+ "floral white" => array(255, 250, 240),
+ "FloralWhite" => array(255, 250, 240),
+ "old lace" => array(253, 245, 230),
+ "OldLace" => array(253, 245, 230),
+ "linen" => array(250, 240, 230),
+ "antique white" => array(250, 235, 215),
+ "AntiqueWhite" => array(250, 235, 215),
+ "papaya whip" => array(255, 239, 213),
+ "PapayaWhip" => array(255, 239, 213),
+ "blanched almond" => array(255, 235, 205),
+ "BlanchedAlmond" => array(255, 235, 205),
+ "bisque" => array(255, 228, 196),
+ "peach puff" => array(255, 218, 185),
+ "PeachPuff" => array(255, 218, 185),
+ "navajo white" => array(255, 222, 173),
+ "NavajoWhite" => array(255, 222, 173),
+ "moccasin" => array(255, 228, 181),
+ "cornsilk" => array(255, 248, 220),
+ "ivory" => array(255, 255, 240),
+ "lemon chiffon" => array(255, 250, 205),
+ "LemonChiffon" => array(255, 250, 205),
+ "seashell" => array(255, 245, 238),
+ "honeydew" => array(240, 255, 240),
+ "mint cream" => array(245, 255, 250),
+ "MintCream" => array(245, 255, 250),
+ "azure" => array(240, 255, 255),
+ "alice blue" => array(240, 248, 255),
+ "AliceBlue" => array(240, 248, 255),
+ "lavender" => array(230, 230, 250),
+ "lavender blush" => array(255, 240, 245),
+ "LavenderBlush" => array(255, 240, 245),
+ "misty rose" => array(255, 228, 225),
+ "MistyRose" => array(255, 228, 225),
+ "white" => array(255, 255, 255),
+ "black" => array( 0, 0, 0),
+ "dark slate gray" => array( 47, 79, 79),
+ "DarkSlateGray" => array( 47, 79, 79),
+ "dark slate grey" => array( 47, 79, 79),
+ "DarkSlateGrey" => array( 47, 79, 79),
+ "dim gray" => array(105, 105, 105),
+ "DimGray" => array(105, 105, 105),
+ "dim grey" => array(105, 105, 105),
+ "DimGrey" => array(105, 105, 105),
+ "slate gray" => array(112, 128, 144),
+ "SlateGray" => array(112, 128, 144),
+ "slate grey" => array(112, 128, 144),
+ "SlateGrey" => array(112, 128, 144),
+ "light slate gray" => array(119, 136, 153),
+ "LightSlateGray" => array(119, 136, 153),
+ "light slate grey" => array(119, 136, 153),
+ "LightSlateGrey" => array(119, 136, 153),
+ "gray" => array(190, 190, 190),
+ "grey" => array(190, 190, 190),
+ "light grey" => array(211, 211, 211),
+ "LightGrey" => array(211, 211, 211),
+ "light gray" => array(211, 211, 211),
+ "LightGray" => array(211, 211, 211),
+ "midnight blue" => array( 25, 25, 112),
+ "MidnightBlue" => array( 25, 25, 112),
+ "navy" => array( 0, 0, 128),
+ "navy blue" => array( 0, 0, 128),
+ "NavyBlue" => array( 0, 0, 128),
+ "cornflower blue" => array(100, 149, 237),
+ "CornflowerBlue" => array(100, 149, 237),
+ "dark slate blue" => array( 72, 61, 139),
+ "DarkSlateBlue" => array( 72, 61, 139),
+ "slate blue" => array(106, 90, 205),
+ "SlateBlue" => array(106, 90, 205),
+ "medium slate blue" => array(123, 104, 238),
+ "MediumSlateBlue" => array(123, 104, 238),
+ "light slate blue" => array(132, 112, 255),
+ "LightSlateBlue" => array(132, 112, 255),
+ "medium blue" => array( 0, 0, 205),
+ "MediumBlue" => array( 0, 0, 205),
+ "royal blue" => array( 65, 105, 225),
+ "RoyalBlue" => array( 65, 105, 225),
+ "blue" => array( 0, 0, 255),
+ "dodger blue" => array( 30, 144, 255),
+ "DodgerBlue" => array( 30, 144, 255),
+ "deep sky blue" => array( 0, 191, 255),
+ "DeepSkyBlue" => array( 0, 191, 255),
+ "sky blue" => array(135, 206, 235),
+ "SkyBlue" => array(135, 206, 235),
+ "light sky blue" => array(135, 206, 250),
+ "LightSkyBlue" => array(135, 206, 250),
+ "steel blue" => array( 70, 130, 180),
+ "SteelBlue" => array( 70, 130, 180),
+ "light steel blue" => array(176, 196, 222),
+ "LightSteelBlue" => array(176, 196, 222),
+ "light blue" => array(173, 216, 230),
+ "LightBlue" => array(173, 216, 230),
+ "powder blue" => array(176, 224, 230),
+ "PowderBlue" => array(176, 224, 230),
+ "pale turquoise" => array(175, 238, 238),
+ "PaleTurquoise" => array(175, 238, 238),
+ "dark turquoise" => array( 0, 206, 209),
+ "DarkTurquoise" => array( 0, 206, 209),
+ "medium turquoise" => array( 72, 209, 204),
+ "MediumTurquoise" => array( 72, 209, 204),
+ "turquoise" => array( 64, 224, 208),
+ "cyan" => array( 0, 255, 255),
+ "light cyan" => array(224, 255, 255),
+ "LightCyan" => array(224, 255, 255),
+ "cadet blue" => array( 95, 158, 160),
+ "CadetBlue" => array( 95, 158, 160),
+ "medium aquamarine" => array(102, 205, 170),
+ "MediumAquamarine" => array(102, 205, 170),
+ "aquamarine" => array(127, 255, 212),
+ "dark green" => array( 0, 100, 0),
+ "DarkGreen" => array( 0, 100, 0),
+ "dark olive green" => array( 85, 107, 47),
+ "DarkOliveGreen" => array( 85, 107, 47),
+ "dark sea green" => array(143, 188, 143),
+ "DarkSeaGreen" => array(143, 188, 143),
+ "sea green" => array( 46, 139, 87),
+ "SeaGreen" => array( 46, 139, 87),
+ "medium sea green" => array( 60, 179, 113),
+ "MediumSeaGreen" => array( 60, 179, 113),
+ "light sea green" => array( 32, 178, 170),
+ "LightSeaGreen" => array( 32, 178, 170),
+ "pale green" => array(152, 251, 152),
+ "PaleGreen" => array(152, 251, 152),
+ "spring green" => array( 0, 255, 127),
+ "SpringGreen" => array( 0, 255, 127),
+ "lawn green" => array(124, 252, 0),
+ "LawnGreen" => array(124, 252, 0),
+ "green" => array( 0, 255, 0),
+ "chartreuse" => array(127, 255, 0),
+ "medium spring green" => array( 0, 250, 154),
+ "MediumSpringGreen" => array( 0, 250, 154),
+ "green yellow" => array(173, 255, 47),
+ "GreenYellow" => array(173, 255, 47),
+ "lime green" => array( 50, 205, 50),
+ "LimeGreen" => array( 50, 205, 50),
+ "yellow green" => array(154, 205, 50),
+ "YellowGreen" => array(154, 205, 50),
+ "forest green" => array( 34, 139, 34),
+ "ForestGreen" => array( 34, 139, 34),
+ "olive drab" => array(107, 142, 35),
+ "OliveDrab" => array(107, 142, 35),
+ "dark khaki" => array(189, 183, 107),
+ "DarkKhaki" => array(189, 183, 107),
+ "khaki" => array(240, 230, 140),
+ "pale goldenrod" => array(238, 232, 170),
+ "PaleGoldenrod" => array(238, 232, 170),
+ "light goldenrod yellow" => array(250, 250, 210),
+ "LightGoldenrodYellow" => array(250, 250, 210),
+ "light yellow" => array(255, 255, 224),
+ "LightYellow" => array(255, 255, 224),
+ "yellow" => array(255, 255, 0),
+ "gold" => array(255, 215, 0),
+ "light goldenrod" => array(238, 221, 130),
+ "LightGoldenrod" => array(238, 221, 130),
+ "goldenrod" => array(218, 165, 32),
+ "dark goldenrod" => array(184, 134, 11),
+ "DarkGoldenrod" => array(184, 134, 11),
+ "rosy brown" => array(188, 143, 143),
+ "RosyBrown" => array(188, 143, 143),
+ "indian red" => array(205, 92, 92),
+ "IndianRed" => array(205, 92, 92),
+ "saddle brown" => array(139, 69, 19),
+ "SaddleBrown" => array(139, 69, 19),
+ "sienna" => array(160, 82, 45),
+ "peru" => array(205, 133, 63),
+ "burlywood" => array(222, 184, 135),
+ "beige" => array(245, 245, 220),
+ "wheat" => array(245, 222, 179),
+ "sandy brown" => array(244, 164, 96),
+ "SandyBrown" => array(244, 164, 96),
+ "tan" => array(210, 180, 140),
+ "chocolate" => array(210, 105, 30),
+ "firebrick" => array(178, 34, 34),
+ "brown" => array(165, 42, 42),
+ "dark salmon" => array(233, 150, 122),
+ "DarkSalmon" => array(233, 150, 122),
+ "salmon" => array(250, 128, 114),
+ "light salmon" => array(255, 160, 122),
+ "LightSalmon" => array(255, 160, 122),
+ "orange" => array(255, 165, 0),
+ "dark orange" => array(255, 140, 0),
+ "DarkOrange" => array(255, 140, 0),
+ "coral" => array(255, 127, 80),
+ "light coral" => array(240, 128, 128),
+ "LightCoral" => array(240, 128, 128),
+ "tomato" => array(255, 99, 71),
+ "orange red" => array(255, 69, 0),
+ "OrangeRed" => array(255, 69, 0),
+ "red" => array(255, 0, 0),
+ "hot pink" => array(255, 105, 180),
+ "HotPink" => array(255, 105, 180),
+ "deep pink" => array(255, 20, 147),
+ "DeepPink" => array(255, 20, 147),
+ "pink" => array(255, 192, 203),
+ "light pink" => array(255, 182, 193),
+ "LightPink" => array(255, 182, 193),
+ "pale violet red" => array(219, 112, 147),
+ "PaleVioletRed" => array(219, 112, 147),
+ "maroon" => array(176, 48, 96),
+ "medium violet red" => array(199, 21, 133),
+ "MediumVioletRed" => array(199, 21, 133),
+ "violet red" => array(208, 32, 144),
+ "VioletRed" => array(208, 32, 144),
+ "magenta" => array(255, 0, 255),
+ "violet" => array(238, 130, 238),
+ "plum" => array(221, 160, 221),
+ "orchid" => array(218, 112, 214),
+ "medium orchid" => array(186, 85, 211),
+ "MediumOrchid" => array(186, 85, 211),
+ "dark orchid" => array(153, 50, 204),
+ "DarkOrchid" => array(153, 50, 204),
+ "dark violet" => array(148, 0, 211),
+ "DarkViolet" => array(148, 0, 211),
+ "blue violet" => array(138, 43, 226),
+ "BlueViolet" => array(138, 43, 226),
+ "purple" => array(160, 32, 240),
+ "medium purple" => array(147, 112, 219),
+ "MediumPurple" => array(147, 112, 219),
+ "thistle" => array(216, 191, 216),
+ "snow1" => array(255, 250, 250),
+ "snow2" => array(238, 233, 233),
+ "snow3" => array(205, 201, 201),
+ "snow4" => array(139, 137, 137),
+ "seashell1" => array(255, 245, 238),
+ "seashell2" => array(238, 229, 222),
+ "seashell3" => array(205, 197, 191),
+ "seashell4" => array(139, 134, 130),
+ "AntiqueWhite1" => array(255, 239, 219),
+ "AntiqueWhite2" => array(238, 223, 204),
+ "AntiqueWhite3" => array(205, 192, 176),
+ "AntiqueWhite4" => array(139, 131, 120),
+ "bisque1" => array(255, 228, 196),
+ "bisque2" => array(238, 213, 183),
+ "bisque3" => array(205, 183, 158),
+ "bisque4" => array(139, 125, 107),
+ "PeachPuff1" => array(255, 218, 185),
+ "PeachPuff2" => array(238, 203, 173),
+ "PeachPuff3" => array(205, 175, 149),
+ "PeachPuff4" => array(139, 119, 101),
+ "NavajoWhite1" => array(255, 222, 173),
+ "NavajoWhite2" => array(238, 207, 161),
+ "NavajoWhite3" => array(205, 179, 139),
+ "NavajoWhite4" => array(139, 121, 94),
+ "LemonChiffon1" => array(255, 250, 205),
+ "LemonChiffon2" => array(238, 233, 191),
+ "LemonChiffon3" => array(205, 201, 165),
+ "LemonChiffon4" => array(139, 137, 112),
+ "cornsilk1" => array(255, 248, 220),
+ "cornsilk2" => array(238, 232, 205),
+ "cornsilk3" => array(205, 200, 177),
+ "cornsilk4" => array(139, 136, 120),
+ "ivory1" => array(255, 255, 240),
+ "ivory2" => array(238, 238, 224),
+ "ivory3" => array(205, 205, 193),
+ "ivory4" => array(139, 139, 131),
+ "honeydew1" => array(240, 255, 240),
+ "honeydew2" => array(224, 238, 224),
+ "honeydew3" => array(193, 205, 193),
+ "honeydew4" => array(131, 139, 131),
+ "LavenderBlush1" => array(255, 240, 245),
+ "LavenderBlush2" => array(238, 224, 229),
+ "LavenderBlush3" => array(205, 193, 197),
+ "LavenderBlush4" => array(139, 131, 134),
+ "MistyRose1" => array(255, 228, 225),
+ "MistyRose2" => array(238, 213, 210),
+ "MistyRose3" => array(205, 183, 181),
+ "MistyRose4" => array(139, 125, 123),
+ "azure1" => array(240, 255, 255),
+ "azure2" => array(224, 238, 238),
+ "azure3" => array(193, 205, 205),
+ "azure4" => array(131, 139, 139),
+ "SlateBlue1" => array(131, 111, 255),
+ "SlateBlue2" => array(122, 103, 238),
+ "SlateBlue3" => array(105, 89, 205),
+ "SlateBlue4" => array( 71, 60, 139),
+ "RoyalBlue1" => array( 72, 118, 255),
+ "RoyalBlue2" => array( 67, 110, 238),
+ "RoyalBlue3" => array( 58, 95, 205),
+ "RoyalBlue4" => array( 39, 64, 139),
+ "blue1" => array( 0, 0, 255),
+ "blue2" => array( 0, 0, 238),
+ "blue3" => array( 0, 0, 205),
+ "blue4" => array( 0, 0, 139),
+ "DodgerBlue1" => array( 30, 144, 255),
+ "DodgerBlue2" => array( 28, 134, 238),
+ "DodgerBlue3" => array( 24, 116, 205),
+ "DodgerBlue4" => array( 16, 78, 139),
+ "SteelBlue1" => array( 99, 184, 255),
+ "SteelBlue2" => array( 92, 172, 238),
+ "SteelBlue3" => array( 79, 148, 205),
+ "SteelBlue4" => array( 54, 100, 139),
+ "DeepSkyBlue1" => array( 0, 191, 255),
+ "DeepSkyBlue2" => array( 0, 178, 238),
+ "DeepSkyBlue3" => array( 0, 154, 205),
+ "DeepSkyBlue4" => array( 0, 104, 139),
+ "SkyBlue1" => array(135, 206, 255),
+ "SkyBlue2" => array(126, 192, 238),
+ "SkyBlue3" => array(108, 166, 205),
+ "SkyBlue4" => array( 74, 112, 139),
+ "LightSkyBlue1" => array(176, 226, 255),
+ "LightSkyBlue2" => array(164, 211, 238),
+ "LightSkyBlue3" => array(141, 182, 205),
+ "LightSkyBlue4" => array( 96, 123, 139),
+ "SlateGray1" => array(198, 226, 255),
+ "SlateGray2" => array(185, 211, 238),
+ "SlateGray3" => array(159, 182, 205),
+ "SlateGray4" => array(108, 123, 139),
+ "LightSteelBlue1" => array(202, 225, 255),
+ "LightSteelBlue2" => array(188, 210, 238),
+ "LightSteelBlue3" => array(162, 181, 205),
+ "LightSteelBlue4" => array(110, 123, 139),
+ "LightBlue1" => array(191, 239, 255),
+ "LightBlue2" => array(178, 223, 238),
+ "LightBlue3" => array(154, 192, 205),
+ "LightBlue4" => array(104, 131, 139),
+ "LightCyan1" => array(224, 255, 255),
+ "LightCyan2" => array(209, 238, 238),
+ "LightCyan3" => array(180, 205, 205),
+ "LightCyan4" => array(122, 139, 139),
+ "PaleTurquoise1" => array(187, 255, 255),
+ "PaleTurquoise2" => array(174, 238, 238),
+ "PaleTurquoise3" => array(150, 205, 205),
+ "PaleTurquoise4" => array(102, 139, 139),
+ "CadetBlue1" => array(152, 245, 255),
+ "CadetBlue2" => array(142, 229, 238),
+ "CadetBlue3" => array(122, 197, 205),
+ "CadetBlue4" => array( 83, 134, 139),
+ "turquoise1" => array( 0, 245, 255),
+ "turquoise2" => array( 0, 229, 238),
+ "turquoise3" => array( 0, 197, 205),
+ "turquoise4" => array( 0, 134, 139),
+ "cyan1" => array( 0, 255, 255),
+ "cyan2" => array( 0, 238, 238),
+ "cyan3" => array( 0, 205, 205),
+ "cyan4" => array( 0, 139, 139),
+ "DarkSlateGray1" => array(151, 255, 255),
+ "DarkSlateGray2" => array(141, 238, 238),
+ "DarkSlateGray3" => array(121, 205, 205),
+ "DarkSlateGray4" => array( 82, 139, 139),
+ "aquamarine1" => array(127, 255, 212),
+ "aquamarine2" => array(118, 238, 198),
+ "aquamarine3" => array(102, 205, 170),
+ "aquamarine4" => array( 69, 139, 116),
+ "DarkSeaGreen1" => array(193, 255, 193),
+ "DarkSeaGreen2" => array(180, 238, 180),
+ "DarkSeaGreen3" => array(155, 205, 155),
+ "DarkSeaGreen4" => array(105, 139, 105),
+ "SeaGreen1" => array( 84, 255, 159),
+ "SeaGreen2" => array( 78, 238, 148),
+ "SeaGreen3" => array( 67, 205, 128),
+ "SeaGreen4" => array( 46, 139, 87),
+ "PaleGreen1" => array(154, 255, 154),
+ "PaleGreen2" => array(144, 238, 144),
+ "PaleGreen3" => array(124, 205, 124),
+ "PaleGreen4" => array( 84, 139, 84),
+ "SpringGreen1" => array( 0, 255, 127),
+ "SpringGreen2" => array( 0, 238, 118),
+ "SpringGreen3" => array( 0, 205, 102),
+ "SpringGreen4" => array( 0, 139, 69),
+ "green1" => array( 0, 255, 0),
+ "green2" => array( 0, 238, 0),
+ "green3" => array( 0, 205, 0),
+ "green4" => array( 0, 139, 0),
+ "chartreuse1" => array(127, 255, 0),
+ "chartreuse2" => array(118, 238, 0),
+ "chartreuse3" => array(102, 205, 0),
+ "chartreuse4" => array( 69, 139, 0),
+ "OliveDrab1" => array(192, 255, 62),
+ "OliveDrab2" => array(179, 238, 58),
+ "OliveDrab3" => array(154, 205, 50),
+ "OliveDrab4" => array(105, 139, 34),
+ "DarkOliveGreen1" => array(202, 255, 112),
+ "DarkOliveGreen2" => array(188, 238, 104),
+ "DarkOliveGreen3" => array(162, 205, 90),
+ "DarkOliveGreen4" => array(110, 139, 61),
+ "khaki1" => array(255, 246, 143),
+ "khaki2" => array(238, 230, 133),
+ "khaki3" => array(205, 198, 115),
+ "khaki4" => array(139, 134, 78),
+ "LightGoldenrod1" => array(255, 236, 139),
+ "LightGoldenrod2" => array(238, 220, 130),
+ "LightGoldenrod3" => array(205, 190, 112),
+ "LightGoldenrod4" => array(139, 129, 76),
+ "LightYellow1" => array(255, 255, 224),
+ "LightYellow2" => array(238, 238, 209),
+ "LightYellow3" => array(205, 205, 180),
+ "LightYellow4" => array(139, 139, 122),
+ "yellow1" => array(255, 255, 0),
+ "yellow2" => array(238, 238, 0),
+ "yellow3" => array(205, 205, 0),
+ "yellow4" => array(139, 139, 0),
+ "gold1" => array(255, 215, 0),
+ "gold2" => array(238, 201, 0),
+ "gold3" => array(205, 173, 0),
+ "gold4" => array(139, 117, 0),
+ "goldenrod1" => array(255, 193, 37),
+ "goldenrod2" => array(238, 180, 34),
+ "goldenrod3" => array(205, 155, 29),
+ "goldenrod4" => array(139, 105, 20),
+ "DarkGoldenrod1" => array(255, 185, 15),
+ "DarkGoldenrod2" => array(238, 173, 14),
+ "DarkGoldenrod3" => array(205, 149, 12),
+ "DarkGoldenrod4" => array(139, 101, 8),
+ "RosyBrown1" => array(255, 193, 193),
+ "RosyBrown2" => array(238, 180, 180),
+ "RosyBrown3" => array(205, 155, 155),
+ "RosyBrown4" => array(139, 105, 105),
+ "IndianRed1" => array(255, 106, 106),
+ "IndianRed2" => array(238, 99, 99),
+ "IndianRed3" => array(205, 85, 85),
+ "IndianRed4" => array(139, 58, 58),
+ "sienna1" => array(255, 130, 71),
+ "sienna2" => array(238, 121, 66),
+ "sienna3" => array(205, 104, 57),
+ "sienna4" => array(139, 71, 38),
+ "burlywood1" => array(255, 211, 155),
+ "burlywood2" => array(238, 197, 145),
+ "burlywood3" => array(205, 170, 125),
+ "burlywood4" => array(139, 115, 85),
+ "wheat1" => array(255, 231, 186),
+ "wheat2" => array(238, 216, 174),
+ "wheat3" => array(205, 186, 150),
+ "wheat4" => array(139, 126, 102),
+ "tan1" => array(255, 165, 79),
+ "tan2" => array(238, 154, 73),
+ "tan3" => array(205, 133, 63),
+ "tan4" => array(139, 90, 43),
+ "chocolate1" => array(255, 127, 36),
+ "chocolate2" => array(238, 118, 33),
+ "chocolate3" => array(205, 102, 29),
+ "chocolate4" => array(139, 69, 19),
+ "firebrick1" => array(255, 48, 48),
+ "firebrick2" => array(238, 44, 44),
+ "firebrick3" => array(205, 38, 38),
+ "firebrick4" => array(139, 26, 26),
+ "brown1" => array(255, 64, 64),
+ "brown2" => array(238, 59, 59),
+ "brown3" => array(205, 51, 51),
+ "brown4" => array(139, 35, 35),
+ "salmon1" => array(255, 140, 105),
+ "salmon2" => array(238, 130, 98),
+ "salmon3" => array(205, 112, 84),
+ "salmon4" => array(139, 76, 57),
+ "LightSalmon1" => array(255, 160, 122),
+ "LightSalmon2" => array(238, 149, 114),
+ "LightSalmon3" => array(205, 129, 98),
+ "LightSalmon4" => array(139, 87, 66),
+ "orange1" => array(255, 165, 0),
+ "orange2" => array(238, 154, 0),
+ "orange3" => array(205, 133, 0),
+ "orange4" => array(139, 90, 0),
+ "DarkOrange1" => array(255, 127, 0),
+ "DarkOrange2" => array(238, 118, 0),
+ "DarkOrange3" => array(205, 102, 0),
+ "DarkOrange4" => array(139, 69, 0),
+ "coral1" => array(255, 114, 86),
+ "coral2" => array(238, 106, 80),
+ "coral3" => array(205, 91, 69),
+ "coral4" => array(139, 62, 47),
+ "tomato1" => array(255, 99, 71),
+ "tomato2" => array(238, 92, 66),
+ "tomato3" => array(205, 79, 57),
+ "tomato4" => array(139, 54, 38),
+ "OrangeRed1" => array(255, 69, 0),
+ "OrangeRed2" => array(238, 64, 0),
+ "OrangeRed3" => array(205, 55, 0),
+ "OrangeRed4" => array(139, 37, 0),
+ "red1" => array(255, 0, 0),
+ "red2" => array(238, 0, 0),
+ "red3" => array(205, 0, 0),
+ "red4" => array(139, 0, 0),
+ "DeepPink1" => array(255, 20, 147),
+ "DeepPink2" => array(238, 18, 137),
+ "DeepPink3" => array(205, 16, 118),
+ "DeepPink4" => array(139, 10, 80),
+ "HotPink1" => array(255, 110, 180),
+ "HotPink2" => array(238, 106, 167),
+ "HotPink3" => array(205, 96, 144),
+ "HotPink4" => array(139, 58, 98),
+ "pink1" => array(255, 181, 197),
+ "pink2" => array(238, 169, 184),
+ "pink3" => array(205, 145, 158),
+ "pink4" => array(139, 99, 108),
+ "LightPink1" => array(255, 174, 185),
+ "LightPink2" => array(238, 162, 173),
+ "LightPink3" => array(205, 140, 149),
+ "LightPink4" => array(139, 95, 101),
+ "PaleVioletRed1" => array(255, 130, 171),
+ "PaleVioletRed2" => array(238, 121, 159),
+ "PaleVioletRed3" => array(205, 104, 137),
+ "PaleVioletRed4" => array(139, 71, 93),
+ "maroon1" => array(255, 52, 179),
+ "maroon2" => array(238, 48, 167),
+ "maroon3" => array(205, 41, 144),
+ "maroon4" => array(139, 28, 98),
+ "VioletRed1" => array(255, 62, 150),
+ "VioletRed2" => array(238, 58, 140),
+ "VioletRed3" => array(205, 50, 120),
+ "VioletRed4" => array(139, 34, 82),
+ "magenta1" => array(255, 0, 255),
+ "magenta2" => array(238, 0, 238),
+ "magenta3" => array(205, 0, 205),
+ "magenta4" => array(139, 0, 139),
+ "orchid1" => array(255, 131, 250),
+ "orchid2" => array(238, 122, 233),
+ "orchid3" => array(205, 105, 201),
+ "orchid4" => array(139, 71, 137),
+ "plum1" => array(255, 187, 255),
+ "plum2" => array(238, 174, 238),
+ "plum3" => array(205, 150, 205),
+ "plum4" => array(139, 102, 139),
+ "MediumOrchid1" => array(224, 102, 255),
+ "MediumOrchid2" => array(209, 95, 238),
+ "MediumOrchid3" => array(180, 82, 205),
+ "MediumOrchid4" => array(122, 55, 139),
+ "DarkOrchid1" => array(191, 62, 255),
+ "DarkOrchid2" => array(178, 58, 238),
+ "DarkOrchid3" => array(154, 50, 205),
+ "DarkOrchid4" => array(104, 34, 139),
+ "purple1" => array(155, 48, 255),
+ "purple2" => array(145, 44, 238),
+ "purple3" => array(125, 38, 205),
+ "purple4" => array( 85, 26, 139),
+ "MediumPurple1" => array(171, 130, 255),
+ "MediumPurple2" => array(159, 121, 238),
+ "MediumPurple3" => array(137, 104, 205),
+ "MediumPurple4" => array( 93, 71, 139),
+ "thistle1" => array(255, 225, 255),
+ "thistle2" => array(238, 210, 238),
+ "thistle3" => array(205, 181, 205),
+ "thistle4" => array(139, 123, 139),
+ "gray0" => array( 0, 0, 0),
+ "grey0" => array( 0, 0, 0),
+ "gray1" => array( 3, 3, 3),
+ "grey1" => array( 3, 3, 3),
+ "gray2" => array( 5, 5, 5),
+ "grey2" => array( 5, 5, 5),
+ "gray3" => array( 8, 8, 8),
+ "grey3" => array( 8, 8, 8),
+ "gray4" => array( 10, 10, 10),
+ "grey4" => array( 10, 10, 10),
+ "gray5" => array( 13, 13, 13),
+ "grey5" => array( 13, 13, 13),
+ "gray6" => array( 15, 15, 15),
+ "grey6" => array( 15, 15, 15),
+ "gray7" => array( 18, 18, 18),
+ "grey7" => array( 18, 18, 18),
+ "gray8" => array( 20, 20, 20),
+ "grey8" => array( 20, 20, 20),
+ "gray9" => array( 23, 23, 23),
+ "grey9" => array( 23, 23, 23),
+ "gray10" => array( 26, 26, 26),
+ "grey10" => array( 26, 26, 26),
+ "gray11" => array( 28, 28, 28),
+ "grey11" => array( 28, 28, 28),
+ "gray12" => array( 31, 31, 31),
+ "grey12" => array( 31, 31, 31),
+ "gray13" => array( 33, 33, 33),
+ "grey13" => array( 33, 33, 33),
+ "gray14" => array( 36, 36, 36),
+ "grey14" => array( 36, 36, 36),
+ "gray15" => array( 38, 38, 38),
+ "grey15" => array( 38, 38, 38),
+ "gray16" => array( 41, 41, 41),
+ "grey16" => array( 41, 41, 41),
+ "gray17" => array( 43, 43, 43),
+ "grey17" => array( 43, 43, 43),
+ "gray18" => array( 46, 46, 46),
+ "grey18" => array( 46, 46, 46),
+ "gray19" => array( 48, 48, 48),
+ "grey19" => array( 48, 48, 48),
+ "gray20" => array( 51, 51, 51),
+ "grey20" => array( 51, 51, 51),
+ "gray21" => array( 54, 54, 54),
+ "grey21" => array( 54, 54, 54),
+ "gray22" => array( 56, 56, 56),
+ "grey22" => array( 56, 56, 56),
+ "gray23" => array( 59, 59, 59),
+ "grey23" => array( 59, 59, 59),
+ "gray24" => array( 61, 61, 61),
+ "grey24" => array( 61, 61, 61),
+ "gray25" => array( 64, 64, 64),
+ "grey25" => array( 64, 64, 64),
+ "gray26" => array( 66, 66, 66),
+ "grey26" => array( 66, 66, 66),
+ "gray27" => array( 69, 69, 69),
+ "grey27" => array( 69, 69, 69),
+ "gray28" => array( 71, 71, 71),
+ "grey28" => array( 71, 71, 71),
+ "gray29" => array( 74, 74, 74),
+ "grey29" => array( 74, 74, 74),
+ "gray30" => array( 77, 77, 77),
+ "grey30" => array( 77, 77, 77),
+ "gray31" => array( 79, 79, 79),
+ "grey31" => array( 79, 79, 79),
+ "gray32" => array( 82, 82, 82),
+ "grey32" => array( 82, 82, 82),
+ "gray33" => array( 84, 84, 84),
+ "grey33" => array( 84, 84, 84),
+ "gray34" => array( 87, 87, 87),
+ "grey34" => array( 87, 87, 87),
+ "gray35" => array( 89, 89, 89),
+ "grey35" => array( 89, 89, 89),
+ "gray36" => array( 92, 92, 92),
+ "grey36" => array( 92, 92, 92),
+ "gray37" => array( 94, 94, 94),
+ "grey37" => array( 94, 94, 94),
+ "gray38" => array( 97, 97, 97),
+ "grey38" => array( 97, 97, 97),
+ "gray39" => array( 99, 99, 99),
+ "grey39" => array( 99, 99, 99),
+ "gray40" => array(102, 102, 102),
+ "grey40" => array(102, 102, 102),
+ "gray41" => array(105, 105, 105),
+ "grey41" => array(105, 105, 105),
+ "gray42" => array(107, 107, 107),
+ "grey42" => array(107, 107, 107),
+ "gray43" => array(110, 110, 110),
+ "grey43" => array(110, 110, 110),
+ "gray44" => array(112, 112, 112),
+ "grey44" => array(112, 112, 112),
+ "gray45" => array(115, 115, 115),
+ "grey45" => array(115, 115, 115),
+ "gray46" => array(117, 117, 117),
+ "grey46" => array(117, 117, 117),
+ "gray47" => array(120, 120, 120),
+ "grey47" => array(120, 120, 120),
+ "gray48" => array(122, 122, 122),
+ "grey48" => array(122, 122, 122),
+ "gray49" => array(125, 125, 125),
+ "grey49" => array(125, 125, 125),
+ "gray50" => array(127, 127, 127),
+ "grey50" => array(127, 127, 127),
+ "gray51" => array(130, 130, 130),
+ "grey51" => array(130, 130, 130),
+ "gray52" => array(133, 133, 133),
+ "grey52" => array(133, 133, 133),
+ "gray53" => array(135, 135, 135),
+ "grey53" => array(135, 135, 135),
+ "gray54" => array(138, 138, 138),
+ "grey54" => array(138, 138, 138),
+ "gray55" => array(140, 140, 140),
+ "grey55" => array(140, 140, 140),
+ "gray56" => array(143, 143, 143),
+ "grey56" => array(143, 143, 143),
+ "gray57" => array(145, 145, 145),
+ "grey57" => array(145, 145, 145),
+ "gray58" => array(148, 148, 148),
+ "grey58" => array(148, 148, 148),
+ "gray59" => array(150, 150, 150),
+ "grey59" => array(150, 150, 150),
+ "gray60" => array(153, 153, 153),
+ "grey60" => array(153, 153, 153),
+ "gray61" => array(156, 156, 156),
+ "grey61" => array(156, 156, 156),
+ "gray62" => array(158, 158, 158),
+ "grey62" => array(158, 158, 158),
+ "gray63" => array(161, 161, 161),
+ "grey63" => array(161, 161, 161),
+ "gray64" => array(163, 163, 163),
+ "grey64" => array(163, 163, 163),
+ "gray65" => array(166, 166, 166),
+ "grey65" => array(166, 166, 166),
+ "gray66" => array(168, 168, 168),
+ "grey66" => array(168, 168, 168),
+ "gray67" => array(171, 171, 171),
+ "grey67" => array(171, 171, 171),
+ "gray68" => array(173, 173, 173),
+ "grey68" => array(173, 173, 173),
+ "gray69" => array(176, 176, 176),
+ "grey69" => array(176, 176, 176),
+ "gray70" => array(179, 179, 179),
+ "grey70" => array(179, 179, 179),
+ "gray71" => array(181, 181, 181),
+ "grey71" => array(181, 181, 181),
+ "gray72" => array(184, 184, 184),
+ "grey72" => array(184, 184, 184),
+ "gray73" => array(186, 186, 186),
+ "grey73" => array(186, 186, 186),
+ "gray74" => array(189, 189, 189),
+ "grey74" => array(189, 189, 189),
+ "gray75" => array(191, 191, 191),
+ "grey75" => array(191, 191, 191),
+ "gray76" => array(194, 194, 194),
+ "grey76" => array(194, 194, 194),
+ "gray77" => array(196, 196, 196),
+ "grey77" => array(196, 196, 196),
+ "gray78" => array(199, 199, 199),
+ "grey78" => array(199, 199, 199),
+ "gray79" => array(201, 201, 201),
+ "grey79" => array(201, 201, 201),
+ "gray80" => array(204, 204, 204),
+ "grey80" => array(204, 204, 204),
+ "gray81" => array(207, 207, 207),
+ "grey81" => array(207, 207, 207),
+ "gray82" => array(209, 209, 209),
+ "grey82" => array(209, 209, 209),
+ "gray83" => array(212, 212, 212),
+ "grey83" => array(212, 212, 212),
+ "gray84" => array(214, 214, 214),
+ "grey84" => array(214, 214, 214),
+ "gray85" => array(217, 217, 217),
+ "grey85" => array(217, 217, 217),
+ "gray86" => array(219, 219, 219),
+ "grey86" => array(219, 219, 219),
+ "gray87" => array(222, 222, 222),
+ "grey87" => array(222, 222, 222),
+ "gray88" => array(224, 224, 224),
+ "grey88" => array(224, 224, 224),
+ "gray89" => array(227, 227, 227),
+ "grey89" => array(227, 227, 227),
+ "gray90" => array(229, 229, 229),
+ "grey90" => array(229, 229, 229),
+ "gray91" => array(232, 232, 232),
+ "grey91" => array(232, 232, 232),
+ "gray92" => array(235, 235, 235),
+ "grey92" => array(235, 235, 235),
+ "gray93" => array(237, 237, 237),
+ "grey93" => array(237, 237, 237),
+ "gray94" => array(240, 240, 240),
+ "grey94" => array(240, 240, 240),
+ "gray95" => array(242, 242, 242),
+ "grey95" => array(242, 242, 242),
+ "gray96" => array(245, 245, 245),
+ "grey96" => array(245, 245, 245),
+ "gray97" => array(247, 247, 247),
+ "grey97" => array(247, 247, 247),
+ "gray98" => array(250, 250, 250),
+ "grey98" => array(250, 250, 250),
+ "gray99" => array(252, 252, 252),
+ "grey99" => array(252, 252, 252),
+ "gray100" => array(255, 255, 255)
+);
--- /dev/null
+Smarty is supported only in PHP 4.0.6 or later.
+
+Smarty versions previous to 2.0 require the PEAR libraries. Be sure to include
+the path to the PEAR libraries in your php include_path. Config_file.class.php
+uses the PEAR library for its error handling routines. PEAR comes with the PHP
+distribution. Unix users check /usr/local/lib/php, windows users check
+C:/php/pear.
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
--- /dev/null
+2007-09-27 TAKAGI Masahiro <matakagi@gmail.com>
+
+ * docs/ja/designers/language-custom-functions/language-function-html-checkboxes.xml:
+ sync with en.
+
+2007-09-27 Monte Ohrt <monte@ohrt.com>
+
+ * docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml:
+ remove redundant attribute
+
+2007-09-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/id/programmers/plugins/plugins-functions.xml:
+ removed errornous whitespace
+
+2007-09-18 Zaenal Mutaqin <zaenalm@gmail.com>
+
+ * docs/id/designers/language-basic-syntax/language-escaping.xml
+ docs/id/designers/language-basic-syntax/language-math.xml
+ docs/id/designers/language-basic-syntax/language-syntax-attributes.xml
+ docs/id/designers/language-basic-syntax/language-syntax-comments.xml
+ docs/id/designers/language-basic-syntax/language-syntax-functions.xml
+ docs/id/designers/language-basic-syntax/language-syntax-quotes.xml
+ docs/id/designers/language-basic-syntax/language-syntax-variables.xml
+ docs/id/designers/language-builtin-functions/language-function-capture.xml
+ docs/id/designers/language-builtin-functions/language-function-config-load.xml
+ docs/id/designers/language-builtin-functions/language-function-foreach.xml
+ docs/id/designers/language-builtin-functions/language-function-if.xml
+ docs/id/designers/language-builtin-functions/language-function-include-php.xml
+ docs/id/designers/language-builtin-functions/language-function-include.xml
+ docs/id/designers/language-builtin-functions/language-function-insert.xml
+ docs/id/designers/language-builtin-functions/language-function-ldelim.xml
+ docs/id/designers/language-builtin-functions/language-function-literal.xml
+ docs/id/designers/language-builtin-functions/language-function-php.xml
+ docs/id/designers/language-builtin-functions/language-function-section.xml
+ docs/id/designers/language-builtin-functions/language-function-strip.xml
+ docs/id/designers/language-custom-functions/language-function-assign.xml
+ docs/id/designers/language-custom-functions/language-function-counter.xml
+ docs/id/designers/language-custom-functions/language-function-cycle.xml
+ docs/id/designers/language-custom-functions/language-function-debug.xml
+ docs/id/designers/language-custom-functions/language-function-eval.xml
+ docs/id/designers/language-custom-functions/language-function-fetch.xml
+ docs/id/designers/language-custom-functions/language-function-html-checkboxes.xml
+ docs/id/designers/language-custom-functions/language-function-html-image.xml
+ docs/id/designers/language-custom-functions/language-function-html-options.xml
+ docs/id/designers/language-custom-functions/language-function-html-radios.xml
+ docs/id/designers/language-custom-functions/language-function-html-select-date.xml
+ docs/id/designers/language-custom-functions/language-function-html-select-time.xml
+ docs/id/designers/language-custom-functions/language-function-html-table.xml
+ docs/id/designers/language-custom-functions/language-function-mailto.xml
+ docs/id/designers/language-custom-functions/language-function-math.xml
+ docs/id/designers/language-custom-functions/language-function-popup-init.xml
+ docs/id/designers/language-custom-functions/language-function-popup.xml
+ docs/id/designers/language-custom-functions/language-function-textformat.xml
+ docs/id/designers/language-modifiers/language-modifier-capitalize.xml
+ docs/id/designers/language-modifiers/language-modifier-cat.xml
+ docs/id/designers/language-modifiers/language-modifier-count-characters.xml
+ docs/id/designers/language-modifiers/language-modifier-count-paragraphs.xml
+ docs/id/designers/language-modifiers/language-modifier-count-sentences.xml
+ docs/id/designers/language-modifiers/language-modifier-count-words.xml
+ docs/id/designers/language-modifiers/language-modifier-date-format.xml
+ docs/id/designers/language-modifiers/language-modifier-default.xml
+ docs/id/designers/language-modifiers/language-modifier-escape.xml
+ docs/id/designers/language-modifiers/language-modifier-indent.xml
+ docs/id/designers/language-modifiers/language-modifier-lower.xml
+ docs/id/designers/language-modifiers/language-modifier-nl2br.xml
+ docs/id/designers/language-modifiers/language-modifier-regex-replace.xml
+ docs/id/designers/language-modifiers/language-modifier-replace.xml
+ docs/id/designers/language-modifiers/language-modifier-spacify.xml
+ docs/id/designers/language-modifiers/language-modifier-string-format.xml
+ docs/id/designers/language-modifiers/language-modifier-strip-tags.xml
+ docs/id/designers/language-modifiers/language-modifier-strip.xml
+ docs/id/designers/language-modifiers/language-modifier-truncate.xml
+ docs/id/designers/language-modifiers/language-modifier-upper.xml
+ docs/id/designers/language-modifiers/language-modifier-wordwrap.xml
+ docs/id/designers/language-variables/language-assigned-variables.xml
+ docs/id/designers/language-variables/language-config-variables.xml
+ docs/id/designers/language-variables/language-variables-smarty.xml
+ docs/id/programmers/advanced-features/advanced-features-objects.xml
+ docs/id/programmers/advanced-features/advanced-features-outputfilters.xml
+ docs/id/programmers/advanced-features/advanced-features-postfilters.xml
+ docs/id/programmers/advanced-features/advanced-features-prefilters.xml
+ docs/id/programmers/advanced-features/section-template-cache-handler-func.xml
+ docs/id/programmers/advanced-features/template-resources.xml
+ docs/id/programmers/api-functions/api-append-by-ref.xml
+ docs/id/programmers/api-functions/api-append.xml
+ docs/id/programmers/api-functions/api-assign-by-ref.xml
+ docs/id/programmers/api-functions/api-assign.xml
+ docs/id/programmers/api-functions/api-clear-all-assign.xml
+ docs/id/programmers/api-functions/api-clear-all-cache.xml
+ docs/id/programmers/api-functions/api-clear-assign.xml
+ docs/id/programmers/api-functions/api-clear-cache.xml
+ docs/id/programmers/api-functions/api-clear-compiled-tpl.xml
+ docs/id/programmers/api-functions/api-clear-config.xml
+ docs/id/programmers/api-functions/api-config-load.xml
+ docs/id/programmers/api-functions/api-display.xml
+ docs/id/programmers/api-functions/api-fetch.xml
+ docs/id/programmers/api-functions/api-get-config-vars.xml
+ docs/id/programmers/api-functions/api-get-registered-object.xml
+ docs/id/programmers/api-functions/api-get-template-vars.xml
+ docs/id/programmers/api-functions/api-is-cached.xml
+ docs/id/programmers/api-functions/api-load-filter.xml
+ docs/id/programmers/api-functions/api-register-block.xml
+ docs/id/programmers/api-functions/api-register-compiler-function.xml
+ docs/id/programmers/api-functions/api-register-function.xml
+ docs/id/programmers/api-functions/api-register-modifier.xml
+ docs/id/programmers/api-functions/api-register-object.xml
+ docs/id/programmers/api-functions/api-register-outputfilter.xml
+ docs/id/programmers/api-functions/api-register-postfilter.xml
+ docs/id/programmers/api-functions/api-register-prefilter.xml
+ docs/id/programmers/api-functions/api-register-resource.xml
+ docs/id/programmers/api-functions/api-template-exists.xml
+ docs/id/programmers/api-functions/api-trigger-error.xml
+ docs/id/programmers/api-functions/api-unregister-block.xml
+ docs/id/programmers/api-functions/api-unregister-compiler-function.xml
+ docs/id/programmers/api-functions/api-unregister-function.xml
+ docs/id/programmers/api-functions/api-unregister-modifier.xml
+ docs/id/programmers/api-functions/api-unregister-object.xml
+ docs/id/programmers/api-functions/api-unregister-outputfilter.xml
+ docs/id/programmers/api-functions/api-unregister-postfilter.xml
+ docs/id/programmers/api-functions/api-unregister-prefilter.xml
+ docs/id/programmers/api-functions/api-unregister-resource.xml
+ docs/id/programmers/api-variables/variable-autoload-filters.xml
+ docs/id/programmers/api-variables/variable-cache-dir.xml
+ docs/id/programmers/api-variables/variable-cache-handler-func.xml
+ docs/id/programmers/api-variables/variable-cache-lifetime.xml
+ docs/id/programmers/api-variables/variable-cache-modified-check.xml
+ docs/id/programmers/api-variables/variable-caching.xml
+ docs/id/programmers/api-variables/variable-compile-check.xml
+ docs/id/programmers/api-variables/variable-compile-dir.xml
+ docs/id/programmers/api-variables/variable-compile-id.xml
+ docs/id/programmers/api-variables/variable-compiler-class.xml
+ docs/id/programmers/api-variables/variable-config-booleanize.xml
+ docs/id/programmers/api-variables/variable-config-dir.xml
+ docs/id/programmers/api-variables/variable-config-fix-newlines.xml
+ docs/id/programmers/api-variables/variable-config-overwrite.xml
+ docs/id/programmers/api-variables/variable-config-read-hidden.xml
+ docs/id/programmers/api-variables/variable-debug-tpl.xml
+ docs/id/programmers/api-variables/variable-debugging-ctrl.xml
+ docs/id/programmers/api-variables/variable-debugging.xml
+ docs/id/programmers/api-variables/variable-default-modifiers.xml
+ docs/id/programmers/api-variables/variable-default-resource-type.xml
+ docs/id/programmers/api-variables/variable-default-template-handler-func.xml
+ docs/id/programmers/api-variables/variable-error-reporting.xml
+ docs/id/programmers/api-variables/variable-force-compile.xml
+ docs/id/programmers/api-variables/variable-left-delimiter.xml
+ docs/id/programmers/api-variables/variable-php-handling.xml
+ docs/id/programmers/api-variables/variable-plugins-dir.xml
+ docs/id/programmers/api-variables/variable-request-use-auto-globals.xml
+ docs/id/programmers/api-variables/variable-request-vars-order.xml
+ docs/id/programmers/api-variables/variable-right-delimiter.xml
+ docs/id/programmers/api-variables/variable-secure-dir.xml
+ docs/id/programmers/api-variables/variable-security-settings.xml
+ docs/id/programmers/api-variables/variable-security.xml
+ docs/id/programmers/api-variables/variable-template-dir.xml
+ docs/id/programmers/api-variables/variable-trusted-dir.xml
+ docs/id/programmers/api-variables/variable-use-sub-dirs.xml
+ docs/id/programmers/caching/caching-cacheable.xml
+ docs/id/programmers/caching/caching-groups.xml
+ docs/id/programmers/caching/caching-multiple-caches.xml
+ docs/id/programmers/caching/caching-setting-up.xml
+ docs/id/programmers/plugins/plugins-block-functions.xml
+ docs/id/programmers/plugins/plugins-compiler-functions.xml
+ docs/id/programmers/plugins/plugins-functions.xml
+ docs/id/programmers/plugins/plugins-howto.xml
+ docs/id/programmers/plugins/plugins-inserts.xml
+ docs/id/programmers/plugins/plugins-modifiers.xml
+ docs/id/programmers/plugins/plugins-naming-conventions.xml
+ docs/id/programmers/plugins/plugins-outputfilters.xml
+ docs/id/programmers/plugins/plugins-prefilters-postfilters.xml
+ docs/id/programmers/plugins/plugins-resources.xml
+ docs/id/programmers/plugins/plugins-writing.xml:
+ Typos correction and all translated now.
+
+2007-09-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/id/bookinfo.xml
+ docs/id/getting-started.xml
+ docs/id/language-defs.ent
+ docs/id/language-snippets.ent
+ docs/id/livedocs.ent
+ docs/id/preface.xml:
+ added indonesian docs - thanks Zaenal Mutaqin
+
+ * docs/scripts/generate_web.php:
+ raise pcre.backtrack_limit - thanks to takagi
+
+2007-09-16 Monte Ohrt <monte@ohrt.com>
+
+ * libs/Smarty_Compiler.class.php:
+ fix typo
+
+2007-08-22 George Miroshnikov <support@infinity.com.ua>
+
+ * docs/ru/getting-started.xml
+ docs/ru/getting-started.xml:
+ Sync with EN.
+
+2007-08-01 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ add append feature to capture
+
+2007-06-24 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
+
+ * docs/ja/getting-started.xml:
+ sync with en.
+
+2007-06-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/Makefile.in:
+ reverted accidently modified file
+
+ * docs/Makefile.in
+ docs/de/getting-started.xml:
+ sync with en
+
+ * docs/en/getting-started.xml:
+ fixed link to ini_set(). thanks to Lee Yunyoung.
+
+2007-06-18 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
+
+ * docs/ja/language-snippets.ent
+ docs/ja/programmers/api-functions/api-register-outputfilter.xml
+ docs/ja/programmers/api-functions/api-register-postfilter.xml
+ docs/ja/programmers/api-functions/api-register-prefilter.xml:
+ sync with en.
+
+2007-06-18 Danilo Buerger <danilo@blizzz.org>
+
+ * docs/en/language-snippets.ent
+ docs/en/programmers/api-functions/api-register-outputfilter.xml
+ docs/en/programmers/api-functions/api-register-postfilter.xml
+ docs/en/programmers/api-functions/api-register-prefilter.xml:
+ Updated docs according to the changes from the previous commit
+
+ * NEWS
+ libs/Smarty.class.php:
+ Added the ability to (un)register multiple filters of the same type with
+ the same method name but different class name. Before it was not possible
+ due to the fact that only the method name was used to distinguish between
+ different filters of the same type. This does however not allow (same as
+ before) to register multiple filters of the same type with the same method
+ and class name (i.e. different instances of the same class).
+
+2007-05-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/compiler.assign.php:
+ fixed typo
+
+2007-05-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed calling registered objects' methods with an empty argument list.
+ thanks marcello
+
+2007-05-03 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
+
+ * docs/ja/designers/language-variables.xml
+ docs/ja/designers/language-builtin-functions/language-function-config-load.xml
+ docs/ja/designers/language-builtin-functions/language-function-foreach.xml
+ docs/ja/designers/language-builtin-functions/language-function-if.xml
+ docs/ja/designers/language-modifiers/language-modifier-cat.xml
+ docs/ja/designers/language-modifiers/language-modifier-wordwrap.xml
+ docs/ja/designers/language-variables/language-variables-smarty.xml:
+ sync with en.
+
+2007-05-03 Monte Ohrt <monte@ohrt.com>
+
+ * docs/en/designers/language-variables.xml
+ docs/en/designers/language-builtin-functions/language-function-config-load.xml
+ docs/en/designers/language-builtin-functions/language-function-foreach.xml
+ docs/en/designers/language-builtin-functions/language-function-if.xml
+ docs/en/designers/language-modifiers/language-modifier-cat.xml
+ docs/en/designers/language-modifiers/language-modifier-wordwrap.xml
+ docs/en/designers/language-variables/language-variables-smarty.xml:
+ update documentation corrections from marcello in the forums. Thanks
+ marcello!
+
+2007-04-22 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
+
+ * docs/ja/programmers/advanced-features.xml
+ docs/ja/programmers/api-functions.xml
+ docs/ja/programmers/api-variables.xml:
+ corrected the garbled text.
+
+2007-04-21 TAKAGI Masahiro <matakagi@osk2.3web.ne.jp>
+
+ * docs/ja/bookinfo.xml
+ docs/ja/getting-started.xml
+ docs/ja/language-defs.ent
+ docs/ja/language-snippets.ent
+ docs/ja/livedocs.ent
+ docs/ja/make_chm_index.html
+ docs/ja/preface.xml
+ docs/ja/translation.xml
+ docs/ja/appendixes/bugs.xml
+ docs/ja/appendixes/resources.xml
+ docs/ja/appendixes/tips.xml
+ docs/ja/appendixes/troubleshooting.xml
+ docs/ja/designers/chapter-debugging-console.xml
+ docs/ja/designers/config-files.xml
+ docs/ja/designers/language-basic-syntax.xml
+ docs/ja/designers/language-builtin-functions.xml
+ docs/ja/designers/language-combining-modifiers.xml
+ docs/ja/designers/language-custom-functions.xml
+ docs/ja/designers/language-modifiers.xml
+ docs/ja/designers/language-variables.xml
+ docs/ja/designers/language-basic-syntax/language-escaping.xml
+ docs/ja/designers/language-basic-syntax/language-math.xml
+ docs/ja/designers/language-basic-syntax/language-syntax-attributes.xml
+ docs/ja/designers/language-basic-syntax/language-syntax-comments.xml
+ docs/ja/designers/language-basic-syntax/language-syntax-functions.xml
+ docs/ja/designers/language-basic-syntax/language-syntax-quotes.xml
+ docs/ja/designers/language-basic-syntax/language-syntax-variables.xml
+ docs/ja/designers/language-builtin-functions/language-function-capture.xml
+ docs/ja/designers/language-builtin-functions/language-function-config-load.xml
+ docs/ja/designers/language-builtin-functions/language-function-foreach.xml
+ docs/ja/designers/language-builtin-functions/language-function-if.xml
+ docs/ja/designers/language-builtin-functions/language-function-include-php.xml
+ docs/ja/designers/language-builtin-functions/language-function-include.xml
+ docs/ja/designers/language-builtin-functions/language-function-insert.xml
+ docs/ja/designers/language-builtin-functions/language-function-ldelim.xml
+ docs/ja/designers/language-builtin-functions/language-function-literal.xml
+ docs/ja/designers/language-builtin-functions/language-function-php.xml
+ docs/ja/designers/language-builtin-functions/language-function-section.xml
+ docs/ja/designers/language-builtin-functions/language-function-strip.xml
+ docs/ja/designers/language-custom-functions/language-function-assign.xml
+ docs/ja/designers/language-custom-functions/language-function-counter.xml
+ docs/ja/designers/language-custom-functions/language-function-cycle.xml
+ docs/ja/designers/language-custom-functions/language-function-debug.xml
+ docs/ja/designers/language-custom-functions/language-function-eval.xml
+ docs/ja/designers/language-custom-functions/language-function-fetch.xml
+ docs/ja/designers/language-custom-functions/language-function-html-checkboxes.xml
+ docs/ja/designers/language-custom-functions/language-function-html-image.xml
+ docs/ja/designers/language-custom-functions/language-function-html-options.xml
+ docs/ja/designers/language-custom-functions/language-function-html-radios.xml
+ docs/ja/designers/language-custom-functions/language-function-html-select-date.xml
+ docs/ja/designers/language-custom-functions/language-function-html-select-time.xml
+ docs/ja/designers/language-custom-functions/language-function-html-table.xml
+ docs/ja/designers/language-custom-functions/language-function-mailto.xml
+ docs/ja/designers/language-custom-functions/language-function-math.xml
+ docs/ja/designers/language-custom-functions/language-function-popup-init.xml
+ docs/ja/designers/language-custom-functions/language-function-popup.xml
+ docs/ja/designers/language-custom-functions/language-function-textformat.xml
+ docs/ja/designers/language-modifiers/language-modifier-capitalize.xml
+ docs/ja/designers/language-modifiers/language-modifier-cat.xml
+ docs/ja/designers/language-modifiers/language-modifier-count-characters.xml
+ docs/ja/designers/language-modifiers/language-modifier-count-paragraphs.xml
+ docs/ja/designers/language-modifiers/language-modifier-count-sentences.xml
+ docs/ja/designers/language-modifiers/language-modifier-count-words.xml
+ docs/ja/designers/language-modifiers/language-modifier-date-format.xml
+ docs/ja/designers/language-modifiers/language-modifier-default.xml
+ docs/ja/designers/language-modifiers/language-modifier-escape.xml
+ docs/ja/designers/language-modifiers/language-modifier-indent.xml
+ docs/ja/designers/language-modifiers/language-modifier-lower.xml
+ docs/ja/designers/language-modifiers/language-modifier-nl2br.xml
+ docs/ja/designers/language-modifiers/language-modifier-regex-replace.xml
+ docs/ja/designers/language-modifiers/language-modifier-replace.xml
+ docs/ja/designers/language-modifiers/language-modifier-spacify.xml
+ docs/ja/designers/language-modifiers/language-modifier-string-format.xml
+ docs/ja/designers/language-modifiers/language-modifier-strip-tags.xml
+ docs/ja/designers/language-modifiers/language-modifier-strip.xml
+ docs/ja/designers/language-modifiers/language-modifier-truncate.xml
+ docs/ja/designers/language-modifiers/language-modifier-upper.xml
+ docs/ja/designers/language-modifiers/language-modifier-wordwrap.xml
+ docs/ja/designers/language-variables/language-assigned-variables.xml
+ docs/ja/designers/language-variables/language-config-variables.xml
+ docs/ja/designers/language-variables/language-variables-smarty.xml
+ docs/ja/programmers/advanced-features.xml
+ docs/ja/programmers/api-functions.xml
+ docs/ja/programmers/api-variables.xml
+ docs/ja/programmers/caching.xml
+ docs/ja/programmers/plugins.xml
+ docs/ja/programmers/smarty-constants.xml
+ docs/ja/programmers/advanced-features/advanced-features-objects.xml
+ docs/ja/programmers/advanced-features/advanced-features-outputfilters.xml
+ docs/ja/programmers/advanced-features/advanced-features-postfilters.xml
+ docs/ja/programmers/advanced-features/advanced-features-prefilters.xml
+ docs/ja/programmers/advanced-features/section-template-cache-handler-func.xml
+ docs/ja/programmers/advanced-features/template-resources.xml
+ docs/ja/programmers/api-functions/api-append-by-ref.xml
+ docs/ja/programmers/api-functions/api-append.xml
+ docs/ja/programmers/api-functions/api-assign-by-ref.xml
+ docs/ja/programmers/api-functions/api-assign.xml
+ docs/ja/programmers/api-functions/api-clear-all-assign.xml
+ docs/ja/programmers/api-functions/api-clear-all-cache.xml
+ docs/ja/programmers/api-functions/api-clear-assign.xml
+ docs/ja/programmers/api-functions/api-clear-cache.xml
+ docs/ja/programmers/api-functions/api-clear-compiled-tpl.xml
+ docs/ja/programmers/api-functions/api-clear-config.xml
+ docs/ja/programmers/api-functions/api-config-load.xml
+ docs/ja/programmers/api-functions/api-display.xml
+ docs/ja/programmers/api-functions/api-fetch.xml
+ docs/ja/programmers/api-functions/api-get-config-vars.xml
+ docs/ja/programmers/api-functions/api-get-registered-object.xml
+ docs/ja/programmers/api-functions/api-get-template-vars.xml
+ docs/ja/programmers/api-functions/api-is-cached.xml
+ docs/ja/programmers/api-functions/api-load-filter.xml
+ docs/ja/programmers/api-functions/api-register-block.xml
+ docs/ja/programmers/api-functions/api-register-compiler-function.xml
+ docs/ja/programmers/api-functions/api-register-function.xml
+ docs/ja/programmers/api-functions/api-register-modifier.xml
+ docs/ja/programmers/api-functions/api-register-object.xml
+ docs/ja/programmers/api-functions/api-register-outputfilter.xml
+ docs/ja/programmers/api-functions/api-register-postfilter.xml
+ docs/ja/programmers/api-functions/api-register-prefilter.xml
+ docs/ja/programmers/api-functions/api-register-resource.xml
+ docs/ja/programmers/api-functions/api-template-exists.xml
+ docs/ja/programmers/api-functions/api-trigger-error.xml
+ docs/ja/programmers/api-functions/api-unregister-block.xml
+ docs/ja/programmers/api-functions/api-unregister-compiler-function.xml
+ docs/ja/programmers/api-functions/api-unregister-function.xml
+ docs/ja/programmers/api-functions/api-unregister-modifier.xml
+ docs/ja/programmers/api-functions/api-unregister-object.xml
+ docs/ja/programmers/api-functions/api-unregister-outputfilter.xml
+ docs/ja/programmers/api-functions/api-unregister-postfilter.xml
+ docs/ja/programmers/api-functions/api-unregister-prefilter.xml
+ docs/ja/programmers/api-functions/api-unregister-resource.xml
+ docs/ja/programmers/api-variables/variable-autoload-filters.xml
+ docs/ja/programmers/api-variables/variable-cache-dir.xml
+ docs/ja/programmers/api-variables/variable-cache-handler-func.xml
+ docs/ja/programmers/api-variables/variable-cache-lifetime.xml
+ docs/ja/programmers/api-variables/variable-cache-modified-check.xml
+ docs/ja/programmers/api-variables/variable-caching.xml
+ docs/ja/programmers/api-variables/variable-compile-check.xml
+ docs/ja/programmers/api-variables/variable-compile-dir.xml
+ docs/ja/programmers/api-variables/variable-compile-id.xml
+ docs/ja/programmers/api-variables/variable-compiler-class.xml
+ docs/ja/programmers/api-variables/variable-config-booleanize.xml
+ docs/ja/programmers/api-variables/variable-config-dir.xml
+ docs/ja/programmers/api-variables/variable-config-fix-newlines.xml
+ docs/ja/programmers/api-variables/variable-config-overwrite.xml
+ docs/ja/programmers/api-variables/variable-config-read-hidden.xml
+ docs/ja/programmers/api-variables/variable-debug-tpl.xml
+ docs/ja/programmers/api-variables/variable-debugging-ctrl.xml
+ docs/ja/programmers/api-variables/variable-debugging.xml
+ docs/ja/programmers/api-variables/variable-default-modifiers.xml
+ docs/ja/programmers/api-variables/variable-default-resource-type.xml
+ docs/ja/programmers/api-variables/variable-default-template-handler-func.xml
+ docs/ja/programmers/api-variables/variable-error-reporting.xml
+ docs/ja/programmers/api-variables/variable-force-compile.xml
+ docs/ja/programmers/api-variables/variable-left-delimiter.xml
+ docs/ja/programmers/api-variables/variable-php-handling.xml
+ docs/ja/programmers/api-variables/variable-plugins-dir.xml
+ docs/ja/programmers/api-variables/variable-request-use-auto-globals.xml
+ docs/ja/programmers/api-variables/variable-request-vars-order.xml
+ docs/ja/programmers/api-variables/variable-right-delimiter.xml
+ docs/ja/programmers/api-variables/variable-secure-dir.xml
+ docs/ja/programmers/api-variables/variable-security-settings.xml
+ docs/ja/programmers/api-variables/variable-security.xml
+ docs/ja/programmers/api-variables/variable-template-dir.xml
+ docs/ja/programmers/api-variables/variable-trusted-dir.xml
+ docs/ja/programmers/api-variables/variable-use-sub-dirs.xml
+ docs/ja/programmers/caching/caching-cacheable.xml
+ docs/ja/programmers/caching/caching-groups.xml
+ docs/ja/programmers/caching/caching-multiple-caches.xml
+ docs/ja/programmers/caching/caching-setting-up.xml
+ docs/ja/programmers/plugins/plugins-block-functions.xml
+ docs/ja/programmers/plugins/plugins-compiler-functions.xml
+ docs/ja/programmers/plugins/plugins-functions.xml
+ docs/ja/programmers/plugins/plugins-howto.xml
+ docs/ja/programmers/plugins/plugins-inserts.xml
+ docs/ja/programmers/plugins/plugins-modifiers.xml
+ docs/ja/programmers/plugins/plugins-naming-conventions.xml
+ docs/ja/programmers/plugins/plugins-outputfilters.xml
+ docs/ja/programmers/plugins/plugins-prefilters-postfilters.xml
+ docs/ja/programmers/plugins/plugins-resources.xml
+ docs/ja/programmers/plugins/plugins-writing.xml:
+ added Japanese translation files.
+
+ * docs/Makefile.in
+ docs/configure.in:
+ added the configuration for Japanese translation.
+
+2007-04-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/en/programmers/smarty-constants.xml:
+ fixed typo
+
+2007-04-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/ru/getting-started.xml:
+ fixed uri for Zend Accelerator
+
+2007-04-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/de/getting-started.xml
+ docs/es/getting-started.xml
+ docs/it/getting-started.xml
+ docs/pt_BR/getting-started.xml:
+ fixed uris for php-accelerator
+
+2007-03-08 Monte Ohrt <monte@ohrt.com>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers
+
+2007-03-07 Monte Ohrt <monte@ohrt.com>
+
+ * (Smarty_2_6_18)
+ NEWS:
+ update NEWS file with patch
+
+ * (Smarty_2_6_18)
+ docs/en/designers/language-builtin-functions/language-function-section.xml:
+ note the fact that section loop will accept an integer
+
+2007-03-06 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ fix html_select_date separator when parts are missing (thanks to kayk for
+ the patch)
+
+2007-03-06 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ bumped version number
+
+ * NEWS:
+ added release headline
+
+ * libs/internals/core.write_compiled_include.php:
+ fixed detection of non-cached block when writing compiled includes
+
+2007-03-01 Danilo Buerger <danilo@blizzz.org>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ Applied boots clean up patch and removed commented out code.
+ Updated NEWS file
+
+2007-02-27 Danilo Buerger <danilo@blizzz.org>
+
+ * NEWS
+ docs/en/designers/language-modifiers/language-modifier-date-format.xml
+ libs/internals/core.write_file.php
+ libs/plugins/modifier.date_format.php:
+ Updated smarty_core_write_file() and smarty_modifier_date_format() to speed
+ up Windows detection.
+ Emulated more parameters for Windows in smarty_modifier_date_format() and
+ fixed some old ones.
+ Updated the docs to tell what parameters are emulated on Windows.
+ Updated NEWS file.
+
+ * NEWS:
+ Updated NEWS file to reflect changes commited in the last revision
+
+2007-02-27 Monte Ohrt <monte@ohrt.com>
+
+ * docs/en/appendixes/troubleshooting.xml:
+ fix typo
+
+2007-02-27 Danilo Buerger <danilo@blizzz.org>
+
+ * libs/Smarty_Compiler.class.php:
+ Modified _(push|pop)_cacheable_state() to embedd alternate syntax. See this
+ bug report: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=10502
+
+2007-02-26 Peter 'Mash' Morgan <pm@daffodil.uk.com>
+
+ * docs/en/designers/language-custom-functions/language-function-html-options.xml:
+ Fix incorrect var name
+
+2007-02-23 Monte Ohrt <monte@ohrt.com>
+
+ * libs/Smarty_Compiler.class.php:
+ escape creating of language=php from interleaving
+
+ * libs/Smarty_Compiler.class.php:
+ add removed line back in
+
+ * libs/Smarty_Compiler.class.php:
+ fix up last patch, remove unnecessary lines
+
+ * libs/Smarty_Compiler.class.php:
+ fix situation when no compiled tags are present
+
+ * libs/Smarty_Compiler.class.php:
+ fix problem with php open tags generated from tag interleaving
+
+2007-02-06 boots <jayboots@yahoo.com>
+
+ * docs/en/programmers/advanced-features/template-resources.xml:
+ Correct default template handler function example.
+
+2007-01-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/modifier.truncate.php:
+ fixed handling of $etc in the truncate modifier when $etc is longer
+ than $length.
+
+ thanks to Sylvinus!
+
+2007-01-10 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/plugins/modifier.date_format.php
+ libs/plugins/modifier.date_format.php:
+ fix handling of %I with mysql timestamps
+
+ Thanks to Danilo Buerger
+
+ * NEWS
+ libs/internals/core.write_file.php:
+ Better recognize Windows filesystems to reduce warnings
+
+ * NEWS
+ libs/plugins/modifier.date_format.php:
+ Emulate %R in the date_format modifier on Windows
+
+ Thanks to Danilo Buerger
+
+2006-12-10 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/getting-started.xml:
+ fix build
+
+ * docs/fr/language-snippets.ent
+ docs/fr/designers/language-builtin-functions/language-function-include-php.xml
+ docs/fr/designers/language-modifiers/language-modifier-truncate.xml
+ docs/fr/designers/language-variables/language-variables-smarty.xml:
+ sync with EN
+
+2006-12-02 Peter 'Mash' Morgan <pm@daffodil.uk.com>
+
+ * docs/en/designers/language-builtin-functions/language-function-include-php.xml:
+ Tidy example, speeling andd add links
+
+ * docs/en/getting-started.xml:
+ Add/correct entities
+
+ * docs/entities/global.ent:
+ Fix entities (strange)
+
+2006-12-01 Monte Ohrt <monte@ohrt.com>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update dev version numbers
+
+2006-12-01 boots <jayboots@yahoo.com>
+
+ * (Smarty_2_6_16)
+ NEWS:
+ Fixed replacement bug introduced in trimwhitespaces output filter that
+ was introduced in the last release.
+
+ Thanks to Spuerhund from the forums.
+
+ * (Smarty_2_6_16)
+ libs/plugins/outputfilter.trimwhitespace.php:
+ Fixed replacement bug introduced by last changes.
+
+ Thanks to Spuerhund from the forums.
+
+2006-11-30 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ docs/en/designers/language-modifiers/language-modifier-truncate.xml
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update dev version numbers, fix manual typo
+
+2006-11-22 George Miroshnikov <support@infinity.com.ua>
+
+ * docs/ru/getting-started.xml
+ docs/ru/language-snippets.ent:
+ sync with EN
+
+ * docs/en/getting-started.xml:
+ replaced hardcoded path separator with PATH_SEPARATOR constant
+
+2006-11-20 boots <jayboots@yahoo.com>
+
+ * libs/plugins/modifier.debug_print_var.php:
+ fix depth formatting of arrays and objects in modifier debug_print_var
+
+2006-11-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/en/designers/language-variables/language-variables-smarty.xml:
+ fixed typo. thanks jonez.
+
+2006-11-08 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/internals/core.write_file.php:
+ change file writing semantics in smarty_core_write_file()
+
+ This avoids unlink() unless rename() fails or a Windows system is detected
+
+ see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=6956
+
+ Thanks to c960657 from the forums.
+
+2006-11-07 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/debug.tpl:
+ update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug
+ output and apply a Smarty based color scheme
+
+ see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=7178
+
+ thanks to cybot from the forums!
+
+ * NEWS
+ libs/plugins/modifier.debug_print_var.php:
+ enhance reporting precision of debug_print_var modifier
+
+ see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=9281
+
+ thanks to cybot from the forums
+
+2006-11-01 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ make html_select_date work consistently with 0000-00-00 00:00:00 and
+ 0000-00-00 inputs
+
+ Thanks to cybot from forums
+
+2006-10-16 George Miroshnikov <support@infinity.com.ua>
+
+ * docs/en/language-snippets.ent:
+ minor typo fix - &$class doesn't make sense.
+
+2006-10-14 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/designers/language-basic-syntax.xml
+ docs/fr/designers/language-builtin-functions.xml
+ docs/fr/designers/language-basic-syntax/language-syntax-attributes.xml
+ docs/fr/designers/language-basic-syntax/language-syntax-comments.xml
+ docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml
+ docs/fr/designers/language-builtin-functions/language-function-capture.xml
+ docs/fr/designers/language-builtin-functions/language-function-php.xml
+ docs/fr/designers/language-builtin-functions/language-function-section.xml
+ docs/fr/designers/language-custom-functions/language-function-popup-init.xml
+ docs/fr/designers/language-modifiers/language-modifier-escape.xml
+ docs/fr/programmers/api-functions/api-display.xml
+ docs/fr/programmers/plugins/plugins-inserts.xml:
+ sync with EN
+
+2006-10-14 Fernando Correa da Conceição <fernando_conceicao@yahoo.com.br>
+
+ * docs/pt_BR/programmers/api-variables/variable-error-reporting.xml:
+ New Translation
+
+ * docs/pt_BR/designers/language-basic-syntax/language-escaping.xml
+ docs/pt_BR/designers/language-basic-syntax/language-syntax-variables.xml:
+ New Translations
+
+ * docs/pt_BR/translation.xml:
+ Used in revcheck
+
+ * docs/pt_BR/getting-started.xml
+ docs/pt_BR/language-snippets.ent
+ docs/pt_BR/make_chm_index.html
+ docs/pt_BR/preface.xml
+ docs/pt_BR/appendixes/resources.xml
+ docs/pt_BR/appendixes/troubleshooting.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-capitalize.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-cat.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-count-characters.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-count-paragraphs.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-count-sentences.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-count-words.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-date-format.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-default.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-escape.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-indent.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-lower.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-nl2br.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-regex-replace.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-replace.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-spacify.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-string-format.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-strip-tags.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-strip.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-truncate.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-upper.xml
+ docs/pt_BR/designers/language-modifiers/language-modifier-wordwrap.xml
+ docs/pt_BR/designers/language-variables/language-assigned-variables.xml
+ docs/pt_BR/designers/language-variables/language-config-variables.xml
+ docs/pt_BR/designers/language-variables/language-variables-smarty.xml
+ docs/pt_BR/programmers/advanced-features.xml
+ docs/pt_BR/programmers/api-functions.xml
+ docs/pt_BR/programmers/api-variables.xml
+ docs/pt_BR/programmers/caching.xml
+ docs/pt_BR/programmers/plugins.xml
+ docs/pt_BR/programmers/smarty-constants.xml
+ docs/pt_BR/programmers/advanced-features/advanced-features-objects.xml
+ docs/pt_BR/programmers/advanced-features/advanced-features-outputfilters.xml
+ docs/pt_BR/programmers/advanced-features/advanced-features-postfilters.xml
+ docs/pt_BR/programmers/advanced-features/advanced-features-prefilters.xml
+ docs/pt_BR/programmers/advanced-features/section-template-cache-handler-func.xml
+ docs/pt_BR/programmers/advanced-features/template-resources.xml
+ docs/pt_BR/programmers/api-functions/api-append-by-ref.xml
+ docs/pt_BR/programmers/api-functions/api-append.xml
+ docs/pt_BR/programmers/api-functions/api-assign-by-ref.xml
+ docs/pt_BR/programmers/api-functions/api-assign.xml
+ docs/pt_BR/programmers/api-functions/api-clear-all-assign.xml
+ docs/pt_BR/programmers/api-functions/api-clear-all-cache.xml
+ docs/pt_BR/programmers/api-functions/api-clear-assign.xml
+ docs/pt_BR/programmers/api-functions/api-clear-cache.xml
+ docs/pt_BR/programmers/api-functions/api-clear-compiled-tpl.xml
+ docs/pt_BR/programmers/api-functions/api-clear-config.xml
+ docs/pt_BR/programmers/api-functions/api-config-load.xml
+ docs/pt_BR/programmers/api-functions/api-display.xml
+ docs/pt_BR/programmers/api-functions/api-fetch.xml
+ docs/pt_BR/programmers/api-functions/api-get-config-vars.xml
+ docs/pt_BR/programmers/api-functions/api-get-registered-object.xml
+ docs/pt_BR/programmers/api-functions/api-get-template-vars.xml
+ docs/pt_BR/programmers/api-functions/api-is-cached.xml
+ docs/pt_BR/programmers/api-functions/api-load-filter.xml
+ docs/pt_BR/programmers/api-functions/api-register-block.xml
+ docs/pt_BR/programmers/api-functions/api-register-compiler-function.xml
+ docs/pt_BR/programmers/api-functions/api-register-function.xml
+ docs/pt_BR/programmers/api-functions/api-register-modifier.xml
+ docs/pt_BR/programmers/api-functions/api-register-object.xml
+ docs/pt_BR/programmers/api-functions/api-register-outputfilter.xml
+ docs/pt_BR/programmers/api-functions/api-register-postfilter.xml
+ docs/pt_BR/programmers/api-functions/api-register-prefilter.xml
+ docs/pt_BR/programmers/api-functions/api-register-resource.xml
+ docs/pt_BR/programmers/api-functions/api-template-exists.xml
+ docs/pt_BR/programmers/api-functions/api-trigger-error.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-block.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-compiler-function.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-function.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-modifier.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-object.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-outputfilter.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-postfilter.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-prefilter.xml
+ docs/pt_BR/programmers/api-functions/api-unregister-resource.xml
+ docs/pt_BR/programmers/api-variables/variable-autoload-filters.xml
+ docs/pt_BR/programmers/api-variables/variable-cache-dir.xml
+ docs/pt_BR/programmers/api-variables/variable-cache-handler-func.xml
+ docs/pt_BR/programmers/api-variables/variable-cache-lifetime.xml
+ docs/pt_BR/programmers/api-variables/variable-cache-modified-check.xml
+ docs/pt_BR/programmers/api-variables/variable-caching.xml
+ docs/pt_BR/programmers/api-variables/variable-compile-check.xml
+ docs/pt_BR/programmers/api-variables/variable-compile-dir.xml
+ docs/pt_BR/programmers/api-variables/variable-compile-id.xml
+ docs/pt_BR/programmers/api-variables/variable-compiler-class.xml
+ docs/pt_BR/programmers/api-variables/variable-config-booleanize.xml
+ docs/pt_BR/programmers/api-variables/variable-config-dir.xml
+ docs/pt_BR/programmers/api-variables/variable-config-fix-newlines.xml
+ docs/pt_BR/programmers/api-variables/variable-config-overwrite.xml
+ docs/pt_BR/programmers/api-variables/variable-config-read-hidden.xml
+ docs/pt_BR/programmers/api-variables/variable-debug-tpl.xml
+ docs/pt_BR/programmers/api-variables/variable-debugging-ctrl.xml
+ docs/pt_BR/programmers/api-variables/variable-debugging.xml
+ docs/pt_BR/programmers/api-variables/variable-default-modifiers.xml
+ docs/pt_BR/programmers/api-variables/variable-default-resource-type.xml
+ docs/pt_BR/programmers/api-variables/variable-default-template-handler-func.xml
+ docs/pt_BR/programmers/api-variables/variable-force-compile.xml
+ docs/pt_BR/programmers/api-variables/variable-global-assign.xml
+ docs/pt_BR/programmers/api-variables/variable-left-delimiter.xml
+ docs/pt_BR/programmers/api-variables/variable-php-handling.xml
+ docs/pt_BR/programmers/api-variables/variable-plugins-dir.xml
+ docs/pt_BR/programmers/api-variables/variable-request-use-auto-globals.xml
+ docs/pt_BR/programmers/api-variables/variable-request-vars-order.xml
+ docs/pt_BR/programmers/api-variables/variable-right-delimiter.xml
+ docs/pt_BR/programmers/api-variables/variable-secure-dir.xml
+ docs/pt_BR/programmers/api-variables/variable-security-settings.xml
+ docs/pt_BR/programmers/api-variables/variable-security.xml
+ docs/pt_BR/programmers/api-variables/variable-template-dir.xml
+ docs/pt_BR/programmers/api-variables/variable-trusted-dir.xml
+ docs/pt_BR/programmers/api-variables/variable-undefined.xml
+ docs/pt_BR/programmers/api-variables/variable-use-sub-dirs.xml
+ docs/pt_BR/programmers/caching/caching-cacheable.xml
+ docs/pt_BR/programmers/caching/caching-groups.xml
+ docs/pt_BR/programmers/caching/caching-multiple-caches.xml
+ docs/pt_BR/programmers/caching/caching-setting-up.xml
+ docs/pt_BR/programmers/plugins/plugins-block-functions.xml
+ docs/pt_BR/programmers/plugins/plugins-compiler-functions.xml
+ docs/pt_BR/programmers/plugins/plugins-functions.xml
+ docs/pt_BR/programmers/plugins/plugins-howto.xml
+ docs/pt_BR/programmers/plugins/plugins-inserts.xml
+ docs/pt_BR/programmers/plugins/plugins-modifiers.xml
+ docs/pt_BR/programmers/plugins/plugins-naming-conventions.xml
+ docs/pt_BR/programmers/plugins/plugins-outputfilters.xml
+ docs/pt_BR/programmers/plugins/plugins-prefilters-postfilters.xml
+ docs/pt_BR/programmers/plugins/plugins-resources.xml
+ docs/pt_BR/programmers/plugins/plugins-writing.xml:
+ Big update. Revision tag for all files. Some updates. Now I can update it
+
+2006-10-09 Peter 'Mash' Morgan <pm@daffodil.uk.com>
+
+ * docs/en/getting-started.xml
+ docs/en/designers/language-basic-syntax.xml
+ docs/en/designers/language-custom-functions/language-function-popup-init.xml
+ docs/en/designers/language-modifiers/language-modifier-escape.xml
+ docs/en/programmers/api-functions/api-display.xml
+ docs/en/programmers/plugins/plugins-inserts.xml:
+ Minor changes and corrections
+
+ * docs/en/designers/language-basic-syntax.xml
+ docs/en/designers/language-builtin-functions.xml
+ docs/en/designers/language-basic-syntax/language-syntax-attributes.xml
+ docs/en/designers/language-basic-syntax/language-syntax-comments.xml
+ docs/en/designers/language-basic-syntax/language-syntax-quotes.xml
+ docs/en/designers/language-modifiers/language-modifier-escape.xml:
+ Minor formatting and error correction
+
+ * docs/en/designers/language-builtin-functions/language-function-capture.xml
+ docs/en/designers/language-builtin-functions/language-function-php.xml
+ docs/en/designers/language-builtin-functions/language-function-section.xml:
+ minor formatting and changes
+
+ * docs/en/getting-started.xml:
+ Tidied up formatting so more readable, tidied up the install to the paths
+ are more clear (ta jj)
+
+2006-10-09 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/designers/language-builtin-functions/language-function-section.xml:
+ sync with EN
+
+2006-10-08 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/designers/language-builtin-functions/language-function-php.xml
+ docs/fr/designers/language-modifiers/language-modifier-escape.xml
+ docs/fr/designers/language-variables/language-variables-smarty.xml
+ docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml:
+ fix build
+
+ * docs/fr/designers/language-builtin-functions/language-function-strip.xml
+ docs/fr/programmers/caching.xml
+ docs/fr/programmers/smarty-constants.xml
+ docs/fr/programmers/api-variables/variable-autoload-filters.xml
+ docs/fr/programmers/api-variables/variable-cache-dir.xml
+ docs/fr/programmers/api-variables/variable-cache-handler-func.xml
+ docs/fr/programmers/api-variables/variable-cache-lifetime.xml
+ docs/fr/programmers/api-variables/variable-cache-modified-check.xml
+ docs/fr/programmers/api-variables/variable-caching.xml
+ docs/fr/programmers/api-variables/variable-compile-check.xml
+ docs/fr/programmers/api-variables/variable-compile-dir.xml
+ docs/fr/programmers/api-variables/variable-compile-id.xml
+ docs/fr/programmers/api-variables/variable-compiler-class.xml
+ docs/fr/programmers/api-variables/variable-config-booleanize.xml
+ docs/fr/programmers/api-variables/variable-config-dir.xml
+ docs/fr/programmers/api-variables/variable-config-fix-newlines.xml
+ docs/fr/programmers/api-variables/variable-config-overwrite.xml
+ docs/fr/programmers/api-variables/variable-config-read-hidden.xml
+ docs/fr/programmers/api-variables/variable-debug-tpl.xml
+ docs/fr/programmers/api-variables/variable-debugging-ctrl.xml
+ docs/fr/programmers/api-variables/variable-debugging.xml
+ docs/fr/programmers/api-variables/variable-default-modifiers.xml
+ docs/fr/programmers/api-variables/variable-default-resource-type.xml
+ docs/fr/programmers/api-variables/variable-default-template-handler-func.xml
+ docs/fr/programmers/api-variables/variable-error-reporting.xml
+ docs/fr/programmers/api-variables/variable-force-compile.xml
+ docs/fr/programmers/api-variables/variable-left-delimiter.xml
+ docs/fr/programmers/api-variables/variable-php-handling.xml
+ docs/fr/programmers/api-variables/variable-plugins-dir.xml
+ docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml
+ docs/fr/programmers/api-variables/variable-request-vars-order.xml
+ docs/fr/programmers/api-variables/variable-right-delimiter.xml
+ docs/fr/programmers/api-variables/variable-secure-dir.xml
+ docs/fr/programmers/api-variables/variable-security-settings.xml
+ docs/fr/programmers/api-variables/variable-security.xml
+ docs/fr/programmers/api-variables/variable-template-dir.xml
+ docs/fr/programmers/api-variables/variable-trusted-dir.xml
+ docs/fr/programmers/api-variables/variable-use-sub-dirs.xml
+ docs/fr/programmers/caching/caching-cacheable.xml
+ docs/fr/programmers/caching/caching-groups.xml
+ docs/fr/programmers/caching/caching-multiple-caches.xml
+ docs/fr/programmers/caching/caching-setting-up.xml
+ docs/fr/programmers/plugins/plugins-block-functions.xml
+ docs/fr/programmers/plugins/plugins-compiler-functions.xml
+ docs/fr/programmers/plugins/plugins-functions.xml
+ docs/fr/programmers/plugins/plugins-inserts.xml
+ docs/fr/programmers/plugins/plugins-modifiers.xml
+ docs/fr/programmers/plugins/plugins-naming-conventions.xml
+ docs/fr/programmers/plugins/plugins-outputfilters.xml
+ docs/fr/programmers/plugins/plugins-prefilters-postfilters.xml
+ docs/fr/programmers/plugins/plugins-resources.xml
+ docs/fr/programmers/plugins/plugins-writing.xml:
+ sync with EN
+
+2006-10-07 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/programmers/advanced-features/advanced-features-objects.xml
+ docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml
+ docs/fr/programmers/advanced-features/advanced-features-postfilters.xml
+ docs/fr/programmers/advanced-features/advanced-features-prefilters.xml
+ docs/fr/programmers/advanced-features/section-template-cache-handler-func.xml
+ docs/fr/programmers/advanced-features/template-resources.xml
+ docs/fr/programmers/api-functions/api-append-by-ref.xml
+ docs/fr/programmers/api-functions/api-append.xml
+ docs/fr/programmers/api-functions/api-assign-by-ref.xml
+ docs/fr/programmers/api-functions/api-assign.xml
+ docs/fr/programmers/api-functions/api-clear-all-assign.xml
+ docs/fr/programmers/api-functions/api-clear-all-cache.xml
+ docs/fr/programmers/api-functions/api-clear-assign.xml
+ docs/fr/programmers/api-functions/api-clear-cache.xml
+ docs/fr/programmers/api-functions/api-clear-compiled-tpl.xml
+ docs/fr/programmers/api-functions/api-clear-config.xml
+ docs/fr/programmers/api-functions/api-config-load.xml
+ docs/fr/programmers/api-functions/api-display.xml
+ docs/fr/programmers/api-functions/api-fetch.xml
+ docs/fr/programmers/api-functions/api-get-config-vars.xml
+ docs/fr/programmers/api-functions/api-get-registered-object.xml
+ docs/fr/programmers/api-functions/api-get-template-vars.xml
+ docs/fr/programmers/api-functions/api-is-cached.xml
+ docs/fr/programmers/api-functions/api-load-filter.xml
+ docs/fr/programmers/api-functions/api-register-block.xml
+ docs/fr/programmers/api-functions/api-register-compiler-function.xml
+ docs/fr/programmers/api-functions/api-register-function.xml
+ docs/fr/programmers/api-functions/api-register-modifier.xml
+ docs/fr/programmers/api-functions/api-register-object.xml
+ docs/fr/programmers/api-functions/api-register-outputfilter.xml
+ docs/fr/programmers/api-functions/api-register-postfilter.xml
+ docs/fr/programmers/api-functions/api-register-prefilter.xml
+ docs/fr/programmers/api-functions/api-register-resource.xml
+ docs/fr/programmers/api-functions/api-template-exists.xml
+ docs/fr/programmers/api-functions/api-trigger-error.xml
+ docs/fr/programmers/api-functions/api-unregister-block.xml
+ docs/fr/programmers/api-functions/api-unregister-compiler-function.xml
+ docs/fr/programmers/api-functions/api-unregister-function.xml
+ docs/fr/programmers/api-functions/api-unregister-modifier.xml
+ docs/fr/programmers/api-functions/api-unregister-object.xml
+ docs/fr/programmers/api-functions/api-unregister-outputfilter.xml
+ docs/fr/programmers/api-functions/api-unregister-postfilter.xml
+ docs/fr/programmers/api-functions/api-unregister-prefilter.xml
+ docs/fr/programmers/api-functions/api-unregister-resource.xml:
+ sync with EN
+
+2006-10-03 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/designers/language-custom-functions/language-function-html-select-time.xml
+ docs/fr/designers/language-custom-functions/language-function-html-table.xml
+ docs/fr/designers/language-custom-functions/language-function-mailto.xml
+ docs/fr/designers/language-custom-functions/language-function-math.xml
+ docs/fr/designers/language-custom-functions/language-function-popup-init.xml
+ docs/fr/designers/language-custom-functions/language-function-popup.xml
+ docs/fr/designers/language-custom-functions/language-function-textformat.xml
+ docs/fr/designers/language-modifiers/language-modifier-capitalize.xml
+ docs/fr/designers/language-modifiers/language-modifier-cat.xml
+ docs/fr/designers/language-modifiers/language-modifier-count-characters.xml
+ docs/fr/designers/language-modifiers/language-modifier-count-paragraphs.xml
+ docs/fr/designers/language-modifiers/language-modifier-count-sentences.xml
+ docs/fr/designers/language-modifiers/language-modifier-count-words.xml
+ docs/fr/designers/language-modifiers/language-modifier-date-format.xml
+ docs/fr/designers/language-modifiers/language-modifier-default.xml
+ docs/fr/designers/language-modifiers/language-modifier-escape.xml
+ docs/fr/designers/language-modifiers/language-modifier-indent.xml
+ docs/fr/designers/language-modifiers/language-modifier-lower.xml
+ docs/fr/designers/language-modifiers/language-modifier-nl2br.xml
+ docs/fr/designers/language-modifiers/language-modifier-regex-replace.xml
+ docs/fr/designers/language-modifiers/language-modifier-replace.xml
+ docs/fr/designers/language-modifiers/language-modifier-spacify.xml
+ docs/fr/designers/language-modifiers/language-modifier-string-format.xml
+ docs/fr/designers/language-modifiers/language-modifier-strip-tags.xml
+ docs/fr/designers/language-modifiers/language-modifier-strip.xml
+ docs/fr/designers/language-modifiers/language-modifier-truncate.xml
+ docs/fr/designers/language-modifiers/language-modifier-upper.xml
+ docs/fr/designers/language-modifiers/language-modifier-wordwrap.xml
+ docs/fr/designers/language-variables/language-assigned-variables.xml
+ docs/fr/designers/language-variables/language-config-variables.xml
+ docs/fr/designers/language-variables/language-variables-smarty.xml:
+ sync with EN
+
+2006-10-01 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/designers/language-builtin-functions/language-function-include-php.xml
+ docs/fr/designers/language-builtin-functions/language-function-include.xml
+ docs/fr/designers/language-builtin-functions/language-function-insert.xml
+ docs/fr/designers/language-builtin-functions/language-function-ldelim.xml
+ docs/fr/designers/language-builtin-functions/language-function-literal.xml
+ docs/fr/designers/language-builtin-functions/language-function-php.xml
+ docs/fr/designers/language-custom-functions/language-function-assign.xml
+ docs/fr/designers/language-custom-functions/language-function-counter.xml
+ docs/fr/designers/language-custom-functions/language-function-cycle.xml
+ docs/fr/designers/language-custom-functions/language-function-debug.xml
+ docs/fr/designers/language-custom-functions/language-function-eval.xml
+ docs/fr/designers/language-custom-functions/language-function-fetch.xml
+ docs/fr/designers/language-custom-functions/language-function-html-checkboxes.xml
+ docs/fr/designers/language-custom-functions/language-function-html-image.xml
+ docs/fr/designers/language-custom-functions/language-function-html-options.xml
+ docs/fr/designers/language-custom-functions/language-function-html-radios.xml
+ docs/fr/designers/language-custom-functions/language-function-html-select-date.xml:
+ sync with EN
+
+2006-09-30 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/getting-started.xml:
+ fix build
+
+ * docs/fr/designers/chapter-debugging-console.xml
+ docs/fr/designers/config-files.xml
+ docs/fr/designers/language-builtin-functions.xml
+ docs/fr/designers/language-modifiers.xml
+ docs/fr/designers/language-variables.xml
+ docs/fr/designers/language-basic-syntax/language-escaping.xml
+ docs/fr/designers/language-basic-syntax/language-math.xml
+ docs/fr/designers/language-basic-syntax/language-syntax-comments.xml
+ docs/fr/designers/language-basic-syntax/language-syntax-functions.xml
+ docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml
+ docs/fr/designers/language-basic-syntax/language-syntax-variables.xml
+ docs/fr/designers/language-builtin-functions/language-function-capture.xml
+ docs/fr/designers/language-builtin-functions/language-function-config-load.xml
+ docs/fr/designers/language-builtin-functions/language-function-foreach.xml
+ docs/fr/designers/language-builtin-functions/language-function-if.xml:
+ sync with EN
+
+ * docs/fr/getting-started.xml
+ docs/fr/language-snippets.ent
+ docs/fr/appendixes/resources.xml
+ docs/fr/appendixes/tips.xml
+ docs/fr/appendixes/troubleshooting.xml:
+ sync with EN
+
+2006-09-27 Peter 'Mash' Morgan <pm@daffodil.uk.com>
+
+ * docs/en/designers/language-builtin-functions/language-function-section.xml:
+ Minor tweaks and corrections
+
+ * docs/en/getting-started.xml
+ docs/en/designers/chapter-debugging-console.xml
+ docs/en/designers/language-basic-syntax/language-syntax-comments.xml
+ docs/en/designers/language-custom-functions/language-function-html-image.xml
+ docs/en/designers/language-custom-functions/language-function-html-options.xml
+ docs/en/designers/language-custom-functions/language-function-html-radios.xml
+ docs/en/designers/language-custom-functions/language-function-html-select-date.xml
+ docs/en/designers/language-custom-functions/language-function-html-select-time.xml
+ docs/en/designers/language-custom-functions/language-function-html-table.xml
+ docs/en/designers/language-custom-functions/language-function-mailto.xml
+ docs/en/designers/language-custom-functions/language-function-popup-init.xml
+ docs/en/designers/language-custom-functions/language-function-textformat.xml
+ docs/en/designers/language-variables/language-config-variables.xml
+ docs/en/designers/language-variables/language-variables-smarty.xml:
+ Add literal tags to html, general formatting
+
+ * docs/en/getting-started.xml
+ docs/en/appendixes/resources.xml
+ docs/en/appendixes/tips.xml
+ docs/en/appendixes/troubleshooting.xml
+ docs/en/designers/config-files.xml
+ docs/en/programmers/caching.xml
+ docs/en/programmers/smarty-constants.xml
+ docs/en/programmers/advanced-features/advanced-features-objects.xml
+ docs/en/programmers/advanced-features/advanced-features-outputfilters.xml
+ docs/en/programmers/advanced-features/advanced-features-postfilters.xml
+ docs/en/programmers/advanced-features/advanced-features-prefilters.xml
+ docs/en/programmers/advanced-features/section-template-cache-handler-func.xml
+ docs/en/programmers/advanced-features/template-resources.xml
+ docs/en/programmers/api-variables/variable-autoload-filters.xml
+ docs/en/programmers/api-variables/variable-cache-dir.xml
+ docs/en/programmers/api-variables/variable-cache-handler-func.xml
+ docs/en/programmers/api-variables/variable-cache-lifetime.xml
+ docs/en/programmers/api-variables/variable-cache-modified-check.xml
+ docs/en/programmers/api-variables/variable-caching.xml
+ docs/en/programmers/api-variables/variable-compile-check.xml
+ docs/en/programmers/api-variables/variable-compile-dir.xml
+ docs/en/programmers/api-variables/variable-compile-id.xml
+ docs/en/programmers/api-variables/variable-config-booleanize.xml
+ docs/en/programmers/api-variables/variable-config-dir.xml
+ docs/en/programmers/api-variables/variable-config-fix-newlines.xml
+ docs/en/programmers/api-variables/variable-config-overwrite.xml
+ docs/en/programmers/api-variables/variable-config-read-hidden.xml
+ docs/en/programmers/api-variables/variable-debug-tpl.xml
+ docs/en/programmers/api-variables/variable-debugging-ctrl.xml
+ docs/en/programmers/api-variables/variable-debugging.xml
+ docs/en/programmers/api-variables/variable-default-modifiers.xml
+ docs/en/programmers/api-variables/variable-default-resource-type.xml
+ docs/en/programmers/api-variables/variable-error-reporting.xml
+ docs/en/programmers/api-variables/variable-force-compile.xml
+ docs/en/programmers/api-variables/variable-left-delimiter.xml
+ docs/en/programmers/api-variables/variable-php-handling.xml
+ docs/en/programmers/api-variables/variable-plugins-dir.xml
+ docs/en/programmers/api-variables/variable-request-use-auto-globals.xml
+ docs/en/programmers/api-variables/variable-request-vars-order.xml
+ docs/en/programmers/api-variables/variable-right-delimiter.xml
+ docs/en/programmers/api-variables/variable-secure-dir.xml
+ docs/en/programmers/api-variables/variable-security-settings.xml
+ docs/en/programmers/api-variables/variable-security.xml
+ docs/en/programmers/api-variables/variable-template-dir.xml
+ docs/en/programmers/api-variables/variable-trusted-dir.xml
+ docs/en/programmers/api-variables/variable-use-sub-dirs.xml
+ docs/en/programmers/caching/caching-cacheable.xml
+ docs/en/programmers/caching/caching-groups.xml
+ docs/en/programmers/caching/caching-multiple-caches.xml
+ docs/en/programmers/caching/caching-setting-up.xml:
+ Tidy up of formatting
+
+ * docs/entities/global.ent:
+ Adding some more resources
+
+ * docs/en/programmers/plugins/plugins-block-functions.xml
+ docs/en/programmers/plugins/plugins-compiler-functions.xml
+ docs/en/programmers/plugins/plugins-functions.xml
+ docs/en/programmers/plugins/plugins-inserts.xml
+ docs/en/programmers/plugins/plugins-modifiers.xml
+ docs/en/programmers/plugins/plugins-naming-conventions.xml
+ docs/en/programmers/plugins/plugins-outputfilters.xml
+ docs/en/programmers/plugins/plugins-prefilters-postfilters.xml
+ docs/en/programmers/plugins/plugins-resources.xml
+ docs/en/programmers/plugins/plugins-writing.xml:
+ Tidy up some formatting
+
+2006-09-26 Peter 'Mash' Morgan <pm@daffodil.uk.com>
+
+ * docs/en/programmers/api-functions/api-append-by-ref.xml
+ docs/en/programmers/api-functions/api-append.xml
+ docs/en/programmers/api-functions/api-assign-by-ref.xml
+ docs/en/programmers/api-functions/api-assign.xml
+ docs/en/programmers/api-functions/api-clear-all-assign.xml
+ docs/en/programmers/api-functions/api-clear-all-cache.xml
+ docs/en/programmers/api-functions/api-clear-assign.xml
+ docs/en/programmers/api-functions/api-clear-cache.xml
+ docs/en/programmers/api-functions/api-clear-compiled-tpl.xml
+ docs/en/programmers/api-functions/api-clear-config.xml
+ docs/en/programmers/api-functions/api-config-load.xml
+ docs/en/programmers/api-functions/api-display.xml
+ docs/en/programmers/api-functions/api-fetch.xml
+ docs/en/programmers/api-functions/api-get-config-vars.xml
+ docs/en/programmers/api-functions/api-get-registered-object.xml
+ docs/en/programmers/api-functions/api-get-template-vars.xml
+ docs/en/programmers/api-functions/api-is-cached.xml
+ docs/en/programmers/api-functions/api-load-filter.xml
+ docs/en/programmers/api-functions/api-register-block.xml
+ docs/en/programmers/api-functions/api-register-compiler-function.xml
+ docs/en/programmers/api-functions/api-register-function.xml
+ docs/en/programmers/api-functions/api-register-modifier.xml
+ docs/en/programmers/api-functions/api-register-object.xml
+ docs/en/programmers/api-functions/api-register-outputfilter.xml
+ docs/en/programmers/api-functions/api-register-postfilter.xml
+ docs/en/programmers/api-functions/api-register-prefilter.xml
+ docs/en/programmers/api-functions/api-register-resource.xml
+ docs/en/programmers/api-functions/api-template-exists.xml
+ docs/en/programmers/api-functions/api-trigger-error.xml
+ docs/en/programmers/api-functions/api-unregister-block.xml
+ docs/en/programmers/api-functions/api-unregister-compiler-function.xml
+ docs/en/programmers/api-functions/api-unregister-function.xml
+ docs/en/programmers/api-functions/api-unregister-modifier.xml
+ docs/en/programmers/api-functions/api-unregister-object.xml
+ docs/en/programmers/api-functions/api-unregister-outputfilter.xml
+ docs/en/programmers/api-functions/api-unregister-postfilter.xml
+ docs/en/programmers/api-functions/api-unregister-prefilter.xml
+ docs/en/programmers/api-functions/api-unregister-resource.xml:
+ Tidy up formatting and examples
+
+ * docs/en/language-snippets.ent:
+ Moved recurring para for register_*
+
+ * docs/en/designers/language-modifiers.xml:
+ Spelling on modifiers
+
+ * docs/en/designers/language-builtin-functions.xml
+ docs/en/designers/language-modifiers.xml
+ docs/en/designers/language-custom-functions/language-function-html-options.xml
+ docs/en/designers/language-modifiers/language-modifier-capitalize.xml
+ docs/en/designers/language-modifiers/language-modifier-cat.xml
+ docs/en/designers/language-modifiers/language-modifier-count-characters.xml
+ docs/en/designers/language-modifiers/language-modifier-count-paragraphs.xml
+ docs/en/designers/language-modifiers/language-modifier-count-sentences.xml
+ docs/en/designers/language-modifiers/language-modifier-count-words.xml
+ docs/en/designers/language-modifiers/language-modifier-date-format.xml
+ docs/en/designers/language-modifiers/language-modifier-default.xml
+ docs/en/designers/language-modifiers/language-modifier-escape.xml
+ docs/en/designers/language-modifiers/language-modifier-indent.xml
+ docs/en/designers/language-modifiers/language-modifier-lower.xml
+ docs/en/designers/language-modifiers/language-modifier-nl2br.xml
+ docs/en/designers/language-modifiers/language-modifier-regex-replace.xml
+ docs/en/designers/language-modifiers/language-modifier-replace.xml
+ docs/en/designers/language-modifiers/language-modifier-spacify.xml
+ docs/en/designers/language-modifiers/language-modifier-string-format.xml
+ docs/en/designers/language-modifiers/language-modifier-strip-tags.xml
+ docs/en/designers/language-modifiers/language-modifier-strip.xml
+ docs/en/designers/language-modifiers/language-modifier-truncate.xml
+ docs/en/designers/language-modifiers/language-modifier-upper.xml
+ docs/en/designers/language-modifiers/language-modifier-wordwrap.xml:
+ Tidying up some markup
+
+ * docs/en/designers/language-variables.xml:
+ typo
+
+ * docs/en/designers/language-variables.xml
+ docs/en/designers/language-variables/language-assigned-variables.xml
+ docs/en/designers/language-variables/language-config-variables.xml
+ docs/en/designers/language-variables/language-variables-smarty.xml:
+ Tidy up formatting on variables
+
+ * docs/en/designers/language-basic-syntax/language-escaping.xml
+ docs/en/designers/language-basic-syntax/language-math.xml
+ docs/en/designers/language-basic-syntax/language-syntax-comments.xml
+ docs/en/designers/language-basic-syntax/language-syntax-functions.xml
+ docs/en/designers/language-basic-syntax/language-syntax-quotes.xml
+ docs/en/designers/language-basic-syntax/language-syntax-variables.xml:
+ Formatting of the basic-syntax dir
+
+ * docs/en/designers/language-custom-functions/language-function-assign.xml
+ docs/en/designers/language-custom-functions/language-function-counter.xml
+ docs/en/designers/language-custom-functions/language-function-cycle.xml
+ docs/en/designers/language-custom-functions/language-function-debug.xml
+ docs/en/designers/language-custom-functions/language-function-eval.xml
+ docs/en/designers/language-custom-functions/language-function-fetch.xml
+ docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml
+ docs/en/designers/language-custom-functions/language-function-html-image.xml
+ docs/en/designers/language-custom-functions/language-function-html-options.xml
+ docs/en/designers/language-custom-functions/language-function-html-radios.xml
+ docs/en/designers/language-custom-functions/language-function-html-select-date.xml
+ docs/en/designers/language-custom-functions/language-function-html-select-time.xml
+ docs/en/designers/language-custom-functions/language-function-html-table.xml
+ docs/en/designers/language-custom-functions/language-function-mailto.xml
+ docs/en/designers/language-custom-functions/language-function-math.xml
+ docs/en/designers/language-custom-functions/language-function-popup-init.xml
+ docs/en/designers/language-custom-functions/language-function-popup.xml
+ docs/en/designers/language-custom-functions/language-function-textformat.xml:
+ More formatting and cleaning up examples
+
+2006-09-25 Peter 'Mash' Morgan <pm@daffodil.uk.com>
+
+ * docs/en/designers/language-builtin-functions/language-function-foreach.xml
+ docs/en/designers/language-builtin-functions/language-function-section.xml:
+ Doh! removing tabs
+
+ * docs/en/designers/language-builtin-functions/language-function-capture.xml
+ docs/en/designers/language-builtin-functions/language-function-config-load.xml
+ docs/en/designers/language-builtin-functions/language-function-foreach.xml
+ docs/en/designers/language-builtin-functions/language-function-if.xml
+ docs/en/designers/language-builtin-functions/language-function-include-php.xml
+ docs/en/designers/language-builtin-functions/language-function-include.xml
+ docs/en/designers/language-builtin-functions/language-function-insert.xml
+ docs/en/designers/language-builtin-functions/language-function-ldelim.xml
+ docs/en/designers/language-builtin-functions/language-function-literal.xml
+ docs/en/designers/language-builtin-functions/language-function-php.xml
+ docs/en/designers/language-builtin-functions/language-function-section.xml
+ docs/en/designers/language-builtin-functions/language-function-strip.xml:
+ A lot of formatting, tagging and tidy up. Some consistency at last
+
+ * docs/en/designers/language-builtin-functions/language-function-section.xml:
+ Major tidy up
+
+ * docs/en/designers/language-builtin-functions/language-function-foreach.xml:
+ Major tidy up, added index property and some examples
+
+2006-09-03 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/designers/language-custom-functions/language-function-popup-init.xml
+ docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml
+ docs/fr/programmers/advanced-features/advanced-features-postfilters.xml
+ docs/fr/programmers/advanced-features/advanced-features-prefilters.xml:
+ sync with EN
+
+2006-09-01 George Miroshnikov <support@infinity.com.ua>
+
+ * docs/ru/programmers/api-functions/api-append-by-ref.xml
+ docs/ru/programmers/api-functions/api-append.xml
+ docs/ru/programmers/api-functions/api-assign-by-ref.xml
+ docs/ru/programmers/api-functions/api-assign.xml
+ docs/ru/programmers/api-functions/api-clear-all-assign.xml
+ docs/ru/programmers/api-functions/api-clear-all-cache.xml
+ docs/ru/programmers/api-functions/api-clear-assign.xml
+ docs/ru/programmers/api-functions/api-clear-cache.xml
+ docs/ru/programmers/api-functions/api-clear-compiled-tpl.xml
+ docs/ru/programmers/api-functions/api-clear-config.xml
+ docs/ru/programmers/api-functions/api-config-load.xml
+ docs/ru/programmers/api-functions/api-display.xml:
+ sync with EN
+
+2006-08-25 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed wrong handling of name attribute in {insert}
+ thanks to Ivan Kravets for reporting this
+
+ * libs/Smarty_Compiler.class.php:
+ fixed typo
+
+2006-08-21 George Miroshnikov <support@infinity.com.ua>
+
+ * docs/ru/designers/language-custom-functions/language-function-popup-init.xml
+ docs/ru/programmers/advanced-features/advanced-features-objects.xml
+ docs/ru/programmers/advanced-features/advanced-features-outputfilters.xml
+ docs/ru/programmers/advanced-features/advanced-features-postfilters.xml
+ docs/ru/programmers/advanced-features/advanced-features-prefilters.xml
+ docs/ru/programmers/advanced-features/section-template-cache-handler-func.xml
+ docs/ru/programmers/advanced-features/template-resources.xml:
+ sync with EN
+
+ * docs/en/programmers/advanced-features/advanced-features-prefilters.xml:
+ another missing dot
+
+ * docs/en/programmers/advanced-features/advanced-features-postfilters.xml:
+ missing dot
+
+ * docs/en/programmers/advanced-features/advanced-features-outputfilters.xml:
+ missing comma
+
+2006-08-19 Peter 'Mash' Morgan <pmm@daffodil.uk.com>
+
+ * docs/en/designers/language-custom-functions/language-function-popup-init.xml:
+ avoid dupes and added remote paths
+
+2006-08-06 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/designers/language-custom-functions/language-function-html-table.xml
+ docs/fr/designers/language-custom-functions/language-function-mailto.xml:
+ sync with EN
+
+2006-08-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix false replacement of "$t" inside double quotes
+ thanks to checat for reporting this
+
+2006-07-20 George Miroshnikov <support@infinity.com.ua>
+
+ * docs/ru/designers/language-custom-functions/language-function-html-table.xml
+ docs/ru/designers/language-custom-functions/language-function-mailto.xml:
+ incrementing EN-Revision
+
+ * docs/ru/designers/language-custom-functions/language-function-assign.xml
+ docs/ru/designers/language-custom-functions/language-function-eval.xml
+ docs/ru/designers/language-custom-functions/language-function-fetch.xml
+ docs/ru/designers/language-custom-functions/language-function-html-checkboxes.xml
+ docs/ru/designers/language-custom-functions/language-function-html-image.xml
+ docs/ru/designers/language-custom-functions/language-function-html-options.xml
+ docs/ru/designers/language-custom-functions/language-function-html-radios.xml
+ docs/ru/designers/language-custom-functions/language-function-html-table.xml
+ docs/ru/designers/language-custom-functions/language-function-mailto.xml
+ docs/ru/designers/language-custom-functions/language-function-popup-init.xml
+ docs/ru/designers/language-custom-functions/language-function-popup.xml
+ docs/ru/designers/language-modifiers/language-modifier-date-format.xml
+ docs/ru/designers/language-modifiers/language-modifier-default.xml
+ docs/ru/designers/language-modifiers/language-modifier-escape.xml
+ docs/ru/designers/language-modifiers/language-modifier-indent.xml
+ docs/ru/designers/language-modifiers/language-modifier-lower.xml
+ docs/ru/designers/language-modifiers/language-modifier-nl2br.xml
+ docs/ru/designers/language-modifiers/language-modifier-strip.xml
+ docs/ru/designers/language-modifiers/language-modifier-truncate.xml
+ docs/ru/designers/language-modifiers/language-modifier-upper.xml
+ docs/ru/designers/language-modifiers/language-modifier-wordwrap.xml
+ docs/ru/designers/language-variables/language-variables-smarty.xml:
+ sync with EN
+
+ * docs/en/designers/language-custom-functions/language-function-mailto.xml:
+ typo
+
+2006-07-10 boots <jayboots@yahoo.com>
+
+ * libs/plugins/function.html_table.php:
+ fixed email address in comments
+
+ * NEWS
+ libs/plugins/function.html_table.php:
+ html_table: fixed th/tr output, added hdir support for column
+ headings,update docs to reflect new features
+
+2006-07-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_table.php:
+ fix occasional notices on undefined variables
+
+2006-07-08 boots <jayboots@yahoo.com>
+
+ * libs/plugins/function.html_table.php:
+ Added ability to specify column headings in {html_table}
+
+ Added th_attrs attribute which works similary to td_attr and tr_attr but
+ for TH elements. Changes the cols attribute to allow mixed values; a
+ numeric still specifies the number of columns to render but now an array
+ of values can be used to specify TH column values. The number of columns
+ is determine from the size of the array. Further, a comma-separated
+ string of column names can be used which is internally coverted to an
+ array and used as if it was specified as a normal array.
+
+ Thanks for lynlyn for the feature request.
+
+2006-06-23 boots <jayboots@yahoo.com>
+
+ * libs/plugins/outputfilter.trimwhitespace.php:
+ fix comments in outputfilter.trimwhitespace
+
+ * NEWS
+ libs/plugins/outputfilter.trimwhitespace.php:
+ fixed ordering of replacements in trimwhitespace output filter
+
+ Thanks to Getty from IRC for reporting this.
+
+2006-06-20 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/plugins/function.mailto.php:
+ update mailto function plugin to work around a firefox/thunderbird escaping
+ bug
+
+ Thanks to elijahlofgren from the forums for reporting this and providing
+ the necessary patch
+
+ * NEWS
+ libs/plugins/modifier.date_format.php:
+ emulate %l in the date_format modifier on windows
+
+ thanks to Gibberish from the forums for reporting this
+
+2006-06-14 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/plugins/modifier.capitalize.php:
+ Fix handling of apostrophes in the capitalize modifier.
+
+ Thanks to asmecher from the forums for reporting this and providing a
+ partial solution.
+
+2006-05-28 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers
+
+2006-05-25 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ un-hide hidden xml open tags
+
+2006-05-09 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ separate handling of comment blocks from "special blocks"
+
+ * NEWS
+ libs/plugins/function.popup_init.php:
+ reverted {popup_init} as proposed change to insertion behviour was not BC
+
+2006-05-04 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/plugins/function.popup_init.php:
+ changed {popup_init} to only emit code once during a request
+
+ Thanks to TGKnIght from forums
+
+2006-04-22 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix handling of block-methods of registered objects
+ thanks to El Hombre Gris
+
+2006-04-04 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/function.html_select_date.php:
+ fix typo
+
+2006-03-09 Monte Ohrt <monte@ohrt.com>
+
+ * (Smarty_2_6_13)
+ NEWS:
+ update for release
+
+2006-03-08 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/modifier.regex_replace.php:
+ remove delim quote
+
+ * libs/plugins/modifier.regex_replace.php:
+ fix delimiter issue
+
+2006-03-03 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/modifier.regex_replace.php:
+ use preg_replace to cover any space chars
+
+ * libs/plugins/modifier.regex_replace.php:
+ fix problem with allowing "e" modifier
+
+2006-01-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ removed possiblity for E_NOTICE on an undefined variable in
+ Smarty_Compiler::_compile_if_tag() - thanks to sbeh
+
+2006-01-18 Monte Ohrt <monte@ohrt.com>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers
+
+ * (Smarty_2_6_12)
+ NEWS:
+ commit 2.6.12 release
+
+2006-01-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed use of references $cache_attrs and $repeat in Smarty_Compiler.
+
+ php does not allow to pass an assigned by reference to a function. since
+ php-5.1.2
+ the reference to the lval gets lost when passing an assignment.
+
+2005-12-31 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ fixed incompatible use of fread() in Smarty::_read_file()
+ it choke on php-5.1.1 and later.
+ thanks to andig for pointing this out.
+
+2005-12-21 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ Fix improper tokenization of certain inline math expressions.
+
+ Thanks to gerard at forums for reporting this.
+
+2005-12-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.math.php:
+ fixed problem with math in certain LC_NUMERIC locales.
+ thanks to wiebren for providing problem+solution.
+
+2005-12-14 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS:
+ fixed iso-latin1 special chars
+
+2005-12-14 Monte Ohrt <monte@ohrt.com>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers
+
+ * (Smarty_2_6_11)
+ NEWS:
+ commit NEWS file for 2.6.11
+
+2005-12-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/de/getting-started.xml:
+ sync with en
+
+2005-11-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed code generation of non-cacheable blocks to play well with php's
+ "Alternative syntax" used for example in compiled {if}..{else}..{/if}
+ blocks.
+
+ (see: http://php.net/manual/en/control-structures.alternative-syntax.php
+ on "Alternative syntax")
+
+ thanks to kihara from the forum.
+
+2005-11-26 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS:
+ fixed handling of multiple identical calls to {insert}.
+
+ the function was called multiple times, but all inserts where replaced
+ by the results of the first call to the insert function.
+
+ * libs/plugins/compiler.assign.php
+ libs/plugins/function.config_load.php:
+ added credits
+
+ * libs/plugins/function.popup.php:
+ added "closeclick" from
+ http://www.bosrup.com/web/overlib/?Command_Reference
+
+2005-11-23 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/plugins/modifier.escape.php:
+ replace {} string access with equivalent substr() to avoid E_STRICT
+ warnings in PHP 5.1
+
+2005-11-09 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/Smarty.class.php:
+ return valid reference in get_config_vars() when given var is non-existant
+
+2005-10-11 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/block.textformat.php
+ libs/plugins/compiler.assign.php
+ libs/plugins/function.assign_debug_info.php
+ libs/plugins/function.config_load.php
+ libs/plugins/function.counter.php
+ libs/plugins/function.eval.php
+ libs/plugins/function.fetch.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_select_date.php
+ libs/plugins/function.html_select_time.php
+ libs/plugins/function.math.php
+ libs/plugins/function.popup.php
+ libs/plugins/function.popup_init.php
+ libs/plugins/modifier.capitalize.php
+ libs/plugins/modifier.count_characters.php
+ libs/plugins/modifier.count_paragraphs.php
+ libs/plugins/modifier.count_sentences.php
+ libs/plugins/modifier.count_words.php
+ libs/plugins/modifier.date_format.php
+ libs/plugins/modifier.debug_print_var.php
+ libs/plugins/modifier.default.php
+ libs/plugins/modifier.escape.php
+ libs/plugins/modifier.indent.php
+ libs/plugins/modifier.lower.php
+ libs/plugins/modifier.regex_replace.php
+ libs/plugins/modifier.replace.php
+ libs/plugins/modifier.spacify.php
+ libs/plugins/modifier.string_format.php
+ libs/plugins/modifier.strip_tags.php
+ libs/plugins/modifier.truncate.php
+ libs/plugins/modifier.upper.php
+ libs/plugins/modifier.wordwrap.php
+ libs/plugins/shared.escape_special_chars.php
+ libs/plugins/shared.make_timestamp.php:
+ Added author title to plugins where they don't exist. I put my name where I
+ was the original or co-author. If there needs to be more credit given
+ somewhere, speak up!
+
+2005-10-10 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/plugins/function.html_image.php:
+ add path_prefix to html_image, fix incorrect secure_dir error when image
+ file is missing
+
+2005-10-04 Monte Ohrt <monte@ohrt.com>
+
+ * demo/templates/index.tpl:
+ remove popup example, update section var syntax
+
+2005-09-16 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/de/getting-started.xml:
+ more fixes
+
+ * docs/de/getting-started.xml:
+ fix php bug #34520: broken example display (de only)
+
+2005-08-30 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/modifier.escape.php:
+ change default charset from utf8 to iso-8859-1
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ add char_set param
+
+2005-08-17 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS:
+ fix notice in debug security check
+
+ * libs/Smarty.class.php:
+ fix typo
+
+ * NEWS
+ libs/Smarty.class.php:
+ return valid reference in get_template_vars() when given var is
+ non-existant
+
+2005-08-12 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ add "urlpathinfo" escape type to escape modifier. (apache does not like %2F
+ in the PATH_INFO)
+
+2005-08-05 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers
+
+2005-08-04 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS:
+ update secure_dir notes
+
+ * NEWS:
+ allow debug.tpl to work from arbitrary dir
+
+2005-08-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed proper escaping for literal strings passed to
+ Smarty_Compiler::_expand_quoted_text() by
+ Smarty_Compiler::_parse_var_props()
+
+2005-07-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/shared.make_timestamp.php:
+ removed ambiguity for numeric values passed to smarty_make_timestamp().
+ numeric values are *always* treated as timestamps now.
+
+2005-07-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php:
+ removed E_NOTICE from Config_File::get()
+
+ * libs/Smarty.class.php:
+ removed E_NOTICE
+
+2005-07-10 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/getting-started.xml:
+ sync with EN
+
+2005-07-08 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS:
+ correct username in NEWS file
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ added passthru attribute feature to html_select_date
+
+2005-07-03 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/language-snippets.ent
+ docs/fr/preface.xml:
+ sync with EN
+
+2005-06-16 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/de/preface.xml
+ docs/de/preface.xml:
+ sync with en
+
+2005-06-13 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/plugins/modifier.truncate.php:
+ add "middle" parameter to truncate modifier
+
+2005-06-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/de/livedocs.ent:
+ added german livedocs.ent
+
+ * docs/de/language-snippets.ent
+ docs/de/preface.xml:
+ sync with en
+
+2005-06-09 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/de/bookinfo.xml
+ docs/de/getting-started.xml
+ docs/de/getting-started.xml:
+ sync with en
+
+2005-05-24 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/getting-started.xml
+ docs/fr/language-snippets.ent:
+ sync with EN
+
+2005-05-20 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/function.html_radios.php:
+ fix allowable label id characters
+
+2005-05-06 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/plugins/function.html_radios.php:
+ make form input label ids optional (monte)
+
+2005-05-02 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ add error message for empty if/elseif statements
+
+2005-04-15 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/plugins/function.html_radios.php:
+ cast selected value to string for comparison in html_radios
+
+2005-04-07 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ added xhtml compliance to html_select_date's year_as_text-feature
+ thanks to Mark West
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ fixed handling of selected month html_select_date
+ thanks to Yuri Weseman for providing problem+solution
+
+2005-04-07 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/configure.in:
+ sync configure and file-entities scripts with phpdoc, for better
+ windows/cygwin support
+
+2005-03-31 Monte Ohrt <monte@ohrt.com>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers
+
+ * (Smarty_2_6_9)
+ NEWS:
+ update NEWS file
+
+2005-03-30 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.math.php:
+ re-enabled hex-constant. i hope in a sane way this time.
+
+2005-03-30 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/function.math.php:
+ fix function testing logic
+
+ * libs/Smarty_Compiler.class.php:
+ disable variable func calls completely
+
+ * libs/Smarty_Compiler.class.php:
+ disallow variable func calls when security is enabled
+
+2005-03-22 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ bumped version-number to 2.6.9-dev
+ added headline of 2.6.6 release to NEWS file
+
+2005-03-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * (Smarty_2_6_8)
+ NEWS:
+ maybe even better this way. thanks monte :)
+
+ * NEWS:
+ little more clear news-entry
+
+2005-03-21 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS:
+ update NEWS with e-modifier removal
+
+ * (Smarty_2_6_8)
+ libs/plugins/modifier.regex_replace.php:
+ remove e-modifier
+
+2005-03-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ objects don't get casted to arrays anymore in {foreach}
+
+2005-02-26 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ add "null" as a valid token for {if} when security is enabled
+
+2005-02-25 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS
+ libs/plugins/function.mailto.php:
+ add javascript_charcode option to mailto
+
+2005-02-24 Monte Ohrt <monte@ohrt.com>
+
+ * NEWS:
+ update NEWS file
+
+ * QUICK_START
+ libs/plugins/function.html_radios.php:
+ add label ids to html_radios
+
+2005-02-10 Monte Ohrt <monte@ohrt.com>
+
+ * QUICK_START:
+ update with directory structure
+
+2005-02-10 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/Makefile.in:
+ fix chm generation
+
+2005-02-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed too agressive {strip} around delimiters inside strip-blocks
+
+2005-02-10 Monte Ohrt <monte@ohrt.com>
+
+ * QUICK_START:
+ fix a couple errors
+
+2005-02-10 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/Makefile.in
+ docs/README:
+ commiting the new tools to make the CHM manual.
+
+2005-02-09 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed handling of strip-tags with non-default delimiters
+
+2005-02-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_radios.php:
+ fixed syntax error. shame on me.
+
+2005-02-03 Monte Ohrt <monte@ohrt.com>
+
+ * QUICK_START:
+ fix example
+
+ * QUICK_START:
+ initial commit
+
+ * RELEASE_NOTES
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers in cvs
+
+ * (Smarty_2_6_7)
+ NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ commit version numbers for new release
+
+2005-02-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * (Smarty_2_6_7)
+ libs/plugins/function.html_image.php:
+ fixed comment (thanks to CirTap)
+
+2005-02-01 Monte Ohrt <monte@ohrt.com>
+
+ * libs/plugins/function.html_image.php:
+ remove border tag
+
+2005-02-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ fixed serialization of values containing newlines (like _cache_attrs)
+ in core_write_cache_file()
+
+ bumped version to 2.6.6-dev-3 to indicate that the fileformat of cache
+ has changed
+
+2005-01-30 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed handling of hashed opening php-tags inside strip-blocks
+ (reported by titi_rafa)
+
+2005-01-30 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/fr/language-snippets.ent:
+ fix build
+
+2005-01-28 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ escape:url now uses the (RFC 1738 compliant) rawurlencode()
+
+2005-01-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ replaced ? true : false and removed intermediate $_cookie_var in the
+ handling of the SMARTY_DEBUG-cookie
+
+2005-01-22 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/bookinfo.xml:
+ update EN-Revision tag
+
+2005-01-21 Monte Ohrt <monte@ohrt.com>
+
+ * README
+ RELEASE_NOTES
+ docs/de/bookinfo.xml
+ docs/fr/bookinfo.xml
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/plugins/function.cycle.php
+ libs/plugins/function.debug.php
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_image.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/function.html_table.php
+ libs/plugins/function.mailto.php
+ libs/plugins/modifier.cat.php
+ libs/plugins/modifier.nl2br.php
+ libs/plugins/modifier.strip.php
+ libs/plugins/outputfilter.trimwhitespace.php:
+ de-spammify e-mails
+
+ * README
+ RELEASE_NOTES
+ docs/de/bookinfo.xml
+ docs/fr/bookinfo.xml
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/plugins/function.cycle.php
+ libs/plugins/function.debug.php
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_image.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/function.html_table.php
+ libs/plugins/function.mailto.php
+ libs/plugins/modifier.cat.php
+ libs/plugins/modifier.nl2br.php
+ libs/plugins/modifier.strip.php
+ libs/plugins/outputfilter.trimwhitespace.php:
+ update copyright notices, e-mail addresses
+
+2005-01-06 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ reduced the code that is generated on a {foreach}-block that has a
+ name.
+
+ instead of pre-computing all foreach-properties (like first, last,
+ show) on each iteration, they are computed on demand as soon as
+ {$smarty.foreach.*}-variables are used.
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ slight optimization in the compilation of $smarty.const.FOO .
+
+ more complex consts like $smarty.const.$name still compile to
+ constant($this->_tpl_vars['name'])
+
+2005-01-05 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ make block functions and registered objects' block methods use a
+ local variable for block_content instead of $this->_block_content
+
+ it's not necessary to have $smarty->_block_content accessible.
+
+2005-01-04 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/bookinfo.xml:
+ sync with EN
+
+2005-01-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ Happy new year from germany.
+
+2004-12-28 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php:
+ fix _read_file comments
+
+2004-12-26 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/getting-started.xml
+ docs/fr/preface.xml:
+ typo
+
+ * docs/fr/language-defs.ent
+ docs/fr/language-snippets.ent
+ docs/fr/livedocs.ent:
+ sync with EN & typo
+
+2004-12-21 Yannick Torres <yannick.torres@keliglia.com>
+
+ * docs/fr/bookinfo.xml
+ docs/fr/getting-started.xml
+ docs/fr/translation.xml:
+ sync with EN
+
+2004-12-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed escaping of template-filenames in the generated code that loads
+ needed plugins
+
+2004-12-15 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/function.popup.php:
+ fix invalid HTML issue with popup
+
+2004-12-06 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/plugins/function.popup.php:
+ - fixed {popup} to properly handle inarray and function parameters and
+ added support for mouseoff and followmouse options
+
+2004-11-21 Mehdi Achour <didou@keliglia.com>
+
+ * docs/fr/livedocs.ent:
+ add livedocs specific entities files
+
+2004-11-16 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_radios.php:
+ cleaned up typecasting
+
+2004-11-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_options.php:
+ fixed semantically misleading check for $options (use isset() instead
+ of is_array() because it is always an array).
+
+ thanks to albert almeida.
+
+2004-11-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ removed unused code
+
+2004-10-25 Mehdi Achour <didou@keliglia.com>
+
+ * docs/fr/bookinfo.xml
+ docs/fr/getting-started.xml:
+ sync with en
+
+2004-10-13 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ update header
+
+2004-10-02 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS:
+ fixed nocache-handling with nested includes. there was a logical error
+ in the replacement of internal nocache-tags to dynamic content that
+ lead to false results with deeply nested includes or with
+ nocache-blocks inside nocache-blocks.
+
+ many thanks to Lars Jankowfsky for providing big help on reproducing
+ and tracking down this bug!
+
+2004-10-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ - better header for compiled includes (more in line with compiled
+ templates)
+
+ - reuse cache_serials if a file is compiled more than once in one
+ process (force_compile)
+
+ - don't print nocache-delimiters wenn already inside
+ process_cached_inserts()
+
+2004-09-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ switched from @count() to !empty() . this was pointed out a few times
+ by a few people with buggy error-handlers
+
+ * libs/Smarty_Compiler.class.php:
+ added some property declarations
+
+2004-09-28 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ bumped up version number to reflect incompatibility in tempfiles of
+ 'core' vs. 'internals'
+
+2004-09-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_select_date.php:
+ fixed $start_year when no value for the year in $time is given.
+
+2004-09-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_table.php:
+ fixed handling of "inner"-attribute
+
+ * libs/Smarty_Compiler.class.php:
+ fixed handling of object derefence inside backticks
+
+2004-09-20 Monte Ohrt <monte@ispi.net>
+
+ * libs/debug.tpl:
+ add <head></head> tags
+
+2004-09-18 boots <jayboots@yahoo.com>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/plugins/function.config_load.php
+ libs/plugins/function.debug.php
+ libs/plugins/function.fetch.php
+ libs/plugins/function.html_image.php:
+ Fixed \\r\\n line endings mistakenly introduced in last commit. d'oh.
+
+2004-09-16 boots <jayboots@yahoo.com>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.assemble_plugin_filepath.php
+ libs/core/core.assign_smarty_interface.php
+ libs/core/core.create_dir_structure.php
+ libs/core/core.display_debug_console.php
+ libs/core/core.get_include_path.php
+ libs/core/core.get_microtime.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.is_secure.php
+ libs/core/core.is_trusted.php
+ libs/core/core.load_plugins.php
+ libs/core/core.load_resource_plugin.php
+ libs/core/core.process_cached_inserts.php
+ libs/core/core.process_compiled_include.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.rm_auto.php
+ libs/core/core.rmdir.php
+ libs/core/core.run_insert_handler.php
+ libs/core/core.smarty_include_php.php
+ libs/core/core.write_cache_file.php
+ libs/core/core.write_compiled_include.php
+ libs/core/core.write_compiled_resource.php
+ libs/core/core.write_file.php
+ libs/plugins/function.config_load.php
+ libs/plugins/function.debug.php
+ libs/plugins/function.fetch.php
+ libs/plugins/function.html_image.php:
+ Moved /libs/core to /libs/internals and created new constant,
+ SMARTY_CORE_DIR which defaults to SMARTY_DIR/internals. This should help
+ CVS and rsynch users butupgrades will require changes and this may affect
+ 3rd party plugins that use the /core dir.
+
+2004-09-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ moved $this->_num_const_regexp out of $this->_var_regexp and added it
+ to the places that affect $this->_var_regexp
+
+ this should fix some problems parsing plugin-names endings with digits
+
+2004-09-14 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update files to 2.6.6-dev
+
+2004-09-13 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS:
+ fixed typo
+
+2004-09-13 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_6_5)
+ NEWS:
+ update NEWS file with parsing correction note
+
+2004-09-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.debug.php:
+ removed notice from {debug}
+ thanks to Peter Billen for pointing this one out!
+
+2004-09-11 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ fix more object calling syntax issues
+
+2004-09-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ added $smarty->security_settings['ALLOW_CONSTANTS']
+ including test-cases for them
+
+2004-09-09 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ break down regex to digestable chunks, fix multiple param problem with
+ method calls,
+ add object method testing to unit_test cases
+
+ * libs/Smarty_Compiler.class.php:
+ update code comment with more examples
+
+ * libs/Smarty_Compiler.class.php:
+ allow objects in arbitrary param positions
+
+ * libs/Smarty_Compiler.class.php:
+ fix object parameter regex, allow one level of object indirection
+
+ * libs/Smarty_Compiler.class.php:
+ fix compile problem with numeric constants and math operator matching
+
+2004-09-07 Monte Ohrt <monte@ispi.net>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update files to 2.6.5-dev
+
+ * (Smarty_2_6_4)
+ NEWS:
+ update NEWS file with 2.6.4 header
+
+2004-08-31 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ fix preg_quote
+
+ * libs/Smarty_Compiler.class.php:
+ fix math in object params, clean up some regex on the way, change
+ preg_ delimiters to ~ to avoid character clashes with ! and %
+
+2004-08-30 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ add $smarty.ldelim and $smarty.rdelim to smarty special var
+
+2004-08-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/core/core.write_file.php:
+ tempnam() seems to be borken on many installation.
+
+ now we try tempnam first and if that fails we generate our own
+ temp-filename with uniqid()
+
+2004-08-23 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/modifier.capitalize.php:
+ dont use constant, use static var instead
+
+ * libs/plugins/modifier.capitalize.php:
+ implement optional param to capitalize for digit behavior
+
+ * libs/plugins/modifier.capitalize.php:
+ another commit to capitalize, taking special chars into account
+
+2004-08-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ cleaned up attribute-handling in Smarty_Compiler::_compile_foreach_start()
+
+2004-08-23 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/function.html_select_date.php
+ libs/plugins/modifier.capitalize.php:
+ fix capitalize modifier to not rely on buggy ucwords() func
+
+2004-08-20 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/function.html_select_date.php:
+ update version
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ make time param work with negative timestamps, force year range to include
+ given date unless explicitly set
+
+2004-08-19 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/function.fetch.php:
+ fix bug with fetch, passing user/pass in url did not work
+
+2004-08-13 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed handling of {foreachelse} and {sectionelse} that got borked with
+ the latest commit (v 1.330)
+
+2004-08-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed occasional wrong error messages on mismatched tags when
+ {else}, {elseif}, {foreachelse} or {sectionelse} is involved
+
+ thanks to Ooypunk for pointing me on this
+
+2004-08-12 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/.cvsignore
+ docs/Makefile.in
+ docs/configure.in:
+ enable russian PDF builds
+
+2004-07-30 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/configure.in:
+ typo
+
+ * docs/Makefile.in
+ docs/README
+ docs/configure.in:
+ add make test_xml
+ this is usefull to detect XML problems
+
+2004-07-29 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/configure.in:
+ avoid warnings in head
+
+ * docs/.cvsignore
+ docs/Makefile.in
+ docs/README
+ docs/configure.in:
+ build pdf files
+ just type make pdf
+
+2004-07-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed handling of methods arguments.
+
+ thanks to Manfred Wischin for finding this one and providing the
+ conceptual fix.
+
+2004-07-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_radios.php:
+ there was little flaw in smarty_function_html_radios() and
+ smarty_function_html_checkboxes():
+
+ the newly introduced assign-attribute was still added to the
+ tag-output as an extra-attribute.
+
+ fixed.
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.load_plugins.php
+ libs/core/core.load_resource_plugin.php
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_image.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/function.html_select_date.php
+ libs/plugins/function.html_select_time.php
+ libs/plugins/modifier.date_format.php:
+ backed out renaming of _get_plugin_filepath() to get_plugin_filepath()
+
+ we'll stick to _get_plugin_filepath() and look for a more viable
+ solution to be exposed to plugin-writers.
+
+2004-07-20 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php
+ libs/core/core.is_trusted.php
+ libs/plugins/compiler.assign.php:
+ Some fixes on PhpDocumentor comments. Thanks go to Ruben Vermeersch.
+
+2004-07-16 andreas halter <phpcvs@andreashalter.ch>
+
+ * docs/de/bookinfo.xml
+ docs/de/getting-started.xml
+ docs/de/language-defs.ent
+ docs/de/language-snippets.ent
+ docs/de/preface.xml:
+ - updated for 2.6.3
+ - updates for new build system
+ - added missing files
+ - corrections from users
+ - revcheck comments for all files
+ - big up to didou and nuno, brilliant work
+ - make test: ok
+ - make: ok
+
+2004-07-16 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/de/getting-started.xml:
+ fix the revision tracking tag
+ the revision number might not be right. just check it, please
+
+2004-07-16 andreas halter <phpcvs@andreashalter.ch>
+
+ * docs/de/getting-started.xml:
+ - updated version (incl revcheck comment) for revcheck testing
+
+2004-07-14 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php:
+ replace " with ' where literal strings are quoted (ever so slight speedup)
+
+2004-07-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/modifier.date_format.php:
+ changed call from $smarty->_get_plugin_filepath() to
+ $smarty->get_plugin_filepath()
+
+ * libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_image.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/function.html_select_date.php
+ libs/plugins/function.html_select_time.php:
+ renamed calls to $smarty->_get_plugin_filepath() to
+ $smarty->get_plugin_filepath()
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.load_plugins.php
+ libs/core/core.load_resource_plugin.php:
+ renamed Smarty::_get_plugin_filepath() to Smarty::get_plugin_filepath()
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/core/core.write_compiled_include.php
+ libs/core/core.write_compiled_resource.php
+ libs/core/core.write_file.php:
+ removed touch() call. changing the timestamp of the compiled-template
+ to the source template's may be irritating for certain
+ source-code-caches. now a newly compiled template gets the current
+ time as timestamp.
+
+2004-07-02 gerald croes <gerald@phpside.org>
+
+ * docs/fr/getting-started.xml
+ docs/fr/preface.xml:
+ Fixed missing tags to be able to make doc again
+
+ * docs/fr/preface.xml:
+ added the "is a good thing [TM]" as in en docs
+
+ * docs/fr/getting-started.xml:
+ added ctags, updated screen => programm listing.
+ added the technical note founded on the en doc
+
+2004-07-02 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/function.mailto.php:
+ add assign attribute to html_checkboxes and html_radios
+
+2004-07-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ removed use of get_include_filepath() inside
+ get_auto_filename(). thanks go to c960657
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ enhanced error-reporting for {foreach}
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed handling of digits inside tagnames. this problem slipped into
+ the regexps by adding support for numeric contants next to string
+ constants as variables.
+
+2004-06-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed escaping of backslashes in Smarty_Compiler::_quote_replace()
+
+2004-06-23 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/modifier.date_format.php:
+ display date_format %e, %T and %D as expected for windows
+
+2004-06-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ changed version-number to 2.6.4-dev
+
+2004-06-16 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_6_3)
+ NEWS:
+ update NEWS file with version number
+
+2004-06-09 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ added escapement of '</' to javascript escaping
+
+2004-06-08 gerald croes <gerald@phpside.org>
+
+ * docs/fr/translation.xml:
+ Add other translators.
+
+2004-06-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ made the correct value of "use_sub_dirs" available to the compiler.
+ (not worth a NEWS-entry, i think)
+
+2004-06-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.fetch.php:
+ fix: proper initialistaion of $content.
+ thanks to Dmitry Koteroff for pointing this out.
+
+2004-05-29 Mehdi Achour <didou@keliglia.com>
+
+ * docs/fr/translation.xml:
+ oups :)
+
+ * docs/fr/translation.xml:
+ added translation file
+
+2004-05-28 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/Makefile.in:
+ clean also file-entities.php
+
+2004-05-28 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.mailto.php:
+ added obfuscation of protocol-string in {mailto} when using
+ hex-encoding (thanks to bharat)
+
+2004-05-26 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ enhanced auto-generated filenames for templates_c and cache
+
+ incremented Smarty::_version because the tempfiles' structure changed
+ a little
+
+2004-05-23 Mehdi Achour <didou@keliglia.com>
+
+ * docs/fr/bookinfo.xml
+ docs/fr/getting-started.xml
+ docs/fr/preface.xml:
+ WS and added revcheck
+
+2004-05-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed typo in error-messages
+
+ * docs/de/language-snippets.ent
+ docs/fr/language-snippets.ent:
+ added empty language-snippets.ent to fix "make web"
+
+2004-05-12 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ add 'nonstd' escape modifier
+
+2004-05-07 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/block.textformat.php:
+ update textformat to not output wrap chars after last para
+
+2004-05-06 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/core/core.write_file.php:
+ use tempnam() instead of unqid() to create better temporary files in
+ smarty_core_write_file().
+
+ (thanks to xces for finding this race-condition and his work on
+ fixing it)
+
+2004-05-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ added check if for file_exists() to Smarty::_read_file()
+
+2004-04-30 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ add 'mail' attribute to escape modifier
+
+2004-04-20 Mehdi Achour <didou@keliglia.com>
+
+ * docs/manual.xml.in:
+ added the language-snippets.ent file and started using entities for notes
+ under en/programmers/api-functions
+
+2004-04-18 Mehdi Achour <didou@keliglia.com>
+
+ * docs/de/getting-started.xml
+ docs/fr/getting-started.xml:
+ new global entity for zend and php-accelerator
+
+ * docs/fr/bookinfo.xml
+ docs/fr/getting-started.xml
+ docs/fr/preface.xml:
+ added myself as translator and added vim comments and xml tags
+
+2004-04-16 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS:
+ added entry for numeric constants
+
+ * libs/Smarty_Compiler.class.php:
+ removed unused 2nd param in call to _parse_var()
+
+ * libs/Smarty_Compiler.class.php:
+ added explanation for $this->_num_const_regexp
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ added escape type "decentity" to smarty_modifier_escape()
+
+ * libs/Smarty_Compiler.class.php:
+ enabled numerical constants be parsed as statements.
+ (like {10} or {10|@range:12} )
+
+ * libs/Smarty_Compiler.class.php:
+ removed unused $smarty_compiler->_dvar_num_var_regexp
+
+ * libs/Smarty.class.php:
+ reverted Stuff
+
+ * libs/debug.tpl
+ libs/core/core.assemble_plugin_filepath.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.write_file.php
+ libs/plugins/function.eval.php
+ libs/plugins/function.popup.php
+ libs/plugins/modifier.escape.php
+ libs/plugins/shared.make_timestamp.php:
+ reverted stuff
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/debug.tpl
+ libs/core/core.assemble_plugin_filepath.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.write_file.php
+ libs/plugins/function.eval.php
+ libs/plugins/function.popup.php
+ libs/plugins/modifier.escape.php
+ libs/plugins/shared.make_timestamp.php:
+ Smarty_Compiler.class.php
+
+2004-04-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/core/core.write_compiled_include.php:
+ made smarty_core_write_compiled_include() php5-aware
+
+ if someone knows a better way than patching the source with the
+ tokenizer, please stand up!
+
+2004-04-14 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/Makefile.in:
+ remove file-entities.ent also
+
+ * docs/.cvsignore
+ docs/Makefile.in
+ docs/README:
+ allow make revcheck
+
+2004-04-13 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/configure.in:
+ do not need inipath
+
+2004-04-13 Mehdi Achour <didou@keliglia.com>
+
+ * docs/TODO:
+ done
+
+ * docs/configure.in
+ docs/manual.xml.in:
+ now the files entites are generated dynamically
+
+2004-04-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php:
+ removed unused functionality to load a subset of lines from a file in
+ Smarty::_read_file()
+
+ additionally removed a warning that is emitted since php-4.3.5 when
+ fread() is called on an empty file (with filesize()==0). thanks to
+ Andreas Streichardt who pointed this out.
+
+ * NEWS
+ libs/core/core.is_secure.php:
+ smarty_core_is_secure() only checks the file for readability now, not
+ the directory where is in.
+
+ * libs/Smarty.class.php:
+ removed unused security_setting 'ALLOW_CONSTANTS'
+
+2004-04-07 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.assign_debug_info.php
+ libs/plugins/function.cycle.php
+ libs/plugins/function.mailto.php:
+ removed trailing spaces
+
+ * libs/Smarty.class.php:
+ removed unused $smarty->_error_msg
+
+2004-04-04 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/configure.in:
+ fixing my crap
+ put build_date back on-line
+
+2004-04-03 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/Makefile.in
+ docs/configure.in
+ docs/manual.xml.in:
+ trying to fix ru problems
+
+2004-03-30 Monte Ohrt <monte@ispi.net>
+
+ * libs/core/core.display_debug_console.php:
+ fix problem with debug_tpl path and security
+
+ * NEWS
+ libs/core/core.display_debug_console.php:
+ fix problem displaying debug console when $default_resource_type is not
+ "file:"
+
+2004-03-29 Mehdi Achour <didou@keliglia.com>
+
+ * docs/TODO:
+ and finally, add a TODO here
+
+ * docs/de/bookinfo.xml
+ docs/de/manual.sgml
+ docs/fr/bookinfo.xml
+ docs/fr/manual.xml:
+ translate bookinfo.xml and put back the translators
+
+2004-03-28 Mehdi Achour <didou@keliglia.com>
+
+ * docs/manual.xml.in:
+ add global.ent and define some general entities
+
+ * docs/de/bookinfo.xml
+ docs/de/getting-started.xml
+ docs/de/language-defs.ent
+ docs/de/preface.xml:
+ add new de files
+
+ * docs/de/appendixes.sgml
+ docs/de/designers.sgml
+ docs/de/getting-started.sgml
+ docs/de/html-common.dsl
+ docs/de/preface.sgml
+ docs/de/programmers.sgml:
+ drop old de files
+
+ * docs/fr/bookinfo.xml
+ docs/fr/getting-started.xml
+ docs/fr/manual.xml
+ docs/fr/preface.xml:
+ add ommited files
+
+ * docs/fr/language-defs.ent:
+ split the french dir
+
+ * docs/fr/appendixes.sgml
+ docs/fr/designers.sgml
+ docs/fr/getting-started.sgml
+ docs/fr/html-common.dsl
+ docs/fr/manual.sgml
+ docs/fr/preface.sgml
+ docs/fr/programmers.sgml:
+ drop old french files
+
+ * docs/manual.xml.in:
+ let's put the new build system
+
+2004-03-26 Mehdi Achour <didou@keliglia.com>
+
+ * docs/de/common.dsl
+ docs/de/html.dsl
+ docs/fr/common.dsl
+ docs/fr/html.dsl
+ docs/fr/php.dsl:
+ not needed anymore
+
+2004-03-24 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/Makefile.in:
+ updated stylesheets
+ highlight PHP automatically
+
+ * docs/Makefile.in
+ docs/html.dsl:
+ remove unneeded file
+
+2004-03-23 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/version.ent.in:
+ remove this also
+
+ * docs/getting-started.sgml:
+ remove this one too
+
+ * docs/appendixes.sgml
+ docs/common.dsl
+ docs/designers.sgml
+ docs/html-common.dsl
+ docs/manual.sgml
+ docs/php.dsl
+ docs/preface.sgml
+ docs/programmers.sgml:
+ removing uneeded files
+
+ * docs/.cvsignore:
+ commiting missing files for docbook
+
+ * docs/.cvsignore
+ docs/Makefile.in
+ docs/configure.in
+ docs/manual.xml.in:
+ bundling docbook 4
+ now make and make web works
+
+2004-03-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.config_load.php:
+ unrolled call to the is_compiled()-check to be able to supply the
+ correct resource_base_path for config_load. this avoids errors when
+ config-files are accessed where security is enabled.
+
+ thanks to shuther for pointing out this bug.
+
+2004-03-20 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/manual.xml.in:
+ fix build date
+
+2004-03-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.is_secure.php:
+ removed merging of $smarty->template_dir into $smarty->secure_dir
+
+ the resource_base_path is considerd secure instead. this change should
+ have absolutely no impact on smarty's security's behaviour
+
+2004-03-18 Nuno Lopes <nunoplopes@sapo.pt>
+
+ * docs/configure.in:
+ correcting non-existent var
+
+ * docs/.cvsignore
+ docs/Makefile.in
+ docs/configure.in
+ docs/manual.xml.in
+ docs/version.ent.in:
+ generate build date
+
+ * docs/.cvsignore
+ docs/Makefile.in
+ docs/README
+ docs/configure.in
+ docs/manual.xml.in:
+ new build/test system
+
+2004-03-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ moved setting of a default resource_base_path from
+ Smarty::_parse_resource_name() to Smarty::_fetch_resource_info()
+
+ this shouldn't affect anything, since all calls to
+ _parse_resource_name() that are not done from within
+ _fetch_resource_info() all pass their own resource_base_path
+
+2004-03-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ removed '.' from the list of default resource_base_paths in
+ _parse_resource_name()
+
+ this should only affect _parse_resource_name() for templates, not for
+ php-resources and not for config_files. the latter pass two their own
+ resource_base_path.
+
+2004-03-16 Mehdi Achour <didou@keliglia.com>
+
+ * docs/appendixes.sgml
+ docs/getting-started.sgml
+ docs/preface.sgml:
+ adding editor comments
+
+ * docs/appendixes.sgml
+ docs/getting-started.sgml:
+ cleaning words spacing, killing tabulations, using roles for
+ programlisting..
+
+2004-03-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ simplified Smarty::clear_all_cache();
+
+2004-03-12 boots <jayboots@yahoo.com>
+
+ * docs/programmers.sgml:
+ Updated is_cached prototype to indicate proper return type. (thanks to
+ Geoffrey Hoffman)
+
+2004-03-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.assemble_plugin_filepath.php:
+ fixed little bug that prevented plugins filepaths that are found in
+ php's include_path (and not in one of the plugins_dirs) from being
+ cached in the internal plugins-filepath-cache
+
+2004-03-01 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ update include_php docs:wq
+ :q
+
+ * docs/appendixes.sgml:
+ update componentized template example to something useful
+
+2004-02-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ _parse_resource_name() returned true on non-existant absolute
+ paths. This caused a warning on _fetch_resource_info() when used in
+ conjunction with template_exists(). It should be fixed now without
+ negative effects.
+
+2004-02-24 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ one more typo
+
+ * docs/designers.sgml:
+ fix typo
+
+2004-02-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/core/core.is_secure.php:
+ smarty_resource_*_secure got &$smarty passed errornously as 3rd
+ parameter and not as 2nd. this is fixed.
+
+2004-02-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS:
+ fix handling of integer values like width and delay im
+ smarty_function_popup()
+
+ * libs/plugins/function.popup.php:
+ fixed handling of integer-attributes
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ updated version to 2.6.3-dev
+
+2004-02-22 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_select_date.php:
+ removed notice on html_select_date with the month_empty-attribute
+
+ * libs/plugins/function.mailto.php:
+ removed 2 notices of undefined vars (thanks Cit)
+
+2004-02-17 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ add header
+
+ * (Smarty_2_6_2)
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ change some info in headers, remove fluff
+
+2004-02-13 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ correctly handle partially empty dates (like "2004--" or "-12-").
+
+ * docs/programmers.sgml:
+ learned something about <note> and sgml and applied this to the
+ use.sub.dirs-section :)
+
+ * docs/designers.sgml:
+ changed attribute-name "checked" to "selected" in the docs for
+ html_radios and html_checkboxes. "checked" is deprecated for ages
+ AFAIK and selected is recommended for consistency with {html_options}
+
+ * docs/programmers.sgml:
+ added note about use_sub_dirs and Smarty-2.6.2 .
+ fixed markup for section about clear_compiled_tpl() .
+
+2004-02-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Config_File.class.php:
+ YES and NO should not be booleanized inside triple-quotes in a
+ config-file. this behaviour changed by accident in 2.6.1 and is now
+ reverted to pre-2.6.1 behaviour
+
+2004-02-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Config_File.class.php:
+ fixed slurping of a the next line following a triple-quoted value in a
+ config-file
+
+2004-02-07 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php:
+ avoid @-operator for handling empty lines in Config_File.class.php
+
+ * libs/Smarty_Compiler.class.php:
+ removed two notices from Smarty_Compiler::_parse_is_expr()
+ (thanks shuther!)
+
+ * NEWS
+ libs/Smarty.class.php:
+ changed default for use_sub_dirs to false
+
+ * libs/plugins/function.mailto.php:
+ removed notice of undefined variable. (thanks shuther!)
+
+2004-01-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ added file and line-number-information to error-messages regarding
+ assigned objects an an error messages regarding modifiers with
+ security.
+
+2004-01-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ removed use of temporary var $_params in compiled code of block-plugins
+
+ * NEWS
+ libs/plugins/function.popup.php:
+ fixed quoting of values in smarty_function_popup()
+
+2004-01-25 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/programmers.sgml:
+ documented parameters of Smarty::clear_compiled_tpl()
+
+ * libs/Smarty_Compiler.class.php:
+ Smarty_Compiler::_syntax_error() uses Smarty::_trigger_fatal_error() now
+ instead of the trigger_error()-function
+
+ * libs/Smarty.class.php:
+ Smarty::_trigger_fatal_error() uses Smarty::trigger_error() now,
+ instead of the native trigger_error()-function
+
+ * libs/Smarty_Compiler.class.php:
+ unrecognized custom-functions trigger an error at compile now, not at
+ display-time.
+
+2004-01-23 Monte Ohrt <monte@ispi.net>
+
+ * docs/getting-started.sgml:
+ reword a paragraph
+
+2004-01-22 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.config_load.php:
+ removed emission of unnecessary notices for unavailable config-files
+ in config_load()
+
+ * NEWS
+ libs/Config_File.class.php:
+ fixed handling of hidden sections in Config_File
+
+2004-01-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.config_load.php:
+ added handling of resources for {config_load}
+
+2004-01-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_table.php:
+ fixed bug when using arrays with tr_attr and td_attr in {html_table}
+
+2004-01-16 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ add unit testing
+
+ * NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers, add initial unit test directory
+
+ * (Smarty_2_6_1)
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers for 2.6.1 release
+
+2004-01-16 Messju Mohr <messju@lammfellpuschen.de>
+
+ * (Smarty_2_6_1)
+ NEWS
+ docs/programmers.sgml
+ libs/Smarty.class.php:
+ renamed $smarty->tpl_rror_reporting to $smarty->error_reporting
+ "tpl_" is a bit redundant here (it's a TemPLate-engine overall :)
+
+2004-01-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_image.php:
+ forgot to remove duplicate is_secure()-check
+
+ * NEWS
+ libs/plugins/function.html_image.php:
+ fix: $smarty->security is now correctly handled
+
+ minor optimizations:
+ core/core.is_secure.php is only included when needed
+ $dpi_default is only determined when needed
+
+2004-01-14 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/appendixes.sgml
+ docs/programmers.sgml:
+ removed suggestions to use extract() from the manual
+
+ * docs/designers.sgml:
+ fixed typo
+
+2004-01-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ mention SCRIPT_NAME below {$smarty} reserved variable because it got
+ lost in the docs for $smarty->global_assign
+
+ * docs/designers.sgml:
+ added docs for {$smarty.version} special variable
+
+ * docs/programmers.sgml:
+ removed docs for $global_assign
+
+ * docs/programmers.sgml:
+ added docs for tpl_error_reporting
+
+ * docs/designers.sgml:
+ added docs for year_empty-, month_empty- and day_emtpy-attributes of
+ html_select_date. maybe an example is needed to better explain empty
+ values in YYY-MM-DD.
+
+2004-01-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed handling of {php}-tags
+
+2004-01-10 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ fix html_checkboxes examples
+
+2004-01-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/core/core.assemble_plugin_filepath.php:
+ added caching of requested paths to smarty_core_assemble_plugin_filepath()
+
+ * NEWS:
+ fix handling of comments inside {php}- and {literal}-blocks
+
+ * libs/Smarty_Compiler.class.php:
+ fixed handling of comments inside {php} and {literal}
+
+2004-01-06 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Config_File.class.php:
+ fixed bug handling triple-quotes in config-files
+
+ * libs/Config_File.class.php:
+ fixed bugs with triple-quotes in config-files
+ thanks BRDude for finding them testing!
+
+2004-01-02 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ removed unnecessary param in call to _fetch_resource_info()
+
+2003-12-30 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ oops! removed tabs.
+
+2003-12-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ made $SCRIPT_NAME available again
+ changes default for request_use_auto_global to prefer autoglobals
+
+ * libs/Smarty.class.php:
+ removed tabs and trailing spaces
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ readded default_modifiers. who removed that?
+
+2003-12-23 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ add portuguese docs
+
+2003-12-22 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ fix counter example
+
+2003-12-19 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php:
+ add debug console persistance feature
+
+2003-12-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/block.textformat.php
+ libs/plugins/function.html_table.php
+ libs/plugins/function.popup.php:
+ removed extract(). enhanced parameter parsing.
+
+ * libs/plugins/function.counter.php
+ libs/plugins/function.fetch.php
+ libs/plugins/function.popup_init.php
+ libs/plugins/modifier.capitalize.php
+ libs/plugins/modifier.cat.php
+ libs/plugins/modifier.date_format.php
+ libs/plugins/modifier.debug_print_var.php
+ libs/plugins/modifier.escape.php
+ libs/plugins/modifier.indent.php
+ libs/plugins/modifier.lower.php
+ libs/plugins/modifier.nl2br.php
+ libs/plugins/modifier.strip.php
+ libs/plugins/modifier.upper.php
+ libs/plugins/modifier.wordwrap.php
+ libs/plugins/outputfilter.trimwhitespace.php
+ libs/plugins/shared.escape_special_chars.php:
+ removed tabs. fixed indentiation.
+
+ * libs/plugins/modifier.truncate.php:
+ removed tabs
+
+ * libs/plugins/function.counter.php
+ libs/plugins/function.cycle.php:
+ removed extract() from parameter-parsing
+
+2003-12-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_select_date.php:
+ fix plugin-name in error message
+
+ * libs/plugins/function.html_select_time.php:
+ remove extract-call from {html_select_time}
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ allow single-digit days and months without smarty_make_timestamp()
+ this makes dates like "1968-11-6" work correctly since no strtotime()
+ is involved
+
+ add warning when unknown parameter is passed
+
+2003-12-16 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ fix headers sent erroneously with cache_modified_check and fetch()
+
+2003-12-12 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/function.config_load.php:
+ move set_path() call below the conditional bracket
+
+ * NEWS
+ libs/plugins/function.config_load.php:
+ fix config_load filepath bug
+
+2003-12-12 boots <jayboots@yahoo.com>
+
+ * docs/designers.sgml:
+ Updated language.function.if with additional annotation and to fix error
+ that broke docs build process
+
+2003-12-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ little optimization for "is odd" and "is even"
+
+2003-12-11 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix 'is even by' and 'is odd by' logic
+
+2003-12-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ update example-output of {mailto}
+
+ * libs/plugins/function.mailto.php:
+ removed extract-call -> cleaner parameter-handling
+
+ * libs/plugins/function.mailto.php:
+ fixed indentiation
+
+ * TODO:
+ removed two done topics
+
+2003-12-11 boots <jayboots@yahoo.com>
+
+ * docs/designers.sgml:
+ Updated language.function.if to describe qualifiers (thanks andre)
+
+2003-12-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_select_date.php:
+ added day_empty, month_empty, year_empty and all_empty attributes
+ to pass an undefined date use {html_select_date time="--" ...}
+
+ * libs/plugins/function.html_select_date.php:
+ removed extract()-call
+
+ * libs/plugins/function.html_select_date.php:
+ fixed indetiation
+
+2003-12-10 boots <jayboots@yahoo.com>
+
+ * NEWS
+ docs/designers.sgml:
+ Added table to language.function.if to describe qualifiers
+
+2003-12-09 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_options.php:
+ strict comparason didn't work in all cases. use type-casting now.
+
+ * NEWS
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_options.php:
+ fix bug when comparing array-keys to "selected" in html_options and
+ html_checkboxes
+
+ in_array() uses "strict" comparason now.
+
+ * libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_radios.php:
+ removed tabs, fixed indentiation
+
+2003-12-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ add better checks for correctly nested tags when compiling
+
+2003-12-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/plugins/function.html_image.php:
+ fix: check $smarty->request_use_auto_globals at the last occurences of
+ HTTP_*_VARS
+
+2003-12-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ remove $global_assign property from Smarty and $global_assign-handling
+ from the constructor. the only visible change is, that $SCRIPT_NAME is
+ not available in the tempates anymore. $smarty.server.SCRIPT_NAME has
+ to be used from now.
+
+2003-12-03 boots <jayboots@yahoo.com>
+
+ * docs/designers.sgml:
+ Fixed example for count_characters
+
+2003-12-01 boots <jayboots@yahoo.com>
+
+ * docs/designers.sgml:
+ Added section "Escaping Smarty Parsing" under Basic Syntax.
+
+2003-12-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.create_dir_structure.php:
+ thought again about my latest commit and backed it out.
+
+ * libs/core/core.create_dir_structure.php:
+ fix root-dir-handling on windows filepath
+
+2003-11-29 boots <jayboots@yahoo.com>
+
+ * libs/plugins/function.config_load.php:
+ really make the fixes the last patch was supposed to do
+
+ * libs/plugins/function.config_load.php:
+ removed tabs and killed trailing white-space
+
+ * libs/plugins/function.config_load.php:
+ changed $smarty->_syntax_error to $smarty->trigger_error
+
+2003-11-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/modifier.debug_print_var.php:
+ remove warning in debug_print_var on php-resources
+
+ * README:
+ fix version number
+
+2003-11-26 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ raise max_level for $smarty.config... to 3 to allow arrays of config-vars
+
+2003-11-25 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ changed version-tag to indicate incompatibility to older compiled
+ templates
+
+2003-11-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/compiler.assign.php
+ libs/plugins/function.assign.php:
+ move function.assign.php to compiler.assign.php
+
+ * libs/core/core.get_include_path.php:
+ silence occasional warnings of open_basedir- and
+ safe_mode-restrictions in core.get_include_path.php
+
+2003-11-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.write_compiled_resource.php
+ libs/core/core.write_file.php:
+ avoid touch()-ing of recently unlinked files by touch()-ing the
+ tempfile before rename instead of touch()-ing the resulting file after
+ rename.
+
+ * NEWS
+ libs/Smarty.class.php:
+ add property $tpl_error_reporting
+
+2003-11-22 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.assign.php:
+ remove use of extract() in smarty_function_assign()
+
+ * NEWS
+ libs/Smarty.class.php:
+ remove property $undefined. "null" is used literally instead
+
+2003-11-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ remove two E_NOTICES
+
+2003-11-20 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ change version to 2.6.1-dev
+
+2003-11-19 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_6_0)
+ NEWS:
+ update NEWS file
+
+ * (Smarty_2_6_0)
+ docs/designers.sgml
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ change version numbers to 2.6.0
+
+2003-11-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml
+ docs/de/designers.sgml
+ docs/fr/designers.sgml:
+ fix examples of escape-modifier (in docs, docs/de and docs/fr !)
+
+2003-11-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ move Smarty::quote_replace() to Smarty_Compiler::_quote_replace()
+
+ * libs/Smarty.class.php:
+ removed extract-calls from _include()- and _eval()-wrappers
+ variables passed with {include_php} have to accessed as members of $params
+ now
+
+2003-11-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ fixed typo
+
+2003-11-13 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php:
+ fix occasional notice
+
+2003-11-13 andreas halter <phpcvs@andreashalter.ch>
+
+ * docs/de/designers.sgml:
+ - added cat modifier, thanks messju :-)
+
+2003-11-13 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_6_0-RC3)
+ NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ commit RC3 tags
+
+2003-11-13 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix handling of $var.key inside []
+
+ * libs/Smarty.class.php:
+ fix unnecessary loading of core.load_resource_plugin.php
+
+ * (Smarty_2_6_0-RC3)
+ docs/fr/designers.sgml:
+ fixed example of html_table
+
+2003-11-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/core/core.process_cached_inserts.php:
+ fix handling of assign inside {insert}-tags
+
+2003-11-06 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.read_cache_file.php:
+ added $exp_time-parameter
+
+ * docs/programmers.sgml:
+ added $exp_time to cache_handler_func-example
+
+ * libs/Smarty.class.php
+ libs/core/core.write_cache_file.php:
+ added $exp_time-parameter of clear_cache() and clear_all_cache() to
+ cache_handler_func.
+
+2003-11-05 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Config_File.class.php:
+ fix handling if [...] inside triple-quotes in config-files
+
+2003-11-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ fixed little bug in _parse_resource_name() (jlgunter, messju)
+
+2003-11-03 andreas halter <phpcvs@andreashalter.ch>
+
+ * docs/designers.sgml
+ docs/de/designers.sgml
+ docs/fr/designers.sgml:
+ - changed Smarty.php.class occurences to Smarty.class.php
+
+2003-10-29 boots <jayboots@yahoo.com>
+
+ * docs/appendixes.sgml
+ docs/designers.sgml
+ docs/manual.sgml
+ docs/programmers.sgml
+ docs/de/appendixes.sgml
+ docs/de/designers.sgml
+ docs/de/programmers.sgml
+ docs/fr/appendixes.sgml
+ docs/fr/designers.sgml
+ docs/fr/getting-started.sgml
+ docs/fr/manual.sgml
+ docs/fr/preface.sgml
+ docs/fr/programmers.sgml:
+ Fixes to documentation syntax so that all content can be processed used
+ xsltproc docbook-xsl tools. In particular, fixes unescaped entities,
+ broken tags, unquoted attributes.
+
+2003-10-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix handling of simple-math-operators inside modifiers
+
+2003-10-25 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ removed unused property _output_type
+ removed unused param $tag_attrs of _parse_var_props()
+ cleaned up alignment of class-properties
+
+2003-10-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ removed notice in php-tag handling in Smarty_Compiler::_compile_file()
+
+ * libs/Smarty_Compiler.class.php:
+ removed two occasional E_NOTICES from
+ Smarty_Compiler::_compile_include_php_tag()
+
+ * NEWS
+ libs/core/core.create_dir_structure.php:
+ fix handling of trailing-slashes in open_basedir in
+ smarty_core_create_dir_structure()
+
+2003-10-20 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ elements inside `` are bracketed now inside the compiled-tpl. this
+ fixes some issues with simple-math inside backticks.
+
+2003-10-16 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ update overlib docs, no working examples
+
+2003-10-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/core/core.is_secure.php:
+ move check for template_dir in secure_dir-array into core.is_secure.php
+
+ this makes template_exists() work correctly with security=true even if
+ template_dir is not inside the secure_dir-array
+
+2003-10-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/shared.make_timestamp.php:
+ tightened check for YYYYMMDDHHMMSS-format. thanks konstantin for
+ pointing this out.
+
+ removed a few tabs.
+
+ * libs/Smarty_Compiler.class.php:
+ fix precedence of simple-math-operators before modifiers.
+ thanks dominik!
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.assemble_plugin_filepath.php
+ libs/core/core.assign_smarty_interface.php
+ libs/core/core.create_dir_structure.php
+ libs/core/core.display_debug_console.php
+ libs/core/core.get_include_path.php
+ libs/core/core.get_microtime.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.is_secure.php
+ libs/core/core.is_trusted.php
+ libs/core/core.load_plugins.php
+ libs/core/core.load_resource_plugin.php
+ libs/core/core.process_cached_inserts.php
+ libs/core/core.process_compiled_include.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.rm_auto.php
+ libs/core/core.rmdir.php
+ libs/core/core.run_insert_handler.php
+ libs/core/core.smarty_include_php.php
+ libs/core/core.write_compiled_include.php
+ libs/core/core.write_compiled_resource.php
+ libs/core/core.write_file.php:
+ removed tabs from the main and the core/*.php files
+
+2003-10-08 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_6_0-RC2)
+ NEWS
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ update version numbers to RC2
+
+2003-09-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml
+ docs/de/designers.sgml:
+ fixed description of cycle's advance-attribute
+
+2003-09-16 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ apply modifiers only once to section-loop and foreach-from attributes
+
+2003-09-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.write_cache_paths_file.php:
+ backed out _smarty_cached_paths-file-handling
+
+ * libs/Smarty.class.php
+ libs/core/core.rm_auto.php:
+ fixed clear_compiled_tpl with explicit $tpl_file given
+ fixed return value of smarty_core_rm_auto() + Smarty::_unlink()
+
+ * libs/Smarty.class.php:
+ little fix in _get_auto_filename()
+
+2003-09-14 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/core/core.assemble_auto_filename.php:
+ removed auto-filenames from path-cache. merged assemble_auto_filename
+ back into Smarty::_get_auto_filename()
+
+2003-09-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed quoting of modifier parameters
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.load_plugins.php
+ libs/core/core.load_resource_plugin.php:
+ remove Smarty::_plugin_implementation_exists() - use php's native
+ is_callable()
+
+2003-09-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ silenced two notices acces HTTP_SERVER_VARS
+
+2003-09-10 andreas halter <phpcvs@andreashalter.ch>
+
+ * docs/de/designers.sgml
+ docs/de/getting-started.sgml
+ docs/de/programmers.sgml:
+ - minor fixes (2 rep), slight wording changes
+ - jade transform problem fixed
+
+2003-09-08 andreas halter <phpcvs@andreashalter.ch>
+
+ * docs/de/designers.sgml
+ docs/de/getting-started.sgml
+ docs/de/manual.sgml
+ docs/de/preface.sgml
+ docs/de/programmers.sgml:
+ all updated for 2.6.0 release, translated everything from 2_5_0 branch to
+ 20030908
+
+2003-09-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ proper checking for files in _fetch_resource_info()
+
+2003-09-02 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ ignore {strip}/{/strip) inside {strip}-blocks
+
+ * libs/plugins/function.mailto.php:
+ fixed 2 notices in smarty_function_mailto()
+
+2003-09-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ re-include cache_paths on multiple calls to fetch() to avoid
+ inconsistencies
+ at multiple calls to fetch() in one script
+
+ * libs/Smarty_Compiler.class.php:
+ fixed handling of \r in {strip}
+ renamed $_trailing_lf to $_additional_newline
+
+ * libs/Smarty_Compiler.class.php:
+ the weekly fix for {strip} :)
+
+ * docs/designers.sgml:
+ fixed example for simple math.
+
+2003-08-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.assign_smarty_interface.php
+ libs/core/core.display_debug_console.php
+ libs/plugins/function.assign.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_table.php:
+ fixed PHPDocumentor-comments (thanks Konstantin)
+
+ * libs/core/core.rmdir.php:
+ made rmdir a bit more optimistic. especially it now removes
+ directories correctly that where created accidently by "safe_mode=On
+ && $use_sub_dirs=true"
+
+2003-08-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed removal of leading/trailing newlines in {strip}-blocks
+
+2003-08-25 Messju Mohr <messju@lammfellpuschen.de>
+
+ * INSTALL:
+ added note emphasizing the introduction of "libs/" with 2.5.0
+
+ * NEWS
+ libs/plugins/modifier.escape.php:
+ fixed proper escaping of " and ' with escape:javascript
+
+2003-08-22 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/core/core.assemble_plugin_filepath.php:
+ fixed bug in traversal of $smarty->plugins_dir-array in
+ smarty_core_assemble_plugin_filepath(). the first matching plugin in
+ the path should be used, not the last one.
+
+ * libs/core/core.read_cache_file.php:
+ discard $_cache_info when the cache should be regenerated
+
+2003-08-20 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php
+ libs/plugins/block.strip.php:
+ reverted {strip} from a block-plugin back into the compiler
+
+ * docs/programmers.sgml:
+ fixed examples for register_function() and register_block()
+
+ * libs/Smarty.class.php:
+ made template_exists() quiet when the template does not exist (thanks
+ to konstatin for pointing this out)
+
+2003-08-18 Monte Ohrt <monte@ispi.net>
+
+ * docs/getting-started.sgml:
+ fix example title
+
+ * docs/README
+ docs/getting-started.sgml:
+ change installation wording confusion
+
+2003-08-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/core/core.read_cache_file.php:
+ fixed unnecessary load of source in template_exists() and the
+ compile-check of smarty_core_read_cache_file()
+
+ * libs/Smarty_Compiler.class.php:
+ allow section-, array- and object-dereference in $smarty-references
+
+2003-08-15 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ added parameter-descriptions for count_characters (thanks Konstantin
+ A. Pelepelin)
+
+ fixed docs for {html_checkboxes}
+
+2003-08-14 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/core/core.read_cache_file.php:
+ fixed timestamp-check of config-files in smarty_core_read_cache_file()
+
+ * libs/Smarty.class.php:
+ fixed typecasting for arrays in _parse_resource_name()
+
+ * NEWS
+ libs/plugins/function.config_load.php:
+ fixes in config_load:
+ - handling of section-attribute
+ - reusing the same config-file multiple times
+ - serialization of config-data for php<4.2.0 (no var_export)
+
+ many thanks to atu for pointing this out and for testing
+
+2003-08-13 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/core/core.smarty_include_php.php:
+ fixed problem with vars as attributes in {include_php}
+
+2003-08-13 Monte Ohrt <monte@ispi.net>
+
+ * docs/README:
+ commit README file for documentation compiling
+
+2003-08-13 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/debug.tpl
+ libs/plugins/modifier.debug_print_var.php:
+ removed '\r' from debug_print_vars' output
+ properly escape vars in javascript-version of debug.tpl
+
+2003-08-11 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_6_0_RC1)
+ NEWS
+ docs/designers.sgml
+ docs/html.dsl
+ docs/php.dsl
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ get ready for 2.6.0-RC1 release
+
+2003-08-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ fixed status-header for cache_modified_check under cgi-sapi
+
+2003-08-09 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.is_secure.php
+ libs/core/core.is_trusted.php:
+ synced secure_dir-checking with trusted_dir-checking
+
+ * libs/core/core.is_secure.php:
+ tightenend path checking in smarty_core_is_secure()
+
+2003-08-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ fix: proper nesting of $smarty->_cache_including flag in cascaded
+ cached/not-cached/fetched/inserted/foo-templates
+
+ * libs/debug.tpl:
+ better escaping for $_debug_tpls[templates].filenames
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ removed redundant $smarty from Smarty::_smarty_include()
+
+ * libs/debug.tpl:
+ proper escaping of filenames in debug-console (thanks to prossel).
+
+2003-08-07 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/programmers.sgml:
+ added docs for block-methods of registered objects
+
+ * docs/programmers.sgml:
+ fixed typo in example for registered objects
+
+ * docs/designers.sgml:
+ fixed exampls of html_image and html_checkboxes
+
+ * libs/plugins/function.debug.php:
+ fixed {debug} and removed tabs in function.debug.php
+
+ * docs/programmers.sgml:
+ fixed example for register_object
+
+ * docs/designers.sgml
+ docs/programmers.sgml:
+ updated docs for capture, html_table, html_image and register_object
+
+2003-08-07 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ docs/programmers.sgml:
+ add math and default_resource_type to docs
+
+ * docs/getting-started.sgml:
+ add core to example, add tech note
+
+2003-08-07 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/manual.sgml
+ docs/fr/manual.sgml:
+ upd copyright in the docs
+
+2003-08-07 Monte Ohrt <monte@ispi.net>
+
+ * docs/getting-started.sgml:
+ added core directory to install instructions
+
+2003-08-07 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml
+ docs/programmers.sgml:
+ added docs for php-functions as modifiers
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ better caching of attributes for $cacheable=false-plugins
+
+ * docs/programmers.sgml:
+ added section "caching.cacheable" to the docs, explaining the usage of
+ the $cacheable-flag of the register_(block|compiler|function)-functions
+
+ * libs/Smarty_Compiler.class.php:
+ fixed output of custom-functions with cached attributes
+
+ * docs/programmers.sgml:
+ docs update on callbacks to the register_*-functions
+
+2003-08-06 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.process_compiled_include.php:
+ added optional parameter $cache_attrs to register_function() and
+ register_block(). $cache_attrs is an array containing attribute- names
+ that should be cached on calls to functions that have $cacheable set
+ to false.
+
+ * libs/Smarty.class.php:
+ fixed bug in _run_mod_handler
+
+ * libs/Smarty_Compiler.class.php:
+ fixed bug with autoload-handling of modifiers. thanks ándre.
+
+2003-08-05 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ updated copyright notice
+
+ * libs/Smarty.class.php
+ libs/core/core.load_plugins.php:
+ fixed bug that occurred when using the same not-cacheable plugin in
+ multiple includes
+
+ * docs/programmers.sgml:
+ docs-update for plugins.writing
+
+2003-08-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml
+ docs/programmers.sgml:
+ updated docs for register_block_function(), block-functions,
+ $request_use_auto_globals and html_checkboxes
+
+2003-07-31 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ enabled registration of class-methods as callbacks for the
+ register_*-functions
+
+ use: array('classname', 'method_name')) as callback
+
+2003-07-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ modifiers are resolved at compile-time now. _run_mod_handler() is
+ still used for modifiers with map_array=true (== no preceeding '@')
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.smarty_include.php:
+ moved _smarty_include() back into Smarty.class.php
+
+ * libs/Smarty.class.php
+ libs/core/core.load_plugins.php:
+ prevent unnecessary calls to _read_file() in _is_compiled()
+ converted method-call to internal function-call in
+ smarty_core_load_plugins()
+
+2003-07-28 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ quote smarty-header properly to prevent resource-names from escaping from
+ the comment
+
+2003-07-25 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.create_dir_structure.php:
+ weakend race-condition and removed bogus error-message caused by that
+ in smarty_core_create_dir_structure().
+
+2003-07-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/core/core.display_debug_console.php
+ libs/core/core.fetch_resource_info.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.parse_resource_name.php
+ libs/core/core.process_cached_inserts.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.run_insert_handler.php
+ libs/core/core.smarty_include.php
+ libs/core/core.smarty_include_php.php
+ libs/plugins/function.eval.php:
+ moved _fetch_resource_info and _parse_resource_name back into
+ Smarty.class.php
+ renamed smarty_include and smarty_eval wrappers to _include and _eval
+
+2003-07-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.process_compiled_include.php
+ libs/core/core.read_cache_file.php:
+ improved checking of compiled_include against cached-template with
+ non-cached-chunks
+
+ * libs/core/core.write_compiled_include.php:
+ fixed too short open-tag
+
+ * libs/plugins/function.eval.php:
+ fixed assign parameter for eval (must have gotton lost on its way to 2.5.0)
+ cleaned up indentiation
+
+2003-07-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ resurrected $foo->$bar syntax
+
+ * libs/Smarty_Compiler.class.php:
+ i'm so stupid. kick me.
+
+ * libs/Smarty_Compiler.class.php:
+ fixed initialisation of $this->_plugins in compile_block_tag()
+
+2003-07-03 Monte Ohrt <monte@ispi.net>
+
+ * libs/Config_File.class.php:
+ add preg_quote delimiter
+
+2003-07-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ applied fix for {$var1->p1|modifier:$var2->p2}-syntax - thanks Dominik
+
+2003-07-02 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed duplicate generation of arg-list in _compile_block_tag()
+
+ * libs/Smarty_Compiler.class.php:
+ fixed off-by-one-error in nocache-tag-handling
+
+2003-06-30 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ backed out errornously committed support for $foo->$bar
+
+ * libs/core/core.write_file.php:
+ fixed indentiation, silenced occasional warning
+
+ * libs/plugins/function.html_image.php:
+ match first character of file-attribute against "/" instead of
+ DIRECTORY_SEPARATOR since it is a url-path and not a file-path.
+
+ * libs/Smarty_Compiler.class.php
+ libs/core/core.write_file.php
+ libs/plugins/function.html_image.php:
+ libs/plugins/function.html_image.php
+
+ * libs/Smarty_Compiler.class.php:
+ re-fixed cacheable_state-handling
+
+ * libs/core/core.display_debug_console.php
+ libs/core/core.process_cached_inserts.php
+ libs/core/core.process_compiled_include.php
+ libs/core/core.run_insert_handler.php:
+ extincting $this out of smarty_core_*-functions
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ fixed handling of nocache-state
+
+2003-06-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/core/core.smarty_include.php
+ libs/core/core.smarty_include_php.php
+ libs/plugins/function.eval.php:
+ removed $this from smarty_include and smarty_include_php
+ added cleaner handling of $this to {eval}
+
+ * libs/core/core.load_resource_plugin.php:
+ fixed inlude_once-call
+
+ * docs/de/designers.sgml
+ docs/fr/designers.sgml:
+ fixed examples of html_radios and html_checkboxes in german and french docs
+
+2003-06-25 Monte Ohrt <monte@ispi.net>
+
+ * libs/core/core.assemble_auto_filename.php
+ libs/core/core.write_cache_paths_file.php:
+ fix typo, fix write_cache_paths logic
+
+ * libs/Smarty.class.php
+ libs/core/core.assemble_auto_filename.php:
+ fix SMARTY_COMPILE_DIR_SEP problem, make local var
+
+2003-06-24 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php
+ libs/core/core.assemble_auto_filename.php
+ libs/core/core.write_cache_paths_file.php:
+ fixed cache_paths bug, simplified filename assembly logic
+
+2003-06-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.html_image.php:
+ added parsing of forgotton param "basedir"
+
+ * libs/Smarty_Compiler.class.php:
+ fixed $smarty.get-reference
+
+ * libs/plugins/block.textformat.php:
+ removed warning
+
+ * libs/Smarty_Compiler.class.php:
+ fixed value of _cacheable_state on compiler-startup
+
+2003-06-23 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.write_cache_paths_file.php:
+ make cache_path per resource, fix a couple directory path issues
+
+2003-06-23 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ removed warning when compiling empty template
+
+ * libs/core/core.write_compiled_include.php:
+ fixed bug in write_compiled_include
+
+ * libs/core/core.assemble_plugin_filepath.php:
+ fixed warning
+
+2003-06-22 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.eval.php:
+ fixed propagation of $this into evald code in smarty_function_eval()
+
+ * libs/core/core.write_cache_paths_file.php
+ libs/core/core.write_compiled_include.php:
+ fix in compiled-include-handling
+
+ * libs/core/core.assemble_auto_filename.php
+ libs/core/core.assemble_plugin_filepath.php
+ libs/core/core.assign_smarty_interface.php
+ libs/core/core.create_dir_structure.php
+ libs/core/core.fetch_resource_info.php
+ libs/core/core.get_include_path.php
+ libs/core/core.get_microtime.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.is_secure.php
+ libs/core/core.is_trusted.php
+ libs/core/core.load_plugins.php
+ libs/core/core.load_resource_plugin.php
+ libs/core/core.parse_resource_name.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.rm_auto.php
+ libs/core/core.rmdir.php
+ libs/core/core.write_cache_file.php
+ libs/core/core.write_cache_paths_file.php
+ libs/core/core.write_compiled_include.php
+ libs/core/core.write_compiled_resource.php
+ libs/core/core.write_file.php
+ libs/plugins/modifier.date_format.php:
+ started moving from $this to $smarty in core.*.php
+
+2003-06-21 Monte Ohrt <monte@ispi.net>
+
+ * libs/core/core.create_dir_structure.php
+ libs/core/core.write_file.php
+ libs/plugins/function.config_load.php:
+ fix more dir paths
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/core/core.assemble_auto_filename.php
+ libs/core/core.assemble_plugin_filepath.php
+ libs/core/core.fetch_resource_info.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.parse_resource_name.php
+ libs/core/core.process_cached_inserts.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.rm_auto.php
+ libs/core/core.rmdir.php
+ libs/core/core.run_insert_handler.php
+ libs/core/core.smarty_include.php
+ libs/core/core.smarty_include_php.php
+ libs/core/core.write_cache_file.php
+ libs/core/core.write_cache_paths_file.php
+ libs/core/core.write_compiled_include.php
+ libs/core/core.write_compiled_resource.php
+ libs/core/core.write_file.php
+ libs/plugins/function.config_load.php
+ libs/plugins/function.fetch.php
+ libs/plugins/function.html_image.php:
+ fix filepaths to core files to use DIRECTORY_SEPARATOR
+
+2003-06-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed {plugin|modifier} syntax
+
+ * libs/Smarty.class.php
+ libs/core/core.write_compiled_include.php:
+ fixed compiled include handling
+
+2003-06-21 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.assemble_auto_filename.php
+ libs/core/core.assemble_plugin_filepath.php
+ libs/core/core.write_cache_paths_file.php:
+ added filepath caching
+
+2003-06-20 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ update more varnames
+
+ * libs/Smarty.class.php
+ libs/core/core.display_debug_console.php
+ libs/core/core.fetch_file_info.php
+ libs/core/core.fetch_resource_info.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.parse_file_path.php
+ libs/core/core.parse_resource_name.php
+ libs/core/core.process_cached_inserts.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.run_insert_handler.php
+ libs/core/core.smarty_include.php
+ libs/core/core.smarty_include_php.php
+ libs/core/core.write_compiled_resource.php
+ libs/core/core.write_compiled_template.php
+ libs/plugins/function.config_load.php:
+ refactored var naming to better reflect "resource" instead of "file" where
+ appropriate
+
+2003-06-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ updated version-number to 2.5.0-cvs
+
+ * libs/core/core.write_cache_file.php:
+ omit is-cache_dir-writable-check if a cache_handler_function is in use
+
+ * libs/core/core.smarty_include_php.php:
+ fixed comments in smarty_include_php
+
+2003-06-19 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.display_debug_console.php
+ libs/core/core.smarty_include.php
+ libs/plugins/function.eval.php:
+ split up _compile_template to _compile_file and _compile_source, fix eval
+ function
+ VS: ----------------------------------------------------------------------
+
+ * libs/plugins/function.config_load.php:
+ fix logic for _is_compiled()
+
+2003-06-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ added optional assign-attribute to {capture}-tag
+
+ * NEWS
+ libs/Smarty.class.php:
+ added $cacheable-parameter to register_compiler_function()
+
+2003-06-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.load_plugins.php
+ libs/core/core.process_compiled_include.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.write_cache_file.php
+ libs/core/core.write_compiled_include.php:
+ added $cacheable-parameter to register_function() and register_block()
+
+ * libs/Smarty.class.php:
+ append '.php' to all compiled templates regardless of the settings of
+ $use_sub_dirs
+
+ * libs/Smarty.class.php
+ libs/core/core.read_cache_file.php:
+ fixed $file_path-parameters passed to smarty_core_fetch_file_info()
+
+2003-06-17 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ fix name
+
+ * libs/Smarty_Compiler.class.php:
+ change varnames to follow coding methods
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ add math patch to core
+
+2003-06-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/core/core.smarty_include.php:
+ switched _process_template() to _is_compiled()-logic
+
+2003-06-17 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php:
+ fix _is_compiled logic
+
+ * NEWS:
+ update news file
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ fix _run_mod_handler routine
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.display_debug_console.php
+ libs/core/core.fetch_file_info.php
+ libs/core/core.parse_file_path.php
+ libs/core/core.write_compiled_template.php
+ libs/plugins/function.config_load.php:
+ fix path problems, rename some varibles from "template" to "file"
+
+2003-06-16 Monte Ohrt <monte@ispi.net>
+
+ * libs/core/core.fetch_file_info.php
+ libs/core/core.fetch_template_info.php:
+ rename file, commit
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.parse_file_path.php
+ libs/core/core.read_cache_file.php
+ libs/plugins/block.strip.php
+ libs/plugins/block.textformat.php
+ libs/plugins/compiler.config_load.php
+ libs/plugins/function.config_load.php
+ libs/plugins/function.eval.php
+ libs/plugins/function.fetch.php
+ libs/plugins/function.html_image.php:
+ fix config_load, compile fetched arrays to compile_dir, switch display
+ back to runtime. clean up var names and function names, split up compile
+ testing and compiling to separate funcs, rename some template_* functions
+ to
+ file_* functions and update logic so they can be used for file resources
+ other than templates.
+
+2003-06-16 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed little bug in _compile_custom_tag()
+
+2003-06-16 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/core/core.assign_smarty_interface.php
+ libs/core/core.create_dir_structure.php
+ libs/core/core.display_debug_console.php
+ libs/core/core.fetch_template_info.php
+ libs/core/core.get_include_path.php
+ libs/core/core.get_microtime.php
+ libs/core/core.get_php_resource.php
+ libs/core/core.is_secure.php
+ libs/core/core.is_trusted.php
+ libs/core/core.load_plugins.php
+ libs/core/core.load_resource_plugin.php
+ libs/core/core.parse_file_path.php
+ libs/core/core.process_cached_inserts.php
+ libs/core/core.read_cache_file.php
+ libs/core/core.rm_auto.php
+ libs/core/core.rmdir.php
+ libs/core/core.run_insert_handler.php
+ libs/core/core.smarty_include.php
+ libs/core/core.smarty_include_php.php
+ libs/core/core.write_cache_file.php
+ libs/core/core.write_compiled_template.php
+ libs/core/core.write_file.php
+ libs/plugins/core.assign_smarty_interface.php
+ libs/plugins/core.create_dir_structure.php
+ libs/plugins/core.display_debug_console.php
+ libs/plugins/core.fetch_template_info.php
+ libs/plugins/core.get_include_path.php
+ libs/plugins/core.get_microtime.php
+ libs/plugins/core.get_php_resource.php
+ libs/plugins/core.is_secure.php
+ libs/plugins/core.is_trusted.php
+ libs/plugins/core.load_plugins.php
+ libs/plugins/core.load_resource_plugin.php
+ libs/plugins/core.parse_file_path.php
+ libs/plugins/core.process_cached_inserts.php
+ libs/plugins/core.read_cache_file.php
+ libs/plugins/core.rm_auto.php
+ libs/plugins/core.rmdir.php
+ libs/plugins/core.run_insert_handler.php
+ libs/plugins/core.smarty_include.php
+ libs/plugins/core.smarty_include_php.php
+ libs/plugins/core.write_cache_file.php
+ libs/plugins/core.write_compiled_template.php
+ libs/plugins/core.write_file.php:
+ move core files into their own directory under SMARTY_DIR,
+ remove abstraction function _execute_core_function
+
+ * libs/Smarty_Compiler.class.php:
+ fix newline handling for template for all template tags
+
+2003-06-11 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/compiler.config_load.php:
+ add compiler function to cvs repository
+
+2003-06-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ added config-option "request_use_auto_globals" to make auto-globals be
+ used as request vars instead of HTTP_*_VARS
+
+2003-06-11 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/plugins/function.config_load.php:
+ make config vars compile statically
+
+2003-06-11 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ backed out newlines patch
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ removed newlines in compiled templates after closing tags
+
+2003-06-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/de/designers.sgml:
+ fixed german note on html_image and disk-access
+
+2003-06-10 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/core.parse_file_path.php:
+ fix bug with resource_type resolving
+
+2003-06-09 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ replace example with more practical one
+
+2003-06-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ added block-methods for registered objects
+
+2003-06-07 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/programmers.sgml:
+ fixed bug in documentation for $smarty->default_modifiers
+
+2003-06-06 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/core.parse_file_path.php:
+ fix problem with new default_resource_type changes
+
+ * NEWS:
+ update NEWS file info
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/plugins/core.parse_file_path.php:
+ add default_resource_type, ignore 1 char resource names
+
+ * NEWS
+ libs/Config_File.class.php:
+ fix bug where config file starts with hidden section
+
+2003-06-04 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty.class.php:
+ -** empty log message ***
+
+2003-06-03 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/function.html_image.php:
+ fix example in code comments
+
+2003-06-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.counter.php:
+ fixed behaviour of start=... for {counter}
+
+2003-06-02 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.counter.php:
+ fixed assign for {counter}
+
+2003-05-30 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/core.write_cache_file.php
+ libs/plugins/core.write_compiled_template.php:
+ add discrete error checking pertaining to $cache_dir
+ and $compile_dir, their existance and writability
+
+2003-05-28 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_table.php:
+ added params vdir, hdir and inner to html_table to allow looping over
+ the data in various directions
+
+2003-05-28 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/core.compile_template.php
+ libs/plugins/core.display_debug_console.php:
+ fix problem with security and debug.tpl file
+
+2003-05-23 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ upd NEWS file
+
+ * libs/Smarty_Compiler.class.php:
+ allow spaces in literal tags
+
+2003-05-22 Monte Ohrt <monte@ispi.net>
+
+ * docs/fr/programmers.sgml:
+ fix special chars
+
+2003-05-19 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ speed up compiled templates, hardcode plugin filepaths instead of
+ recalculate at runtime
+
+2003-05-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ fixed example of {html_image}
+
+ * docs/designers.sgml:
+ fixed typo
+
+2003-05-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/plugins/core.read_cache_file.php
+ libs/plugins/core.smarty_include.php
+ libs/plugins/function.config_load.php:
+ fixed multiple redundant occurrences for 'config' and 'template' in
+ $smarty->_cache_info
+
+2003-05-10 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/core.create_dir_structure.php:
+ refurbished create_dir_structure to use '/' internally
+
+ * libs/plugins/core.create_dir_structure.php:
+ fixed windows absolute-paths in smarty_core_create_dir_structure()
+
+ * libs/plugins/core.create_dir_structure.php:
+ fixed error-message
+
+2003-05-09 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ fixed warning due to missing param to _execute_core_function()
+
+ * libs/Smarty_Compiler.class.php:
+ fixed quoting in _compile_include_php
+
+ * libs/Smarty_Compiler.class.php:
+ fixed quoting of "file"-parameter in _compile_include_tag()
+
+2003-05-08 Monte Ohrt <monte@ispi.net>
+
+ * docs/programmers.sgml:
+ fix typo
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/plugins/core.compile_template.php
+ libs/plugins/core.create_dir_structure.php
+ libs/plugins/core.fetch_template_info.php
+ libs/plugins/core.get_include_path.php
+ libs/plugins/core.get_microtime.php
+ libs/plugins/core.get_php_resource.php
+ libs/plugins/core.is_secure.php
+ libs/plugins/core.is_trusted.php
+ libs/plugins/core.load_plugins.php
+ libs/plugins/core.load_resource_plugin.php
+ libs/plugins/core.parse_file_path.php
+ libs/plugins/core.process_cached_inserts.php
+ libs/plugins/core.read_cache_file.php
+ libs/plugins/core.rm_auto.php
+ libs/plugins/core.rmdir.php
+ libs/plugins/core.run_insert_handler.php
+ libs/plugins/core.smarty_include.php
+ libs/plugins/core.smarty_include_php.php
+ libs/plugins/core.write_cache_file.php
+ libs/plugins/core.write_compiled_template.php
+ libs/plugins/core.write_file.php
+ libs/plugins/function.config_load.php
+ libs/plugins/function.fetch.php
+ libs/plugins/function.html_image.php:
+ abstract more private functions to plugin directory
+
+ * libs/Config_File.class.php:
+ only add DIRECTORY_SEPARATOR if it isn't already present
+
+ * libs/Config_File.class.php:
+ fix directory separator code, use DIRECTORY_SEPARATOR
+
+2003-05-08 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ fixed example of html_checkboxes
+
+ * NEWS
+ libs/Smarty.class.php:
+ fixed bug in _create_dir_structure() when used with
+ open_basedir-restriction and relative paths
+
+ * docs/designers.sgml:
+ fixed example for html_radios
+
+2003-05-07 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php
+ libs/plugins/core.assign_smarty_interface.php
+ libs/plugins/core.display_debug_console.php
+ libs/plugins/function.display_debug_console.php:
+ abstracted display_debug_console and assign_smarty_interface to plugin dir
+ as a test
+
+ * libs/Smarty.class.php
+ libs/plugins/function.display_debug_console.php:
+ correct misc varnames, abstract debug console display to plugin function
+
+ * libs/plugins/modifier.escape.php:
+ fix typo
+
+2003-05-05 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ add % to math
+
+ * libs/Smarty.class.php:
+ clean up comments, formatting
+
+ * NEWS
+ libs/Smarty.class.php:
+ keep DIR_SEP for 3rd party compatability
+
+ * NEWS
+ libs/Smarty.class.php:
+ remove DIR_SEP, use DIRECTORY_SEPARATOR exclusively
+
+ * libs/Smarty_Compiler.class.php:
+ remove ++ and -- math operators on template vars
+
+2003-05-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty_Compiler.class.php:
+ removed unused parameter $quote from Smarty_Compiler::_parse_attrs()
+
+ * libs/plugins/function.html_image.php:
+ fixed DIR_SEP in html_image-plugin
+
+2003-05-04 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty.class.php:
+ rename DIR_SEP to SMARTY_DIR_SEP to avoid varname collisions
+
+2003-05-04 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_image.php:
+ changed "link" to "href" in html_image. "link" is still working but
+ deprecated
+ html_image always renders an alt-tag now (default alt="")
+ cleaned up indentiation of function.html_image.php
+
+2003-05-03 Monte Ohrt <monte@ispi.net>
+
+ * libs/debug.tpl:
+ fix typo
+
+2003-05-02 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.counter.php:
+ fixed assign attribute for multiple counters
+
+2003-05-02 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ allow math on negative number
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ added simple math operators to variables
+
+2003-05-02 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ fixed typos
+
+2003-04-30 Monte Ohrt <monte@ispi.net>
+
+ * docs/fr/appendixes.sgml
+ docs/fr/common.dsl
+ docs/fr/designers.sgml
+ docs/fr/getting-started.sgml
+ docs/fr/html-common.dsl
+ docs/fr/html.dsl
+ docs/fr/manual.sgml
+ docs/fr/php.dsl
+ docs/fr/preface.sgml
+ docs/fr/programmers.sgml:
+ add frech docs to cvs repository
+
+2003-04-29 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ reverted patch for case-insensitive tag-names
+
+2003-04-28 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/programmers.sgml:
+ reverted back to humerous redundancy in the docs :). although we all
+ know we are here to generate template-based output, and not to have
+ fun ;-)
+
+ * docs/getting-started.sgml:
+ fixed default user and group for max os x installation
+
+ * libs/Smarty.class.php:
+ made $function[2] and $function[3] options for register_resource
+
+ * libs/Smarty.class.php:
+ fixed issue with object-callback when fetching a php-resource
+
+ * NEWS
+ libs/Smarty.class.php:
+ enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted') as
+ callback for register_resource()
+
+ enabled array(&$obj, 'method') as callback for
+ $default_template_handler_func
+
+2003-04-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml
+ docs/programmers.sgml:
+ fixed some typos, thank to mehdi
+
+ * libs/plugins/function.counter.php:
+ prevent assign from overruling print-attribute in function.counter.php
+
+ * libs/plugins/function.counter.php:
+ fixed problem with counter and assign
+
+ * libs/Smarty.class.php:
+ fixed notice in _load_plugins()
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ made plugin-names case-insensitive. this affects
+ compiler/block/custom-functions and modifers.
+
+2003-04-26 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ remove unnecessary close/open tags from compiled templates
+
+2003-04-26 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ added documentation for foreach.property.*
+
+2003-04-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * docs/designers.sgml:
+ fixed example table_attr and tr_attr in html_table-example
+
+2003-04-21 Greg Beaver <greg@chiaraquartet.net>
+
+ * libs/Smarty.class.php:
+ fixed small bug in doc comments
+
+2003-04-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_image.php:
+ fixed errornous creation of '//' in image_path in html_image
+
+2003-04-21 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/modifier.debug_print_var.php:
+ fix htmlspecialchars() conflict
+
+ * NEWS
+ libs/plugins/modifier.debug_print_var.php:
+ fix escapement of special chars in key values of debug console
+
+ * NEWS
+ libs/plugins/function.config_load.php:
+ fixed debug timing logic for config_load
+
+ * docs/designers.sgml:
+ fix example text
+
+
+2003-04-20 Greg Beaver <cellog@users.sourceforge.net>
+ * plugins/*
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ Config_File.class.php:
+ updated all doc comments to phpDocumentor format (whew!)
+
+2003-04-06 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/plugins/function.math.php:
+ allowed "_" in the name of variable-parameters to {math}-function
+
+2003-04-04 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ docs/designers.sgml
+ libs/Smarty_Compiler.class.php:
+ change backtic syntax from $`foo` to `$foo`
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ recognize $foo[][] syntax in embedded quotes without backticks
+
+2003-04-03 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ name=123 is passed as an integer (not a string) to plugins now
+
+2003-04-01 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ added CVS $Id: ChangeLog 2746 2007-09-28 01:32:05Z changelog $
+
+2003-03-31 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ added missing compile_id inside Smarty_Compiler
+
+ * libs/Smarty_Compiler.class.php:
+ fixed flaw when generating an error for missing postfilter
+
+2003-03-31 Monte Ohrt <monte@ispi.net>
+
+ * docs/getting-started.sgml
+ docs/programmers.sgml:
+ fix typos
+
+2003-03-27 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/modifier.debug_print_var.php:
+ $length is now propagated to sub-values in debug_print_var
+
+2003-03-26 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ update header
+
+ * RELEASE_NOTES:
+ commit changes to release notes
+
+ * (Smarty_2_5_0_RC2)
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ committing RC2
+
+2003-03-24 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ made clear_cache() ignore compile_id when clearing cache_groups
+
+ * libs/plugins/function.popup.php:
+ made onmouseout XHTML-compatible in function.popup.php
+
+2003-03-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ applied new var-names to fetch()
+
+ * NEWS
+ libs/Smarty.class.php:
+ renamed $localvars to $_localvars in cache-file-handling-functions,
+ added _get_auto_id()-function
+
+2003-03-21 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/function.mailto.php
+ libs/plugins/function.popup.php:
+ update functions for XHTML compatability
+
+2003-03-21 Messju Mohr <messju@lammfellpuschen.de>
+
+ * libs/Smarty.class.php:
+ fixed wrong $auto_id in _read_cache_file()
+
+ * NEWS
+ libs/Smarty.class.php:
+ swapped compile_id and cache_id in read_cache_file and write_cache_file
+
+ * libs/Smarty.class.php:
+ reverted patch for ignoring compile-id back to -r1.364, due to problems
+
+ * NEWS
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_radios.php:
+ html_radios and html_checkboxes accept "selected" instead of "checked"
+ optionally now
+
+ * NEWS
+ libs/Smarty.class.php:
+ swapped compile_id and cache_id for cache-file-handling again
+
+2003-03-20 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ fix notice when no parameter is passed to default
+
+2003-03-20 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ removed notice of undefined var in _rm_auto()
+
+2003-03-19 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/function.html_table.php:
+ fix a few error messages, follow consistancy format plugin_name: errormsg
+
+ * libs/plugins/function.html_radios.php:
+ update error messages
+
+ * NEWS
+ libs/plugins/function.html_radios.php:
+ add a warning when an array is passed as the 'checked' value of html_radios
+
+2003-03-19 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fixed errormessage in _compile_smarty_ref()
+
+ * NEWS
+ docs/designers.sgml:
+ updated docs for html_image
+
+2003-03-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/Smarty.class.php:
+ cleaned up calls to readdir()
+
+ * libs/plugins/function.html_options.php:
+ fixed label for optgroup in html_options
+
+2003-03-18 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix (newly introduced) bug with passing multiple modifiers to a parameter
+
+2003-03-18 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ docs/designers.sgml:
+ updated docs for html_checkboxes, html_options and html_radios
+
+ * libs/plugins/function.html_options.php:
+ fixed wrong default-"name" in function.html_options.php
+
+ * NEWS
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_radios.php:
+ renamed "checkbox" and "radios" to "options" in {html_checkboxes} and
+ {html_radios}
+
+ * libs/plugins/outputfilter.trimwhitespace.php:
+ tried to optimize re-replacement in outputfilter.trimwhitespace.php a
+ little
+
+ * libs/plugins/outputfilter.trimwhitespace.php:
+ fixed greedy str_replace in outputfilter.trimwhitespace.php
+
+ * NEWS
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_radios.php:
+ html_options, html_checkboxes and html_radios now pass-thru all unknown
+ paramters
+
+2003-03-17 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/function.html_options.php:
+ html_options passthru all unknown paramters now
+
+2003-03-17 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/function.html_image.php:
+ Fix link bug in html_image function, also make output XHTML compatible
+
+ * libs/Smarty_Compiler.class.php:
+ fix issue of embedded var and escaped double quotes
+
+2003-03-15 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ back out "@" logic, apply only to default modifier special case
+
+ * libs/Smarty_Compiler.class.php:
+ fix @ logic, only use upon an echo
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ append "@" to template var echoes to supress possible notices
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ append "@" to _run_mod_handler to supress warnings
+
+2003-03-14 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix problem with escaped double quotes
+
+ * NEWS
+ libs/plugins/function.html_radios.php:
+ fixed html_options to not return an array
+
+2003-03-12 Messju Mohr <messju@lammfellpuschen.de>
+
+ * NEWS
+ libs/plugins/modifier.truncate.php:
+ fixed length in modifier.truncate.php
+
+ * NEWS
+ libs/plugins/outputfilter.trimwhitespace.php:
+ fixed handling of '$'-signs in trimwhitespace outputfilter (messju)
+
+2003-03-12 Monte Ohrt <monte@ispi.net>
+
+ * docs/programmers.sgml:
+ update technical explanation of assign_by_ref and append_by_ref
+
+2003-03-11 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/Smarty.class.php:
+ fix config file recompiling code
+
+2003-03-07 Monte Ohrt <monte@ispi.net>
+
+ * libs/plugins/function.html_image.php:
+ change E_USER_ERROR to E_USER_NOTICE
+
+ * libs/plugins/function.html_image.php:
+ suppress warning in html_image
+
+ * NEWS
+ libs/plugins/function.html_image.php:
+ update changes to html_image
+
+2003-03-06 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ docs/de/appendixes.sgml
+ docs/de/common.dsl
+ docs/de/designers.sgml
+ docs/de/getting-started.sgml
+ docs/de/html-common.dsl
+ docs/de/html.dsl
+ docs/de/manual.sgml
+ docs/de/preface.sgml
+ docs/de/programmers.sgml:
+ add german docs to dist
+
+ * NEWS:
+ update news file
+
+ * libs/plugins/function.html_image.php:
+ fix width/height parameter index
+
+ * NEWS
+ libs/Smarty.class.php:
+ get rid of unsetting name and script attributes to insert tags
+
+2003-03-05 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ RELEASE_NOTES:
+ update NEWS file
+
+ * libs/plugins/modifier.string_format.php:
+ fix argument order, erroneously swapped a while back
+
+ * (Smarty_2_5_0_RC1)
+ NEWS
+ README
+ RELEASE_NOTES
+ libs/Config_File.class.php
+ libs/Smarty.class.php
+ libs/Smarty_Compiler.class.php:
+ commit final changes for 2.5.0-RC1
+
+2003-03-04 Monte Ohrt <monte@ispi.net>
+
+ * docs/programmers.sgml:
+ remove $show_info_header and $show_info_include property vars from docs
+
+2003-03-03 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/function.popup.php:
+ fixed PHP notice
+
+2003-02-28 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty_Compiler.class.php:
+ simplify smarty.const.foo and smarty.const.$foo logic
+
+ * libs/Smarty_Compiler.class.php:
+ only allow $foo syntax in embedded quotes, unless escaped with backticks
+ then allow any dollar var
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ fix "once" var compiling to work with new attr compiling methods for
+ include_php
+
+ * FAQ
+ NEWS
+ README
+ docs/designers.sgml
+ docs/getting-started.sgml
+ libs/Smarty_Compiler.class.php
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_image.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/function.html_select_date.php
+ libs/plugins/function.html_select_time.php
+ libs/plugins/function.html_table.php:
+ fix $smarty.const.foo compiling, clean up double quoted strings,
+ allow full dollar var syntax in quotes again
+
+2003-02-27 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ docs/programmers.sgml
+ libs/Smarty_Compiler.class.php:
+ update docs, fix smarty var compiling, allow any $smarty.*.$foo syntax,
+ add $`foobar` for embedded variables
+
+ * libs/plugins/function.html_image.php:
+ update functionality
+
+2003-02-26 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ libs/plugins/modifier.nl2br.php:
+ add nl2br modifier
+
+ * libs/plugins/function.html_image.php:
+ add link parameter
+
+2003-02-24 Monte Ohrt <monte@ispi.net>
+
+ * libs/Smarty.class.php
+ libs/plugins/function.html_image.php:
+ fix rename problem in windows, unlink first
+
+ * libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_image.php
+ libs/plugins/function.html_options.php
+ libs/plugins/function.html_radios.php
+ libs/plugins/shared.escape_special_chars.php:
+ update functions with separate escape_special_chars routine
+
+ * NEWS
+ libs/plugins/function.html_checkboxes.php
+ libs/plugins/function.html_radios.php:
+ commit checkboxes, update radios
+
+ * NEWS
+ libs/Smarty.class.php
+ libs/plugins/function.html_image.php:
+ fix bug with get_registered_object
+
+ * NEWS
+ libs/plugins/modifier.cat.php:
+ added cat modifier to distribution
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ added << >> <> support to IF statements
+
+ * libs/plugins/function.html_radios.php:
+ apply patch to initial html_radios function
+
+ * NEWS
+ libs/Smarty.class.php:
+ fix _assign_smarty_interface to not overwrite keys other than 'request'
+
+ * NEWS
+ libs/plugins/function.html_radios.php:
+ added html_radios to distribution
+
+ * NEWS
+ libs/plugins/modifier.string_format.php:
+ fixed arg order of string_format
+
+ * NEWS
+ libs/Smarty.class.php:
+ use tmp file for file writes, avoid race condition
+
+ * NEWS
+ libs/Smarty_Compiler.class.php:
+ add $smarty.config.foo var, handle embedded smarty var correctly
+
+ * NEWS
+ libs/plugins/function.fetch.php:
+ silence warnings in fetch plugin
+
+2003-02-21 Monte Ohrt <monte@ispi.net>
+
+ * INSTALL:
+ update wording
+
+ * INSTALL:
+ update install instructions
+
+ * AUTHORS
+ BUGS
+ CREDITS
+ QUICKSTART
+ README
+ RESOURCES
+ TESTIMONIALS:
+ remove some files already in docs or elsewhere
+
+ * demo/index.php:
+ add templates_c to repository
+
+ * index.php:
+ move demo files to demo directory
+
+ * Config_File.class.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ debug.tpl:
+ moved lib files under libs directory
+
+2003-02-20 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php:
+ add get_config_vars() method, update get_template_vars() functionality
+
+ * NEWS
+ Smarty.class.php:
+ fix minor logic in _fetch_template_info()
+
+ * NEWS
+ Smarty.class.php:
+ support merging appended vars
+
+ * NEWS
+ Smarty.class.php:
+ fix cache groups behavior with compile_id set
+
+2003-02-19 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ back out third parameter, extend functionality of append
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ update imbedded vars, allow special $smarty vars
+
+ * plugins/function.html_table.php:
+ add plugin html_table
+
+ * NEWS
+ Smarty.class.php:
+ support appending key=>val pairs
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ change embedded variable logic to only recognize $foo and $foo[0][bar]
+ syntax
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ allow null as function attribute value
+
+2003-02-18 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ support foo->bar[index] syntax
+
+ * Smarty_Compiler.class.php:
+ allow $foo->bar[0] syntax
+
+2003-02-17 Monte Ohrt <monte@ispi.net>
+
+ * plugins/modifier.escape.php:
+ fix syntax error from previous commit
+
+ * NEWS
+ Smarty.class.php:
+ add error msgs to get_registered_object
+
+ * Smarty.class.php:
+ add function for getting reference to registered object
+
+ * Smarty_Compiler.class.php:
+ back out patches for object and objref calls on $smarty var
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ treat unrecognized param attribute syntax as a string
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ support $smarty.const.$foo syntax
+
+ * NEWS
+ debug.tpl
+ plugins/modifier.count_words.php
+ plugins/modifier.escape.php:
+ fix E_NOTICE messages
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ add @ and === to if tokens, few param cleanups
+
+2003-02-16 Greg Beaver <greg@chiaraquartet.net>
+
+ * ChangeLog
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ many more phpdoc comment upgrades
+
+2003-02-15 Greg Beaver <cellog@sourceforge.net>
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ continue cleaning of phpdoc comments. All that is needed is the
+ addition of @return tags and perhaps a bit more verbose comments
+ and they are finished.
+
+2003-02-14 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php:
+ enable config_load error messages
+
+ * NEWS
+ plugins/function.html_options.php:
+ fix html_options to not escape already escaped entities
+
+ * NEWS
+ Smarty.class.php:
+ send Last-Modified header on cache creation, misc tab/spacing cleanup
+
+2003-02-13 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ docs/designers.sgml:
+ allow dash in plain text
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ check strict syntax of function attributes
+
+2003-02-12 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ dropped support for modifiers on object parameters,
+ added support for objects as modifier parameters
+
+ * NEWS
+ Smarty_Compiler.class.php
+ docs/designers.sgml:
+ fix bug with decimal numbers in if statements, misc doc updates
+
+2003-02-11 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_4_2)
+ Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ update version numbers
+
+2003-02-10 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ add support for $foo->$bar syntax
+
+ * NEWS:
+ update NEWS file
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ support full var syntax in quoted text, fix problem with const var access,
+ clean up some more regex code, fix object problem with no properties
+
+2003-02-06 Monte Ohrt <monte@ispi.net>
+
+ * (Smarty_2_4_1)
+ Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ committed 2.4.1 changes
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ ignore case in IF statements
+
+2003-02-05 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ treat undefined constants as null
+
+ * NEWS
+ Smarty.class.php:
+ fix problem with inserts and nested fetches
+
+ * Smarty_Compiler.class.php:
+ fix "if" regex for math tokens
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs/getting-started.sgml:
+ added support for extracting params to include_php
+
+2003-02-04 Monte Ohrt <monte@ispi.net>
+
+ * RELEASE_NOTES:
+ reformat text
+
+2003-02-03 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ update news file
+
+2003-02-03 Greg Beaver <greg@chiaraquartet.net>
+
+ * ChangeLog
+ Smarty.class.php:
+ begin fixing phpdoc comments in Smarty.class.php
+
+ * ChangeLog
+ Config_File.class.php:
+ fixed phpdoc comments
+
+2003-02-03 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ allow $foo->bar[$x].foo syntax
+
+ * Smarty_Compiler.class.php
+ index.php
+ configs/test.conf
+ templates/index.tpl:
+ fix accidental commit
+
+ * index.php
+ configs/test.conf
+ templates/index.tpl:
+ allow $foo->bar[$j].blah type of syntax
+
+2003-02-02 Greg Beaver <cellog@php.net>
+
+ * Smarty.class.php
+ begin fixing of phpdoc comments
+
+ * Config_File.class.php
+ fix phpdoc comments, add phpDocumentor docblock templates
+
+2003-02-02 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ docs/html.dsl
+ docs/php.dsl:
+ fix version number
+
+ * (Smarty_2_4_0)
+ Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs/appendixes.sgml
+ docs/designers.sgml
+ docs/programmers.sgml:
+ update Smarty version numbers
+
+2003-01-30 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty_Compiler.class.php
+ TODO:
+ fix order of php tag comparisons
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ fix known php tag handling problems
+
+2003-01-29 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php:
+ change comments to phpdoc style
+
+2003-01-28 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ docs/programmers.sgml:
+ make separate var for compiler file
+
+ * plugins/function.fetch.php:
+ fix error call
+
+2003-01-25 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php:
+ add support for restriction to registered methods
+
+ * plugins/outputfilter.trimwhitespace.php:
+ update with textarea support
+
+2003-01-24 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ fix compiling problem with {foreach} tags
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php:
+ put objects in own array, add object param format support, change
+ object syntax from foo.bar to foo->bar
+
+2003-01-23 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ add support for object registration
+
+2003-01-22 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ add file & line number of calling error to error message
+
+2003-01-21 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ put php style object syntax back in
+
+2003-01-20 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ move security settings to fetch function for template_dir
+
+ * NEWS
+ Smarty.class.php:
+ fix debug template and security, add template_dir to secure_dir at runtime
+
+2003-01-17 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ added new object support without new template syntax
+
+2003-01-15 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ fix if statement syntax for negative integers, fix issue with directories
+ named '0'
+
+2003-01-08 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ plugins/function.counter.php
+ plugins/function.cycle.php
+ plugins/function.debug.php
+ plugins/function.eval.php
+ plugins/function.fetch.php
+ plugins/function.html_options.php
+ plugins/function.html_select_date.php
+ plugins/function.html_select_time.php
+ plugins/function.mailto.php
+ plugins/function.math.php
+ plugins/function.popup.php
+ plugins/function.popup_init.php:
+ update plugins to return values instead of echo, fix config file cache
+ to include global config variables in cache file
+
+ * Smarty_Compiler.class.php:
+ fix bug with >= tests in if statements, comment out full object support
+
+2003-01-06 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ docs/html.dsl
+ plugins/modifier.escape.php:
+ add javascript escape parameter to escape modifier
+
+2003-01-02 Monte Ohrt <monte@ispi.net>
+
+ * templates/header.tpl:
+ move the title into head where it should be
+
+2002-12-24 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ added correct line numbers to smarty syntax error messages
+
+ * docs/programmers.sgml:
+ update append documentation, make more clear on its function
+
+ * Smarty_Compiler.class.php:
+ fix modifier matching regexp
+
+2002-12-23 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ support nested function calls in IF statements
+
+2002-12-20 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ few more fixes, spaces around function parameters
+
+ * Smarty_Compiler.class.php:
+ fix misc syntax issues with {if} tags
+
+2002-12-20 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ fix misc syntax issues with {if} tags
+
+2002-12-19 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ commit updates, passes all smoke tests
+
+ * NEWS:
+ update NEWS file
+
+ * Smarty_Compiler.class.php:
+ fixed literal string not in quotes as parameters
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ fix misc syntax issues, add ability to pass modifiers to functions
+
+2002-12-18 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ update NEWS
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ update compiler code, clean up regex, add new syntax features
+
+2002-12-16 Monte Ohrt <monte@ispi.net>
+
+ * NEWS:
+ update NEWS file
+
+ * Smarty_Compiler.class.php:
+ commit updates for objects
+
+2002-12-14 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php:
+ fix bug with compiling config files with caching on
+
+2002-12-13 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ fix problem with matching single quoted strings
+
+ * Smarty_Compiler.class.php:
+ update embedded variable logic, get rid of ."" at end of output
+
+ * NEWS
+ docs/designers.sgml
+ plugins/function.html_select_date.php:
+ add day_value_format to html_select_date
+
+2002-12-12 Monte Ohrt <monte@ispi.net>
+
+ * plugins/modifier.debug_print_var.php:
+ fix bug, double escaped values in display
+
+ * Smarty.class.php:
+ move debug test back into fetch()
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ plugins/outputfilter.trimwhitespace.php:
+ assigned vars are no longer in global name space, few debug cleanups
+
+2002-12-11 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.popup.php:
+ fix error in newline code
+
+ * plugins/function.popup.php:
+ fix popup to allow newlines in text data
+
+2002-12-10 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ fix plugin error logic
+
+ * docs/designers.sgml
+ docs/programmers.sgml:
+ edit examples, make more verbose
+
+ * NEWS
+ plugins/function.html_options.php:
+ escape html entities in the option values and output
+
+ * NEWS
+ plugins/function.html_options.php:
+ fixed bug with label of html_options
+
+2002-12-09 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ add support for var_export()
+
+ * Config_File.class.php
+ Smarty.class.php:
+ clean up code, respect force_compile and compile_check flags
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs/designers.sgml
+ plugins/function.mailto.php:
+ add caching feature to config loading, document update, add mailto plugin
+
+2002-12-08 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.fetch.php:
+ fix query part of URL
+
+2002-12-05 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ fix typos
+
+2002-11-22 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php:
+ patch for warning message
+
+2002-11-21 Monte Ohrt <monte@ispi.net>
+
+ * RELEASE_NOTES
+ Smarty.class.php:
+ get rid of testing for a set value with assign function, just set to
+ whatever is passed into the template
+
+ * docs/programmers.sgml:
+ fix typo
+
+2002-11-19 Monte Ohrt <monte@ispi.net>
+
+ * Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ commit changes, ready for 2.3.1 release
+
+2002-11-01 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.html_options.php:
+ added label attribute to all option outputs, cover w3c spec.
+
+ * NEWS: update NEWS file
+
+ * docs/designers.sgml: update docs for optgroup output
+
+ * plugins/function.html_options.php:
+ make html_options work with optgroup, make func modular and recursive.
+
+2002-10-29 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php: set mtime on compile files so they match source files
+
+2002-10-18 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php: added proper support for open_basedir setting
+
+ * docs/designers.sgml: clear up docs on index, iteration and rownum
+
+2002-10-16 Monte Ohrt <monte@ispi.net>
+
+ * plugins/modifier.default.php: fix warning message in default modifier
+
+2002-09-25 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ plugins/modifier.strip.php
+ NEWS: added strip variable modifier
+
+2002-09-24 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty_Compiler.class.php:
+ Fix to be able to use $smarty.x variables as arrays.
+
+2002-09-23 Monte Ohrt <monte@ispi.net>
+
+ * Config_File.class.php:
+ add support for mac/dos formatted config files (fix newlines)
+
+ * docs/programmers.sgml: add optional tags to clear_cache parameters
+
+ * docs/designers.sgml:
+ fix error with include_php description, add $this to description
+
+2002-09-20 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ docs/getting-started.sgml: fixed errors with example setup docs
+
+2002-09-16 Monte Ohrt <monte@ispi.net>
+
+ * plugins/block.textformat.php
+ docs/designers.sgml
+ NEWS: add textformat block function
+
+2002-09-10 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ add assign attribute to cycle function documentation
+
+ * docs/designers.sgml
+ docs/programmers.sgml: fix typos
+
+2002-09-09 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.debug.php
+ templates/header.tpl:
+ fix header in debug template, fix typo in header.tpl example
+
+2002-08-15 mohrt <mohrt@pb1.pair.com>
+
+ * docs/programmers.sgml: fix typos
+
+2002-08-08 mohrt <mohrt@pb1.pair.com>
+
+ * RELEASE_NOTES
+ Smarty.class.php:
+ supress warnings from unlink() and is_dir(), let error handler deal with it
+
+2002-08-07 mohrt <mohrt@pb1.pair.com>
+
+ * docs/appendixes.sgml
+ docs/designers.sgml
+ docs/programmers.sgml
+ Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php: update files with new version numbers
+
+2002-08-02 mohrt <mohrt@pb1.pair.com>
+
+ * NEWS: update NEWS file with credits
+
+ * NEWS
+ Smarty.class.php: added assign_by_ref() and append_by_ref() functions
+
+2002-08-01 mohrt <mohrt@pb1.pair.com>
+
+ * TODO
+ NEWS
+ Smarty.class.php:
+ changed default warning type for plugin errors from E_USER_WARNING to E_USER_ERROR
+
+2002-07-29 mohrt <mohrt@pb1.pair.com>
+
+ * plugins/function.html_select_time.php
+ docs/designers.sgml
+ NEWS: added paramters to html_select_time plugin
+
+2002-07-25 Andrei Zmievski <andrei@pb1.pair.com>
+
+ * TODO: *** empty log message ***
+
+2002-07-24 mohrt <mohrt@pb1.pair.com>
+
+ * QUICKSTART: update QUICKSTART guide
+
+ * NEWS
+ debug.tpl
+ plugins/modifier.debug_print_var.php:
+ update debug console to show objects, fix warning in debug.tpl
+
+2002-07-23 mohrt <mohrt@pb1.pair.com>
+
+ * docs/programmers.sgml: fix load_filter examples
+
+ * Config_File.class.php
+ NEWS: fix error when there are no sections in config file
+
+2002-07-19 mohrt <mohrt@pb1.pair.com>
+
+ * docs/getting-started.sgml: fix error in install guide
+
+2002-07-18 mohrt <mohrt@pb1.pair.com>
+
+ * Smarty_Compiler.class.php:
+ correct the expression match for smarty:nodefaults
+
+2002-07-17 mohrt <mohrt@pb1.pair.com>
+
+ * Smarty_Compiler.class.php: fix default modifier to work with config vars
+
+ * Smarty_Compiler.class.php: got args to strstr backwards...
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ change default modifiers to array instead of string
+
+ * Smarty_Compiler.class.php
+ docs/designers.sgml
+ Smarty.class.php: add default modifier logic, minor doc updates
+
+ * NEWS
+ Smarty.class.php
+ plugins/function.popup_init.php:
+ make popup_init xhtml compliant, minor variable name changes for consistancy
+
+2002-07-16 mohrt <mohrt@pb1.pair.com>
+
+ * NEWS: update NEWS file
+
+ * plugins/function.debug.php
+ Smarty.class.php
+ debug.tpl
+ NEWS:
+ fix problem with filenames on windows, add ability to supply expire time in seconds when clearing cache or compiled files
+
+2002-07-15 mohrt <mohrt@pb1.pair.com>
+
+ * Smarty.class.php:
+ fixed problem with insert tags when loading function from script attribute
+ and caching enabled (Monte)
+
+2002-07-14 mohrt <mohrt@pb1.pair.com>
+
+ * NEWS
+ Smarty.class.php: fix bug with debug_tpl file path for Windows
+
+2002-07-12 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: fix append function with array/string issue
+
+2002-07-11 Monte Ohrt <monte@ispi.net>
+
+ * RELEASE_NOTES: update release notes
+
+ * NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ Config_File.class.php: update files to 2.2.0 tags, get ready for release
+
+2002-07-09 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php: make debug.tpl work with any delimiter
+
+ * NEWS
+ Smarty.class.php:
+ change tests in append and assign to != '' instead of empty(), which is more accurate
+
+2002-07-08 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml: minor doc update
+
+ * Smarty.class.php:
+ cast var as an array, simplify and get rid of PHP warning messages
+
+2002-07-03 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: one more N
+
+ * Smarty.class.php:
+ prepend "N" to filenames to avoid possible OS issues with dir names starting with "-"
+
+ * Smarty.class.php: only set $debug_tpl in constructor if empty
+
+ * Smarty.class.php
+ docs/designers.sgml
+ docs/getting-started.sgml
+ docs/programmers.sgml:
+ make use_sub_dirs go back to crc32 for subdir separation
+
+2002-06-29 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.eval.php: do nothing if $val is empty
+
+ * TODO
+ plugins/function.eval.php
+ plugins/function.popup_init.php:
+ add zindex to popup init, fix error message for eval.
+
+2002-06-27 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ only loop through relative paths for PHP include_path, remove $_relative variable
+
+ * Smarty_Compiler.class.php: added {$smarty.version} variable
+
+2002-06-26 Monte Ohrt <monte@ispi.net>
+
+ * docs/appendixes.sgml
+ docs/designers.sgml
+ docs/getting-started.sgml
+ docs/programmers.sgml
+ Smarty.class.php:
+ update plugin loading logic, look in SMARTY_DIR, then cwd. If all fail, then retry all with include_path
+
+ * templates/header.tpl
+ Smarty.class.php: update get_include_path, get _path_array only once
+
+ * Smarty.class.php: fix get_include_path function for windows
+
+ * Smarty.class.php: update plugin search logic
+
+ * Smarty.class.php: only search include_path if relative path
+
+ * plugins/function.html_select_date.php
+ plugins/function.html_select_time.php
+ plugins/modifier.date_format.php
+ Smarty_Compiler.class.php
+ NEWS
+ Smarty.class.php: allow plugins_dir to be an array of directories
+
+2002-06-25 Monte Ohrt <monte@ispi.net>
+
+ * docs/programmers.sgml
+ docs/getting-started.sgml: update installation docs
+
+ * debug.tpl
+ docs/getting-started.sgml
+ templates/debug.tpl
+ NEWS
+ Smarty.class.php: move debug.tpl to SMARTY_DIR, add to constructor
+
+2002-06-24 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.assign_debug_info.php
+ NEWS: fixed warning message in function.assign_debug_info
+
+ * Smarty.class.php: update include_path fixes
+
+ * NEWS:
+ fixed $template_dir, $compile_dir, $cache_dir, $config_dir to respect include_path
+
+2002-06-23 Monte Ohrt <monte@ispi.net>
+
+ * plugins/shared.make_timestamp.php:
+ update timestamp plugin to work when passed a timestamp
+
+2002-06-19 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update NEWS file
+
+ * plugins/modifier.date_format.php
+ docs/designers.sgml:
+ update date_format, allow optional 2nd paramater as default date if passed date is empty. update docs.
+
+ * plugins/modifier.date_format.php:
+ fix date_format modifier, return nothing if given empty string
+
+2002-06-18 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ plugins/function.cycle.php:
+ gave $reset a default value in cycle function
+
+ * plugins/function.html_select_date.php
+ plugins/shared.make_timestamp.php
+ NEWS:
+ corrected warnings in html_select_time function, made make timestamp always return a timestamp
+
+2002-06-17 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: swapped around cache_id and compile_id order
+
+2002-06-14 Monte Ohrt <monte@ispi.net>
+
+ * docs/programmers.sgml
+ plugins/function.popup_init.php
+ Smarty.class.php:
+ change directory delimiter to "^" for cache and compile files
+
+2002-06-13 Andrei Zmievski <andrei@php.net>
+
+ * TODO: done.
+
+ * Smarty_Compiler.class.php:
+ Optimize the calculation of section 'total' property.
+
+2002-06-11 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php:
+ added support for subdir exclusion, deletion by full or partial cache_id and compile_id, change file format to urlencoded values instead of crc32
+
+2002-06-07 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: fix bug with last_modified_check code
+
+ * NEWS
+ Smarty.class.php:
+ updated $GLOBALS refererence for HTTP_IF_MODIFIED_SINCE
+
+2002-06-06 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ overlib.js:
+ remove overlib.js file from distribution, update plugin and docs
+
+2002-06-05 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ NEWS
+ Smarty.class.php: fix 304 Not Modified, don't send content
+
+2002-06-03 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.cycle.php: update version number
+
+ * plugins/function.cycle.php
+ NEWS:
+ fixed cycle function to respect delimiter setting after initial setting
+
+ * Smarty.class.php
+ NEWS:
+ update $GLOBALS references to work properly with track_globals settings
+
+ * plugins/function.math.php: fixed bug with call $assign
+
+ * docs/appendixes.sgml
+ docs/designers.sgml
+ plugins/function.html_options.php
+ plugins/function.html_select_time.php
+ NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ optimized for loops with count() function calls
+
+2002-06-01 Andrei Zmievski <andrei@php.net>
+
+ * TODO: *** empty log message ***
+
+2002-05-21 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update NEWS file
+
+ * plugins/function.html_select_date.php
+ RESOURCES
+ docs/designers.sgml
+ Config_File.class.php:
+ update html_select_date with month_value_format attribute for controlling the format of the month values.
+
+2002-05-17 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ Made it possible to use simple variables inside [] for indexing.
+
+2002-05-16 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ docs/getting-started.sgml
+ NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ TESTIMONIALS: add "once" attribute to php_include, update docs
+
+2002-05-09 Andrei Zmievski <andrei@ispi.net>
+
+ * NEWS
+ TODO: *** empty log message ***
+
+2002-05-07 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.cycle.php: remove \n from cycle function
+
+ * docs/designers.sgml
+ plugins/function.cycle.php
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ NEWS:
+ update cycle function to handle array as input, update files to 2.1.1
+
+2002-05-06 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.fetch.php:
+ update fetch function with more error checking
+
+2002-05-03 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ plugins/function.counter.php:
+ update counter to use name instead of id (id still works though)
+
+ * plugins/function.cycle.php
+ docs/designers.sgml: rename id to name for cycle function
+
+ * plugins/function.cycle.php:
+ update cycle function to allow blank values parameter after initialized
+
+ * plugins/function.cycle.php: fix syntax error
+
+2002-05-02 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.cycle.php: ugh, another typo
+
+ * plugins/function.cycle.php: update comments
+
+ * docs/designers.sgml
+ plugins/function.cycle.php
+ NEWS: added function cycle
+
+ * FAQ
+ Smarty.class.php: fix register_outputfilter function
+
+2002-05-01 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml
+ NEWS
+ Smarty.class.php: fixed bug with resource testing and include_path
+
+2002-04-30 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php: update files for 2.1.0 release
+
+2002-04-30 Andrei Zmievski <andrei@ispi.net>
+
+ * plugins/function.fetch.php
+ docs/programmers.sgml
+ Smarty.class.php: Fix.
+
+2002-04-29 Andrei Zmievski <andrei@ispi.net>
+
+ * docs/programmers.sgml
+ docs/designers.sgml: A whole bunch of docs.
+
+2002-04-26 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ QUICKSTART
+ docs/programmers.sgml: update FAQ, QUICKSTART, small doc syntax fix
+
+2002-04-24 Monte Ohrt <monte@ispi.net>
+
+ * docs/programmers.sgml
+ templates/debug.tpl
+ Smarty.class.php: changed doc structure a bit
+
+2002-04-16 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Add register/unregister API for output filters.
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ TODO:
+ Changed the way filters are loaded, which now has to be done explicitly,
+ either through load_filter() API or by filling in $autoload_filters variable.
+ Also renamed internal variable to avoid namespace pollution.
+
+2002-04-15 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php:
+ Fixed _get_php_resource() to take include_path into account.
+
+2002-04-15 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml:
+ update docs, get modifiers and functions into index for easy access
+
+ * docs/programmers.sgml
+ NEWS
+ Smarty.class.php: update caching documentation
+
+2002-04-15 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty.class.php: Only turn down error notices if $debugging is false.
+
+2002-04-15 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update NEWS file
+
+ * plugins/function.html_select_date.php:
+ fixed logic so this works right when field_separator = "/"
+
+ * plugins/function.html_select_date.php:
+ fix regular expression for matching date
+
+2002-04-13 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml: updated html_select_date docs to reflect changes
+
+ * NEWS
+ plugins/function.html_select_date.php:
+ added YYYY-MM-DD support to html_select_date
+
+2002-04-12 Andrei Zmievski <andrei@php.net>
+
+ * TESTIMONIALS: New entry.
+
+2002-04-12 Monte Ohrt <monte@ispi.net>
+
+ * plugins/modifier.strip_tags.php: back out changes to strip_tags
+
+ * docs/programmers.sgml: update docs regarding cache_lifetime
+
+ * plugins/modifier.strip_tags.php
+ Smarty.class.php:
+ update cache_lifetime logic: -1 = never expire, 0 = always expire
+
+2002-04-11 Andrei Zmievski <andrei@php.net>
+
+ * BUGS
+ FAQ
+ INSTALL
+ NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs/getting-started.sgml:
+ Fixed directory separtor issue. Requiring PHP 4.0.6 now.
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ Added ability to use simple variables for array indices or object properties.
+
+ * TESTIMONIALS: Another one.
+
+ * TESTIMONIALS: Adding one from Mark P.
+
+2002-04-05 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php
+ NEWS
+ Smarty.class.php: Make it possible to unregister pre/postfilter plugins.
+
+2002-04-05 Monte Ohrt <monte@ispi.net>
+
+ * INSTALL: Remove addons file from INSTALL instructions
+
+2002-04-04 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml: update doc error
+
+ * docs/designers.sgml
+ plugins/modifier.escape.php
+ NEWS
+ Smarty.class.php: added htmlall attribute to escape modifier
+
+2002-04-03 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Fixed undefined offset warning in {if} tag.
+
+ * Smarty.class.php
+ NEWS: Added template_exists() API.
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ NEWS:
+ - Added $smarty.template variable.
+ - Fixed {include_php} tag when dynamic values were used for 'file' attribute.
+
+ * Config_File.class.php: Separator setting fix.
+
+2002-03-28 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ README: add digest address
+
+ * FAQ
+ README
+ Smarty.class.php: update mailing list addresses
+
+2002-03-28 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * plugins/function.html_select_date.php
+ plugins/function.html_select_time.php
+ plugins/modifier.date_format.php:
+ Fix for when plugins directory is not the default one.
+
+2002-03-28 Andrei Zmievski <andrei@ispi.net>
+
+ * NEWS: *** empty log message ***
+
+ * plugins/function.html_select_date.php
+ plugins/function.html_select_time.php
+ plugins/modifier.date_format.php:
+ Fix for when plugins directory is not the default one.
+
+2002-03-27 Monte Ohrt <monte@ispi.net>
+
+ * FAQ: update FAQ page
+
+2002-03-26 Andrei Zmievski <andrei@ispi.net>
+
+ * CREDITS
+ NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ TODO: Block functions changes.
+
+ * Config_File.class.php: *** empty log message ***
+
+2002-03-25 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php: Initial implementation of block functions.
+
+2002-03-22 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml: fix documentation error in capture
+
+2002-03-22 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: *** empty log message ***
+
+ * Smarty.class.php: Turn off notices.
+
+2002-03-21 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Make _current_file available to prefilters.
+
+ * NEWS
+ Smarty.class.php:
+ Made is possible to assign variables in pre/postfilters.
+
+2002-03-20 Andrei Zmievski <andrei@php.net>
+
+ * plugins/function.html_select_date.php: Fixed +/- functionality.
+
+ * NEWS: *** empty log message ***
+
+2002-03-20 Monte Ohrt <monte@ispi.net>
+
+ * Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.class.php
+ Smarty_Compiler.class.php: update version numbers
+
+ * plugins/function.html_select_date.php
+ plugins/function.html_select_time.php
+ plugins/modifier.date_format.php:
+ move .make_timestamp.php to shared.make_timestamp.php
+
+ * NEWS
+ Smarty.class.php
+ docs/designers.sgml
+ plugins/function.fetch.php
+ plugins/function.html_select_date.php:
+ update file generation, replace crc32() '-' with 'N'
+
+2002-03-20 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: *** empty log message ***
+
+2002-03-19 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php:
+ Fix plugin behavior for inserts with script attribute.
+
+ * NEWS: *** empty log message ***
+
+ * Smarty_Compiler.class.php: Fix bug with $smarty.cookies.
+
+ * TESTIMONIALS: *** empty log message ***
+
+2002-03-15 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ docs/designers.sgml: update Changelog
+
+ * plugins/modifier.indent.php
+ plugins/modifier.wordwrap.php: add wordwrap and indent to repository
+
+2002-03-14 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ remove show_info_include and show_info_header functions
+
+2002-03-13 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.fetch.php: update fetch function
+
+ * plugins/function.fetch.php: update fetch function with new parameters
+
+2002-03-12 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml: update doc tables
+
+ * docs/designers.sgml: update docs columns
+
+ * docs/getting-started.sgml
+ docs/appendixes.sgml: update docs
+
+ * TESTIMONIALS
+ docs/appendixes.sgml: update syntax error in docs, add to testimonials
+
+2002-03-04 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ README: update FAQ, README with digest mode info
+
+2002-03-02 Monte Ohrt <monte@ispi.net>
+
+ * QUICKSTART: update quickstart
+
+ * Smarty.class.php:
+ change behavior so cache_lifetime = 0 never expires (instead of always regenerate)
+
+2002-03-01 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml: update doc example
+
+2002-03-01 Andrei Zmievski <andrei@php.net>
+
+ * CREDITS
+ RELEASE_NOTES
+ TODO
+ NEWS: *** empty log message ***
+
+2002-03-01 Monte Ohrt <monte@ispi.net>
+
+ * docs/appendixes.sgml
+ docs/designers.sgml
+ docs/getting-started.sgml
+ docs/programmers.sgml: update document id tags
+
+ * docs.sgml: remove docs.sgml
+
+ * RESOURCES
+ Smarty.class.php: update resources
+
+2002-02-28 Andrei Zmievski <andrei@php.net>
+
+ * TESTIMONIALS
+ docs/appendixes.sgml
+ docs/designers.sgml
+ docs/programmers.sgml: *** empty log message ***
+
+2002-02-27 Andrei Zmievski <andrei@php.net>
+
+ * plugins/function.eval.php
+ docs/designers.sgml: *** empty log message ***
+
+2002-02-27 Monte Ohrt <monte@ispi.net>
+
+ * plugins/function.eval.php: added eval function to plugin dir
+
+2002-02-27 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+2002-02-27 Monte Ohrt <monte@ispi.net>
+
+ * docs/designers.sgml: fix syntax error
+
+ * docs/appendixes.sgml
+ docs/designers.sgml
+ docs/getting-started.sgml
+ docs/programmers.sgml: convert technical notes to docbook format
+
+ * NEWS
+ docs/designers.sgml: added "eval" plugin docs
+
+2002-02-26 Andrei Zmievski <andrei@php.net>
+
+ * docs/programmers.sgml
+ docs/designers.sgml
+ docs/appendixes.sgml
+ docs/getting-started.sgml
+ docs/html-common.dsl
+ docs/.cvsignore: *** empty log message ***
+
+ * docs/appendixes.sgml
+ docs/common.dsl
+ docs/designers.sgml
+ docs/getting-started.sgml
+ docs/html-common.dsl
+ docs/html.dsl
+ docs/manual.sgml
+ docs/preface.sgml
+ docs/programmers.sgml: Split up docs.
+
+2002-02-25 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml: *** empty log message ***
+
+2002-02-22 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: update docs
+
+2002-02-22 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml
+ AUTHORS
+ NEWS: *** empty log message ***
+
+2002-02-21 Monte Ohrt <monte@ispi.net>
+
+ * Config_File.class.php
+ NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml: update misc changes
+
+2002-02-21 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml: *** empty log message ***
+
+2002-02-20 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: misc updates
+
+2002-02-20 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml: *** empty log message ***
+
+ * Smarty.class.php
+ plugins/function.assign.php
+ plugins/function.assign_debug_info.php
+ plugins/function.counter.php
+ plugins/function.fetch.php
+ plugins/function.math.php
+ plugins/function.popup.php
+ plugins/function.popup_init.php
+ plugins/modifier.escape.php: Fixup some naming.
+
+2002-02-20 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: update docs
+
+2002-02-20 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml: *** empty log message ***
+
+2002-02-20 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ docs.sgml
+ plugins/modifier.escape.php:
+ removed global vars from fetch function, added attrs to escape modifier
+
+ * docs.sgml: add plugin chapter outline
+
+2002-02-19 Monte Ohrt <monte@ispi.net>
+
+ * README
+ RELEASE_NOTES
+ RESOURCES
+ Smarty.class.php
+ docs.sgml
+ BUGS
+ FAQ
+ INSTALL
+ QUICKSTART: update docs
+
+2002-02-19 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml: Updated resources docs.
+
+ * README: *** empty log message ***
+
+ * docs.sgml: Updated description of {$smarty} variable.
+
+ * BUGS
+ FAQ
+ INSTALL
+ QUICKSTART
+ RELEASE_NOTES
+ docs.sgml: Remove PEAR notes.
+
+2002-02-18 Andrei Zmievski <andrei@php.net>
+
+ * Config_File.class.php
+ NEWS: Removed dependency on PEAR.
+
+2002-02-18 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ docs.sgml
+ plugins/function.popup_init.php: add src attribute to popup_init
+
+2002-02-15 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php
+ plugins/modifier.debug_print_var.php
+ NEWS
+ Smarty.class.php: Performance enhancements.
+
+2002-02-06 Andrei Zmievski <andrei@php.net>
+
+ * plugins/function.html_options.php:
+ Fix html_options output to be XHTML compatible.
+
+2002-02-05 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php: Fix up plugin inclusion.
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ TODO
+ plugins/function.html_select_date.php
+ plugins/function.html_select_time.php
+ plugins/modifier.date_format.php: Fix plugin directory access.
+
+2002-02-04 Andrei Zmievski <andrei@php.net>
+
+ * .cvsignore
+ Smarty_Compiler.class.php: *** empty log message ***
+
+2002-01-31 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ TODO
+ plugins/function.assign.php
+ plugins/function.assign_debug_info.php
+ plugins/function.counter.php
+ plugins/function.fetch.php
+ plugins/function.html_options.php
+ plugins/function.html_select_date.php
+ plugins/function.html_select_time.php
+ plugins/function.math.php
+ plugins/function.popup.php
+ plugins/function.popup_init.php
+ plugins/modifier.capitalize.php
+ plugins/modifier.count_characters.php
+ plugins/modifier.count_paragraphs.php
+ plugins/modifier.count_sentences.php
+ plugins/modifier.count_words.php
+ plugins/modifier.date_format.php
+ plugins/modifier.debug_print_var.php
+ plugins/modifier.default.php
+ plugins/modifier.escape.php
+ plugins/modifier.lower.php
+ plugins/modifier.regex_replace.php
+ plugins/modifier.replace.php
+ plugins/modifier.spacify.php
+ plugins/modifier.string_format.php
+ plugins/modifier.strip_tags.php
+ plugins/modifier.truncate.php
+ plugins/modifier.upper.php
+ plugins/shared.make_timestamp.php
+ templates/index.tpl
+ AUTHORS
+ CREDITS
+ Config_File.class.php
+ README: Implemented plugin architecture.
+
+ * NEWS: *** empty log message ***
+
+2002-01-30 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml: added modifiers wordwrap and indent
+
+2002-01-28 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ docs.sgml:
+ add support for is-modified-since headers, adjust a doc example
+
+2002-01-24 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: cleanup formatting
+
+ * NEWS
+ Smarty.class.php
+ docs.sgml: update ChangeLog, remove insert_tag_check parameter
+
+2002-01-24 Andrei Zmievski <andrei@php.net>
+
+ * plugins/standard.plugin.php: *** empty log message ***
+
+2002-01-24 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: fix syntax error
+
+ * Smarty.class.php: removed unneccesary test from fetch()
+
+2002-01-23 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php: update overlib fixes
+
+ * NEWS: update changelog
+
+ * FAQ
+ NEWS
+ RESOURCES
+ Smarty.addons.php: updated overlib fixes
+
+2001-12-31 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: Fixed compile_id problem.
+
+2001-12-28 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ fixed problem with using assigned var with include_php filepath
+
+2001-12-21 Monte Ohrt <monte@ispi.net>
+
+ * RESOURCES: update RESOURCES
+
+2001-12-20 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ README: update FAQ
+
+2001-12-18 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ docs.sgml
+ Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php: update version numbers
+
+2001-12-18 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: Fixed clear_cache().
+
+2001-12-14 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.addons.php:
+ fixed bug in smarty_make_timestamp introduced in PHP 4.1.0
+
+2001-12-13 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php
+ docs.sgml: update default function args, fix cached insert debug timing
+
+2001-12-12 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: fix syntax error in documentation
+
+ * Smarty.class.php: update default template handling functionality
+
+2001-12-11 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php: update file fetching logic
+
+2001-12-11 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: Added 'script' attribute to {insert..}.
+
+2001-12-10 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php: added default template function handler
+
+ * Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php: update version numbers in files to 1.5.1
+
+2001-12-10 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: Removed error message from the _read_file() method.
+
+ * Smarty.class.php: Fix check for compile and cache IDs.
+
+2001-12-06 Monte Ohrt <monte@ispi.net>
+
+ * QUICKSTART: fix spelling error in QUICKSTART
+
+ * docs.sgml: fixed spelling errors in documenation
+
+ * Smarty_Compiler.class.php
+ docs.sgml
+ Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php: commit 1.5.0 release
+
+ * RESOURCES
+ docs.sgml: added RESOURCES file
+
+2001-12-05 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Refactor.
+
+2001-12-05 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty_Compiler.class.php
+ docs.sgml: added assign to include and php_include
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml: *** empty log message ***
+
+2001-12-04 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty_Compiler.class.php: Formatting.
+
+2001-12-04 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ NEWS
+ Smarty.class.php: update ChangeLog
+
+2001-12-04 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: Formatting.
+
+2001-12-04 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: removed SMARTY_DIR setting in constructor
+
+ * Smarty.class.php: fix Smarty.class.php indention error
+
+ * Smarty.class.php: update trusted logic
+
+2001-12-03 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php:
+ fix up is_secure, is_trusted, make _parse_tpl_path function
+
+ * Smarty.class.php: fix problem with testing SMARTY_DIR as empty
+
+ * NEWS
+ docs.sgml: update documentation, change log
+
+ * Smarty.class.php:
+ update constructor to check for SMARTY_DIR before assigning
+
+2001-12-03 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: *** empty log message ***
+
+2001-12-03 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ INSTALL
+ RELEASE_NOTES: update a few files
+
+ * NEWS
+ QUICKSTART
+ Smarty.class.php
+ docs.sgml: added trusted_dir functionality, cleaned up secure_dir logic
+
+2001-12-03 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * NEWS
+ Smarty.class.php: - Introduced $compile_id class variable.
+ - Fixed a situation where if $cache_id and $compile_id were both null
+ they were passed to auto functions as empty string instead of null.
+
+2001-11-30 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php:
+ change variable names in fetch() fuction to smarty_* to avoid namespace conflicts
+
+ * NEWS
+ Smarty.class.php: fixed bug in _rm_auto with catenated null values
+
+2001-11-29 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty_Compiler.class.php: Added $smarty.section.* syntax.
+
+ * Smarty_Compiler.class.php: Made 'name' attribute optional for {foreach}.
+
+2001-11-29 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ index.php: remove assign "now" in index.tpl
+
+2001-11-29 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php: Fix formatting.
+
+2001-11-28 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.class.php
+ docs.sgml:
+ removed return statements from _read_cache_file (how did they get in there?)
+
+2001-11-27 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml
+ NEWS
+ Smarty.addons.php
+ Smarty.class.php:
+ fixed bugs and added assign attribute to several functions
+
+2001-11-27 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: Some rewording.
+
+ * Smarty_Compiler.class.php: Fix $smarty.capture access.
+
+ * TODO: *** empty log message ***
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ Made {config_load ..} merge globals from each config file only once per scope.
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php: - Added {foreach ...}.
+ - Made certain $smarty.* references handled at compilation time.
+
+2001-11-26 Monte Ohrt <monte@ispi.net>
+
+ * Config_File.class.php
+ NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml: commit cache handler functionality
+
+2001-11-20 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.addons.php
+ Smarty_Compiler.class.php: Various fixes and additions.
+
+ * NEWS
+ index.php: *** empty log message ***
+
+2001-11-05 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: changed _read_file parameter from $end to $lines
+
+ * NEWS
+ Smarty.class.php: fixed is_cache, make cache reading more efficient
+
+2001-11-02 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ NEWS: update FAQ with mailing list Reply-To header FAQ
+
+ * NEWS
+ Smarty.class.php
+ index.php: supress fopen errors, return false if cache file won't load
+
+2001-11-01 Monte Ohrt <monte@ispi.net>
+
+ * QUICKSTART
+ docs.sgml
+ index.php: update QUICKSTART guide with index key example
+
+ * Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml: commit all updates for 1.4.6
+
+2001-11-01 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+2001-10-30 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php: fix assign function problem with empty value passed
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ templates/debug.tpl:
+ fixed bug in assign function when passing an empty value
+
+2001-10-26 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php
+ Smarty.class.php
+ index.php: fix minor typo in debug code
+
+2001-10-26 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Typo.
+
+2001-10-26 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php:
+ update debug console output, handle html encoding correctly
+
+2001-10-26 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ templates/debug.tpl: Debug formatting.
+
+ * Smarty.class.php: Disable rmdir warning.
+
+2001-10-26 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php
+ Smarty.class.php
+ templates/debug.tpl: update debugging to expand array variables
+
+ * Smarty.class.php
+ docs.sgml:
+ update docs for fetching only timestamp with custom template source functions
+
+ * Smarty.addons.php: fix debug console error
+
+2001-10-26 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml: Typos.
+
+ * Smarty.addons.php: Cleanup whitespace.
+
+ * Smarty_Compiler.class.php: Clean up whitespace.
+
+ * Smarty.class.php: Cleaning up code, formatting mostly.
+
+ * NEWS: *** empty log message ***
+
+2001-10-25 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ docs.sgml: update documentation to current version
+
+ * NEWS
+ Smarty.addons.php:
+ updated fetch to give proper warning when fetching unreadable or nonexistant files
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ fixed problem with newline at the end of compiled templates
+
+ * NEWS
+ Smarty.class.php: recompile cache if config file gets modified too.
+
+ * NEWS
+ Smarty.class.php:
+ added feature to regenerate cache if compile_check is enabled and an
+ involved template is modified
+
+2001-10-23 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: fix indent for insert tags in debug console
+
+ * templates/debug.tpl: update debug.tpl file format
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ templates/debug.tpl:
+ update execution time debugging, move into include list
+
+2001-10-10 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ fixed up execution time output in debug console
+
+2001-10-09 Andrei Zmievski <andrei@php.net>
+
+ * Config_File.class.php
+ NEWS
+ Smarty.class.php
+ TODO: Added support for hidden config vars.
+
+2001-10-04 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ templates/debug.tpl: added execution times to debug console
+
+2001-10-02 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Add space.
+
+2001-10-01 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Fix reference to compile_id.
+
+2001-09-28 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php: Added postfilter functions.
+
+2001-09-26 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ docs.sgml: Rename to clear_compiled_tpl().
+
+2001-09-25 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ Fixed line number reporting when removing comments.
+
+2001-09-20 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ RELEASE_NOTES
+ Smarty.addons.php: made html_options output xhtml compatible
+
+2001-09-19 Monte Ohrt <monte@ispi.net>
+
+ * Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ templates/debug.tpl: updated version numbers
+
+2001-09-16 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ NEWS
+ docs.sgml: fix doc error with insert function
+
+2001-09-06 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+2001-08-31 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update ChangeLog
+
+ * overlib.js
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml:
+ update overlib to 3.50, adjust addon code so that the overlib.js file isn't modified
+
+2001-08-31 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: - compile_id changes
+
+ * NEWS
+ Smarty.addons.php: - compile_id support
+ - new options for html_select_date
+
+2001-08-23 Andrei Zmievski <andrei@php.net>
+
+ * TODO: *** empty log message ***
+
+2001-08-10 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ Modified to pass Smarty object as second parameter to insert functions.
+ Also moved _smarty_mod_handler() and _smarty_insert_handler() into the class.
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ Passing Smarty as second parameter to prefilter functions.
+
+2001-08-09 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+2001-08-09 Monte Ohrt <monte@ispi.net>
+
+ * templates/index.tpl
+ Smarty.class.php: add smarty.now variable to template
+
+2001-08-06 Monte Ohrt <monte@ispi.net>
+
+ * templates/index.tpl: change config_load section back to setup
+
+2001-08-06 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php: Optimize a bit.
+
+2001-08-04 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: update capture documentation
+
+2001-08-03 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ NEWS
+ Smarty.class.php:
+ fix bug with URL controlled debugging, works now (Monte)
+
+2001-08-01 Andrei Zmievski <andrei@php.net>
+
+ * Config_File.class.php: *** empty log message ***
+
+ * Smarty_Compiler.class.php
+ Smarty.class.php: - Fixed some E_NOTICE stuff in compiler.
+ - Generalized assign_smarty_interface() a bit.
+
+2001-07-24 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty_Compiler.class.php
+ TODO: See ChangeLog for details.
+
+2001-07-20 Andrei Zmievski <andrei@php.net>
+
+ * Config_File.class.php: Booleanize case-insensitively.
+
+2001-07-17 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update ChangeLog
+
+ * Smarty.class.php
+ docs.sgml: put SMARTY_DIR on Config_File require
+
+2001-07-11 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml
+ FAQ
+ NEWS
+ Smarty.class.php:
+ updated security to not include insecure docs, only warning
+
+2001-07-10 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Adding 'sizeof' as an allowed {if} function.
+
+2001-07-06 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+2001-07-06 Monte Ohrt <monte@ispi.net>
+
+ * Config_File.class.php
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php: update version number to 1.4.4
+
+ * NEWS
+ Smarty.addons.php
+ Smarty_Compiler.class.php
+ docs.sgml
+ templates/header.tpl
+ templates/index.tpl: update documenatation, template examples
+
+2001-07-03 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: Implemented access to request vars via $smarty var.
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ Fixed a bug with parsing function arguments in {if} tags.
+
+2001-06-30 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update ChangeLog
+
+2001-06-29 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php
+ Smarty.class.php
+ docs.sgml
+ overlib.js:
+ moved overlib to separate file, added SMARTY_DIR, documented. added much documentation
+
+2001-06-29 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ RELEASE_NOTES
+ TODO: *** empty log message ***
+
+2001-06-29 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml
+ index.php
+ templates/debug.tpl
+ templates/header.tpl
+ templates/index.tpl: update release notes
+
+2001-06-27 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: *** empty log message ***
+
+ * NEWS
+ Smarty_Compiler.class.php: Implemented 'step' section attribute.
+
+ * Smarty_Compiler.class.php: Negative values of 'max' will mean no max.
+
+ * AUTHORS
+ NEWS: *** empty log message ***
+
+2001-06-26 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ index.php: Added 'max' and 'start' section attributes.
+ Added 'total' and 'iteration' section properties.
+
+2001-06-25 Andrei Zmievski <andrei@php.net>
+
+ * Config_File.class.php
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php: Update version numbers.
+
+2001-06-23 Andrei Zmievski <andrei@php.net>
+
+ * TODO: *** empty log message ***
+
+2001-06-21 Andrei Zmievski <andrei@php.net>
+
+ * Config_File.class.php
+ NEWS: Fixed booleanization bug.
+
+2001-06-20 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml:
+ update documents to reflect changes to cached content & debugging
+
+2001-06-20 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ Smarty.class.php: Remove debug output for cached and fetched cases.
+
+2001-06-20 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: update include_info to false
+
+ * Smarty.class.php
+ docs.sgml
+ index.php
+ templates/footer.tpl:
+ moved debug logic into Smarty completely, created flags for it
+
+2001-06-19 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ Smarty.class.php
+ templates/debug.tpl: *** empty log message ***
+
+ * NEWS
+ Smarty.class.php: Remove unneeded debug functions.
+
+2001-06-19 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml
+ templates/debug.tpl
+ templates/footer.tpl: commit updates, add debug template
+
+2001-06-19 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ TODO:
+ Moved config loading code inside main class, the compiled template now
+ simply calls that method.
+
+2001-06-15 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ templates/index.tpl: * moved config array into class itself
+ * added 'scope' attribute for config_load
+
+ * Smarty_Compiler.class.php
+ Smarty.addons.php
+ Smarty.class.php: Finishing up secure mode.
+
+2001-06-15 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update ChangeLog
+
+ * Smarty_Compiler.class.php: cleaned up logic of if statement security
+
+ * Smarty_Compiler.class.php: update if logic to cover more situations
+
+ * Smarty_Compiler.class.php
+ docs.sgml: update if statement security feature
+
+2001-06-14 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ Smarty.class.php: *** empty log message ***
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ Fixed a bug with quoted strings inside if statements.
+
+2001-06-13 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php
+ Smarty.class.php: added secure_dir array for multiple secure directories
+
+ * Smarty.addons.php: update fetch funtion to respect security setting
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml: update documentation, changelog
+
+ * Smarty.addons.php
+ Smarty.class.php: moved _extract setting to assign functions
+
+ * Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ added assign/unassign custom functions, ability to re-extract tpl_vars
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml
+ index.php: commit security features
+
+2001-06-11 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Version variable typo.
+
+2001-06-05 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php:
+ Create config object in fetch() or just set the config path if it already
+ exists.
+
+2001-06-04 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: *** empty log message ***
+
+ * NEWS
+ Smarty_Compiler.class.php:
+ Fixed a problem with $<number> inside strip tags.
+
+2001-05-31 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Config_File.class.php: Allow empty config_path.
+
+2001-05-29 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ docs.sgml
+ NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php: update version numbers
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml: moved version variable to internal variable
+
+2001-05-22 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php:
+ Moved $_smarty_sections and $_smarty_conf_obj into Smarty class.
+
+2001-05-18 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update ChangeLog
+
+ * FAQ
+ QUICKSTART: update FAQ, QUICKSTART for windows include_path setup
+
+ * configs/test.conf: added configs directory to cvs
+
+2001-05-18 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Use compiler_class for including the file.
+
+2001-05-18 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: fix typo
+
+2001-05-16 Monte Ohrt <monte@ispi.net>
+
+ * README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php: update files to version 1.4.1
+
+ * NEWS: update ChangeLog
+
+2001-05-15 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * index.php: forget that!
+
+ * NEWS
+ Smarty_Compiler.class.php
+ index.php: Fixed a few E_NOTICE warnings.
+
+2001-05-09 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml: update dates versions
+
+2001-05-09 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty.class.php:
+ Use absolute paths when requiring/including Smart components.
+
+ * NEWS: *** empty log message ***
+
+ * Smarty.class.php: Use write mode instead of append.
+
+2001-05-02 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty_Compiler.class.php: Fix indexing by section properties.
+
+2001-05-02 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update changelog
+
+ * Smarty.class.php: remove period from syntax error
+
+2001-05-02 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Double-quote the attribute values by default.
+
+2001-04-30 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ NEWS: added simple {capture} logic
+
+2001-04-30 Andrei Zmievski <andrei@php.net>
+
+ * TODO: *** empty log message ***
+
+ * Smarty_Compiler.class.php
+ Smarty.class.php: Fix passing config vars to included files.
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php: Fix inclusion again.
+
+2001-04-30 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ RELEASE_NOTES
+ Smarty.class.php
+ misc/fix_vars.php
+ NEWS: update paths for windows (c:)
+
+2001-04-28 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php: Fix passing variables to included files.
+
+ * templates/index.tpl: *** empty log message ***
+
+2001-04-27 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Fix includes.
+
+2001-04-26 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php
+ docs.sgml
+ Smarty.class.php: Formatting mostly.
+
+ * Smarty_Compiler.class.php
+ Config_File.class.php: *** empty log message ***
+
+2001-04-26 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ docs.sgml
+ FAQ
+ NEWS
+ QUICKSTART
+ RELEASE_NOTES
+ Smarty.class.php: update docs with new changes
+
+2001-04-26 Andrei Zmievski <andrei@php.net>
+
+ * RELEASE_NOTES: *** empty log message ***
+
+ * docs.sgml
+ templates/index.tpl
+ NEWS
+ Smarty_Compiler.class.php: Added ability to reference object properties.
+
+2001-04-25 Andrei Zmievski <andrei@php.net>
+
+ * README
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml
+ AUTHORS
+ Config_File.class.php
+ CREDITS
+ RELEASE_NOTES
+ NEWS: *** empty log message ***
+
+ * docs.sgml: Docs on new parameter to custom functions.
+
+ * NEWS: *** empty log message ***
+
+ * Smarty_Compiler.class.php:
+ Changing the way tpl vars are referenced and passing smarty object
+ to custom functions.
+
+ * RELEASE_NOTES
+ docs.sgml: Fixing docs a bit.
+
+2001-04-24 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml: Docs for $compiler_class and compiler functions.
+
+ * templates/index.tpl: *** empty log message ***
+
+ * Smarty_Compiler.class.php: Remove debugging.
+
+2001-04-24 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: update compiler function docs
+
+2001-04-24 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ templates/index.tpl: Added compiler function support.
+
+2001-04-24 Monte Ohrt <monte@ispi.net>
+
+ * RELEASE_NOTES
+ Smarty.class.php:
+ update notes, change show_info_header to false by default
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml
+ CREDITS
+ FAQ
+ NEWS
+ README
+ RELEASE_NOTES: update documenation, bug fixes
+
+2001-04-24 Andrei Zmievski <andrei@php.net>
+
+ * misc/fix_vars.php: Hopefully fix for sure.
+
+2001-04-23 Monte Ohrt <monte@ispi.net>
+
+ * misc/fix_vars.php: uncomment copy/unlink
+
+2001-04-23 Andrei Zmievski <andrei@php.net>
+
+ * misc/fix_vars.php: Do it more thoroughly.
+
+ * misc/fix_vars.php: check for }
+
+2001-04-22 Andrei Zmievski <andrei@php.net>
+
+ * misc/fix_vars.php: Fix variable parsing.
+
+2001-04-20 Monte Ohrt <monte@ispi.net>
+
+ * misc/fix_vars.php: fix problem with 4.0.5-dev and preg_replace_callback
+
+2001-04-19 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ docs.sgml
+ misc/fix_vars.php
+ NEWS
+ RELEASE_NOTES
+ Smarty.class.php: update notes/documentation
+
+ * NEWS
+ README
+ RELEASE_NOTES
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml: update files for 1.4.0 release
+
+2001-04-16 Andrei Zmievski <andrei@php.net>
+
+ * misc/fix_vars.php: Added fix_vars.php script.
+
+2001-04-16 Monte Ohrt <monte@ispi.net>
+
+ * QUICKSTART
+ RELEASE_NOTES
+ docs.sgml
+ templates/index.tpl:
+ update RELEASE_NOTES & scripts with new section var syntax
+
+2001-04-13 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: * Implement new variable format parser.
+ * Optimizing config load a bit.
+
+2001-04-13 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ NEWS
+ RELEASE_NOTES
+ Smarty.class.php:
+ added $check_cached_insert_tags to speed up cached pages if
+ {insert ...} is not used (Monte)
+
+2001-04-12 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ RELEASE_NOTES: *** empty log message ***
+
+ * Smarty_Compiler.class.php: Remove redundant functions.
+
+ * Smarty.class.php: Formatting.
+
+2001-04-12 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: update file: parsing
+
+ * Smarty.class.php
+ docs.sgml: update documentation
+
+2001-04-12 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ TODO: *** empty log message ***
+
+2001-04-11 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ QUICKSTART
+ RELEASE_NOTES: added RELEASE_NOTES file to cvs
+
+ * NEWS
+ docs.sgml: update ChangeLog, update documentation
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ templates/index.tpl:
+ update Smarty to compile at run-time. added ability to get files from
+ absolute paths, added work around for LOCK_EX and windows, changed a few
+ file permissions to be more secure.
+
+2001-03-29 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.addons.php:
+ allow arbitrary date strings instead of just timestamps
+
+2001-03-28 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ docs.sgml
+ FAQ
+ NEWS
+ README
+ Smarty.addons.php:
+ update version in class, update docs for count_ and new vars
+
+ * templates/index.tpl
+ docs.sgml: update docs, example template
+
+2001-03-28 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Some variable renaming.
+
+2001-03-23 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php
+ NEWS: Fixed nested include infinite repeat bug.
+
+2001-03-23 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: fix version number
+
+ * Smarty.class.php
+ NEWS: added optional HTML header to output
+
+2001-03-22 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Fixed inclusion of dynamic files.
+
+2001-03-16 Andrei Zmievski <andrei@php.net>
+
+ * Smarty_Compiler.class.php: Fixing the config_load scoping.
+
+ * Smarty_Compiler.class.php: making config variables global for now.
+
+2001-03-15 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty_Compiler.class.php:
+ * Includes are now always done via generated function call to protect
+ namespace.
+ * config_load now always uses global config object to improve
+ performance.
+
+2001-03-13 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: update math documentation with format attribute
+
+2001-03-11 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml
+ NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php: update math function with format attribute
+
+2001-03-10 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php: *** empty log message ***
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php: Added html_select_time custom function.
+
+2001-03-08 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php
+ NEWS
+ README
+ Smarty.addons.php: rename 1.3.1b to 1.3.1pl1
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php: update version numbers, changelog
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php:
+ moved _syntax_error to Smarty_Compiler.class.php
+
+ * Smarty.class.php
+ docs.sgml:
+ missing _syntax_error function recovered. fixed minor syntax in docs
+
+2001-03-07 Monte Ohrt <monte@ispi.net>
+
+ * QUICKSTART
+ README
+ Smarty.addons.php
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ BUGS
+ INSTALL
+ NEWS: update everything to 1.3.1
+
+2001-03-03 Monte Ohrt <monte@ispi.net>
+
+ * Smarty_Compiler.class.php
+ Smarty.class.php: fixed bug with cached insert tags
+
+2001-03-02 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ Smarty_Compiler.class.php:
+ fix cache fuctions with separated compiled class
+
+ * FAQ
+ NEWS
+ docs.sgml: update changelog
+
+2001-03-02 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty_Compiler.class.php: Added 'first' and 'last' section properties.
+
+2001-03-02 Monte Ohrt <monte@ispi.net>
+
+ * TODO: remove compiling separation TODO
+
+ * Smarty_Compiler.class.php
+ Smarty.addons.php
+ Smarty.class.php: update function headers
+
+ * templates/index.tpl
+ NEWS
+ Smarty.class.php
+ Smarty_Compiler.class.php
+ index.php: split out compiling code for faster execution
+
+ * Smarty.class.php: fixed a few warning messages
+
+ * Smarty.addons.php
+ Smarty.class.php
+ docs.sgml
+ NEWS: added fetch, unregister mod/fun, updated docs
+
+2001-03-01 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php: added "int" to available list
+
+ * docs.sgml
+ FAQ
+ Smarty.class.php: update FAQ, add math functions & update documetation
+
+ * index.php
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml: fixed literal tags and other optional delimiters
+
+2001-02-26 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php:
+ Added index_prev, index_next section properties and ability to
+ index by them.
+
+ * NEWS
+ Smarty.addons.php
+ Smarty.class.php: Reverting the plugins patch - needs more thought.
+
+ * Smarty.class.php: Fixing plugin loading.
+
+2001-02-23 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ Smarty.class.php
+ plugins/standard.plugin.php
+ NEWS: Added plugin functionality.
+
+2001-02-22 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml
+ templates/index.tpl
+ NEWS
+ README
+ Smarty.class.php: fixed issue with php tags executed in literal blocks
+
+2001-02-21 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update changelog for LGPL change
+
+ * Smarty.class.php
+ docs.sgml
+ README
+ Smarty.addons.php: updated version numbers to 1.3.0
+
+ * NEWS
+ templates/index.tpl: update changelog, rearrange index.tpl file
+
+2001-02-21 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: *** empty log message ***
+
+2001-02-21 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: update parameters for is_cached and fetch
+
+2001-02-21 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: *** empty log message ***
+
+2001-02-21 Monte Ohrt <monte@ispi.net>
+
+ * NEWS
+ Smarty.addons.php
+ docs.sgml: update docs, remove header function from addons
+
+2001-02-20 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ NEWS: update changelog
+
+ * TODO: update todo
+
+ * TODO: update todo list
+
+ * Smarty.class.php: update php tag handling logic
+
+2001-02-19 Monte Ohrt <monte@ispi.net>
+
+ * index.php
+ Config_File.class.php
+ FAQ
+ Smarty.class.php
+ docs.sgml: fixed <?php tag at beginning of files, updated docs
+
+2001-02-19 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php: *** empty log message ***
+
+2001-02-13 Andrei Zmievski <andrei@php.net>
+
+ * TODO: *** empty log message ***
+
+2001-02-12 Andrei Zmievski <andrei@php.net>
+
+ * templates/index.tpl
+ Smarty.class.php: *** empty log message ***
+
+2001-02-10 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: remove unneeded preg_match
+
+ * Smarty.class.php: remove comment
+
+ * Smarty.class.php: updated php escape to handle <script language="php">
+
+ * NEWS
+ Smarty.class.php: fix php tag escapement logic
+
+ * NEWS: commit changelog
+
+ * docs.sgml: update header docs
+
+ * docs.sgml
+ Smarty.addons.php
+ Smarty.class.php: added header custom function
+
+2001-02-09 Monte Ohrt <monte@ispi.net>
+
+ * index.php
+ templates/header.tpl
+ templates/index.tpl
+ INSTALL
+ QUICKSTART
+ docs.sgml: update documentation, add examples to test script.
+
+2001-02-08 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: *** empty log message ***
+
+2001-02-08 Monte Ohrt <monte@ispi.net>
+
+ * COPYING.lib: added COPYING.lib
+
+ * COPYING
+ Config_File.class.php
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml: changed license to LGPL for commercial use
+
+ * docs.sgml
+ Smarty.class.php: fix clear_assign syntax error
+
+2001-02-07 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: added ability to pass array to clear_assign
+
+ * index.php
+ templates/index.tpl
+ docs.sgml:
+ update documentation, remove tests from index file and template
+
+2001-02-07 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php: Adding file locking.
+
+ * templates/index.tpl
+ Smarty.addons.php
+ Smarty.class.php
+ index.php: More cache work.
+
+2001-02-06 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml
+ Smarty.class.php:
+ change register_ function names, update documents with tables
+
+2001-02-06 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ templates/index.tpl: Reworking and optimizing the cache system.
+
+ * Smarty.class.php: Restoring ?> in patterns.
+
+2001-02-05 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ docs.sgml: update cache directory creation logic
+
+2001-02-05 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Removing once-only subpattern for now..
+
+ * Smarty.class.php: Fix modifier arg parsing.
+
+2001-02-02 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ Smarty.class.php
+ templates/index.tpl: See changelog.
+
+2001-02-01 Andrei Zmievski <andrei@php.net>
+
+ * README: *** empty log message ***
+
+ * Smarty.class.php: Use 'echo' instead of 'print'.
+
+ * Smarty.addons.php: *** empty log message ***
+
+2001-02-01 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: rearranged variables at top of script
+
+2001-02-01 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Retabbing.
+
+ * templates/index.tpl
+ Smarty.class.php
+ index.php: *** empty log message ***
+
+2001-02-01 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: update caching logic
+
+ * Smarty.class.php: fixed clear_all_cache bugs
+
+ * Smarty.class.php: fix .cache check
+
+ * docs.sgml
+ FAQ
+ Smarty.class.php: update .che to .cache
+
+ * FAQ
+ Smarty.class.php
+ docs.sgml: updated docs for caching, added clear_all_cache() directive
+
+2001-01-31 Monte Ohrt <monte@ispi.net>
+
+ * index.php
+ templates/index.tpl
+ docs.sgml: upated docs for date_format and html_options
+
+2001-01-31 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty.addons.php
+ index.php: Added ability to pass 'options' attribute to html_options.
+
+ * Smarty.addons.php
+ Smarty.class.php
+ docs.sgml
+ index.php
+ templates/index.tpl
+ Config_File.class.php
+ NEWS
+ README: Reworking, simplifying, and speeding up cache implementation.
+ Fixing the infelicity where you couldn't have '|' and ':' inside
+ quoted modifier arguments.
+
+2001-01-31 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php
+ index.php
+ templates/index.tpl: removed DEBUG lines
+
+2001-01-30 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: changed default expire to 3600
+
+ * Config_File.class.php
+ NEWS
+ README
+ Smarty.addons.php
+ Smarty.class.php: updated version numbers
+
+ * docs.sgml
+ NEWS
+ Smarty.class.php:
+ added caching, force compile, force cache, misc performance updates
+
+2001-01-30 Andrei Zmievski <andrei@php.net>
+
+ * NEWS: *** empty log message ***
+
+ * Smarty.class.php
+ templates/index.tpl: Remove debug message.
+
+ * Smarty.class.php
+ templates/index.tpl: Fixing the compile directory mayhem...
+
+ * Smarty.class.php:
+ Fix problem with {strip} around {section} and {include}
+
+ * Smarty.addons.php: *** empty log message ***
+
+2001-01-29 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ NEWS
+ README
+ Smarty.class.php: fixed PHP_VERSION check, misc doc updates
+
+ * index.php
+ Config_File.class.php
+ NEWS
+ QUICKSTART
+ README
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml: updated for 1.2.1 compile_dir changes, misc doc updates
+
+2001-01-26 Monte Ohrt <monte@ispi.net>
+
+ * BUGS
+ README: update BUGS and README files
+
+ * FAQ: updated FAQ
+
+ * Config_File.class.php
+ FAQ
+ NEWS
+ README
+ Smarty.addons.php
+ docs.sgml
+ templates/index.tpl
+ AUTHORS: update again
+
+2001-01-26 Andrei Zmievski <andrei@php.net>
+
+ * docs.sgml
+ NEWS
+ README
+ Smarty.class.php
+ templates/index.tpl: *** empty log message ***
+
+ * Smarty.class.php
+ index.php
+ templates/index.tpl: Added ability to index by key.
+
+2001-01-25 Monte Ohrt <monte@ispi.net>
+
+ * NEWS: update changelog
+
+ * README
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml
+ AUTHORS: updated versions to 1.1.0
+
+ * docs.sgml
+ templates/index.tpl
+ Config_File.class.php
+ Smarty.addons.php
+ Smarty.class.php: update copyright notice
+
+ * Config_File.class.php
+ Smarty.addons.php
+ Smarty.class.php
+ docs.sgml: added misc info
+
+2001-01-24 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.addons.php
+ index.php
+ templates/index.tpl
+ Config_File.class.php: initial commit
+
+2001-01-23 Monte Ohrt <monte@ispi.net>
+
+ * docs.sgml: fix typo
+
+2001-01-22 Monte Ohrt <monte@ispi.net>
+
+ * doc.sgm
+ docs.sgml: updated docs, renamed file
+
+ * FAQ: updated FAQ
+
+ * NEWS
+ README: updated Changelog and Readme
+
+ * doc.sgm: updated doc.sgm error
+
+ * AUTHORS
+ COPYING
+ INSTALL
+ NEWS
+ QUICKSTART: misc doc changes, added AUTHORS, COPYING
+
+2001-01-22 Andrei Zmievski <andrei@php.net>
+
+ * NEWS
+ templates/index.tpl: *** empty log message ***
+
+ * Smarty.class.php
+ templates/index.tpl:
+ Fixed bug that wouldn't let you do specify non-array values for 'loop'
+ attribute.
+
+2001-01-22 Monte Ohrt <monte@ispi.net>
+
+ * QUICKSTART: updated QUICKSTART
+
+ * BUGS
+ FAQ
+ INSTALL
+ README
+ doc.sgm: added BUGS and INSTALL, updated docs, FAQ, README
+
+2001-01-21 Monte Ohrt <monte@ispi.net>
+
+ * FAQ
+ doc.sgm: updates to FAQ and docs
+
+2001-01-19 Monte Ohrt <monte@ispi.net>
+
+ * FAQ: initial commit of FAQ
+
+ * QUICKSTART
+ README
+ doc.sgm
+ index.php:
+ updated README, doc.sgm with preg_replace() parameter issue. also removed "./" from index.php file
+
+ * NEWS: initial commit of changelog
+
+ * doc.sgm
+ QUICKSTART: update quickstart text
+
+2001-01-19 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Fix the compiled template check.
+
+2001-01-18 Andrei Zmievski <andrei@php.net>
+
+ * doc.sgm: *** empty log message ***
+
+2001-01-18 Monte Ohrt <monte@ispi.net>
+
+ * index.php
+ templates/index.tpl
+ QUICKSTART
+ Smarty.addons.php
+ Smarty.class.php
+ doc.sgm: update changes
+
+2001-01-18 Andrei Zmievski <andrei@php.net>
+
+ * QUICKSTART
+ Smarty.addons.php: *** empty log message ***
+
+2001-01-18 Monte Ohrt <monte@ispi.net>
+
+ * QUICKSTART
+ doc.sgm: add QUICKSTART, update docs for default modifier
+
+ * Smarty.addons.php
+ Smarty.class.php: added default modifier
+
+ * README
+ Smarty.addons.php
+ Smarty.class.php
+ doc.sgm
+ templates/index.tpl: added dislaimers
+
+2001-01-18 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: *** empty log message ***
+
+2001-01-16 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ templates/index.tpl: Implement 'div by'.
+
+2001-01-12 Monte Ohrt <monte@ispi.net>
+
+ * doc.sgm: update docs
+
+ * doc.sgm: doc changes
+
+ * doc.sgm: update docs
+
+2001-01-12 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ doc.sgm: *** empty log message ***
+
+ * Smarty.class.php: Fix template traversal.
+
+2001-01-11 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: *** empty log message ***
+
+2001-01-09 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ Smarty.class.php: *** empty log message ***
+
+2001-01-09 Monte Ohrt <monte@ispi.net>
+
+ * doc.sgm: update manual
+
+2001-01-05 Monte Ohrt <monte@ispi.net>
+
+ * doc.sgm
+ Smarty.addons.php: commit changes
+
+2001-01-04 Monte Ohrt <monte@ispi.net>
+
+ * doc.sgm
+ templates/index.tpl
+ Smarty.class.php: update changes
+
+ * index.php
+ Smarty.addons.php
+ doc.sgm: add documentation
+
+2001-01-02 Monte Ohrt <monte@ispi.net>
+
+ * index.php
+ templates/index.tpl
+ Smarty.addons.php
+ Smarty.class.php: prepend insert_ to insert tag functions
+
+ * Smarty.class.php
+ index.php
+ templates/index.tpl: remove caching logic
+
+ * README
+ Smarty.class.php
+ index.php
+ templates/index.tpl: update changes
+
+2000-12-27 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ templates/header.tpl
+ templates/index.tpl
+ Smarty.addons.php: *** empty log message ***
+
+2000-12-21 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php: Fix access to template variables.
+
+ * Smarty.class.php
+ templates/header.tpl:
+ Added support for passing variables to included files.
+
+2000-12-20 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php:
+ Added support for inserting results of function processing a template.
+
+2000-12-18 Monte Ohrt <monte@ispi.net>
+
+ * Smarty.class.php: added string_format function
+
+ * Smarty.addons.php: update format to string_format
+
+ * README
+ Smarty.addons.php
+ Smarty.class.php: added format addon function
+
+2000-12-13 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ Smarty.class.php: Fix sectionelse.
+
+2000-12-07 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.addons.php
+ Smarty.class.php
+ templates/index.tpl: *** empty log message ***
+
+2000-12-04 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ templates/index.tpl
+ Smarty.addons.php: *** empty log message ***
+
+2000-11-27 Andrei Zmievski <andrei@php.net>
+
+ * templates/index.tpl
+ Smarty.class.php: *** empty log message ***
+
+2000-11-22 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ templates/index.tpl: *** empty log message ***
+
+2000-11-21 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ templates/index.tpl
+ Smarty.addons.php: *** empty log message ***
+
+2000-11-20 Andrei Zmievski <andrei@php.net>
+
+ * templates/index.tpl
+ Smarty.class.php
+ Smarty.addons.php
+ index.php: *** empty log message ***
+
+ * Smarty.class.php
+ index.php
+ templates/index.tpl: Made sections work mostly.
+
+2000-11-19 Andrei Zmievski <andrei@php.net>
+
+ * index.php
+ templates/index.tpl: *** empty log message ***
+
+2000-11-17 Andrei Zmievski <andrei@php.net>
+
+ * Smarty.class.php
+ Smarty.addons.php: *** empty log message ***
+
+2000-11-15 Monte Ohrt <monte@ispi.net>
+
+ * index.php
+ templates/footer.tpl
+ templates/header.tpl
+ templates/index.tpl: added template files to cvs dir
+
+ * README
+ Smarty.class.php: commit changes
+
+2000-08-08 Monte Ohrt <monte@ispi.net>
+
+ * README
+ Smarty.class.php: update include path bug
+
+ * README: add README file
+
+ * Smarty.class.php: New file.
+
+ * Smarty.class.php: initial import
+
--- /dev/null
+QUESTION INDEX
+--------------
+
+GENERAL
+
+Q: What is Smarty?
+Q: What's the difference between Smarty and other template engines?
+Q: What do you mean "Compiled PHP Scripts" ?
+Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
+Q: Why does smarty have a built in cache? Wouldn't it be better to handle this
+ in a separate class?
+Q: Is Smarty faster than <insert other PHP template engine>?
+Q: How can I be sure to get the best performance from Smarty?
+Q: Do you have a mailing list?
+Q: Can you change the mailing list so reply-to sends to the list and not the
+ user?
+
+TROUBLESHOOTING
+
+Q: Smarty doesn't work.
+Q: I get the following error when running Smarty:
+ Warning: Smarty error: problem creating directory "templates_c/239/239105369"
+ in /path/to/Smarty.class.php on line 542
+Q: I get the following error when running Smarty:
+ Warning: Wrong parameter count for preg_replace() in
+ Smarty.class.php on line 371
+Q: I get this error when passing variables to {include}:
+ Fatal error: Call to undefined function: get_defined_vars() in
+ /path/to/Smarty/templates_c/index.tpl.php on line 8
+Q: I get PHP errors in my {if} tag logic.
+Q: I'm changing my php code and/or templates, and my results are not getting
+ updated.
+Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
+ also zero length.
+Q: The template goes into an infinite loop when I include included templates
+ that pass local variables
+Q: Javascript is causing Smarty errors in my templates.
+Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
+
+MISC
+
+Q: Can I use Macromedia's Dreamweaver to edit my templates?
+Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
+ HREF link. How do I get around this?
+
+HOWTO
+
+Q: How do I generate different cache files per template based on arguments
+ passed to the page?
+Q: How do I pass a template variable as a parameter? {function param={$varname}}
+ does not work.
+Q: How do I include cached template(s) within a non-cached template?
+
+
+GENERAL
+-------
+
+Q: What is Smarty?
+A: Smarty is a template engine for PHP... but be aware this isn't just another
+ PHP template engine. It's much more than that.
+
+Q: What's the difference between Smarty and other template engines?
+A: Most other template engines for PHP provide basic variable substitution and
+ dynamic block functionality. Smarty takes a step further to be a "smart"
+ template engine, adding features such as configuration files, template
+ functions, variable modifiers (see the docs!) and making all of this
+ functionality as easy as possible to use for both programmers and template
+ designers. Smarty also compiles the templates into PHP scripts, eliminating
+ the need to parse the templates on every invocation, making Smarty extremely
+ scalable and manageable for large application needs.
+
+Q: What do you mean "Compiled PHP Scripts" ?
+A: Smarty reads the template files and creates PHP scripts from them. Once
+ these PHP scripts are created, Smarty executes these, never having to parse
+ the template files again. If you change a template file, Smarty will
+ recreate the PHP script for it. All this is done automatically by Smarty.
+ Template designers never need to mess with the generated PHP scripts or even
+ know of their existance. (NOTE: you can turn off this compile checking step
+ in Smarty for increased performance.)
+
+Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
+A: You certainly can, and we highly recommend it! What PHPA does is caches
+ compiled bytecode of your PHP scripts in shared memory or in a file. This
+ speeds up server response and saves the compilation step. Smarty creates PHP
+ scripts, which PHPA will cache nicely. Now, Smarty's built-in cache is
+ something completely different. It caches the _output_ of the template
+ contents. For example, if you have a template that requires several database
+ queries, Smarty can cache this output, saving the need to call the database
+ every time. Smarty and PHPA (or Zend Cache) complement each other nicely. If
+ performance is of the utmost importance, we would recommend using one of
+ these with any PHP application, using Smarty or not. As you can see in the
+ benchmarks, Smartys performance _really_ excels in combination with a PHP
+ accelerator.
+
+Q: Why does Smarty have a built in cache? Wouldn't it be better to handle this
+ in a separate class?
+A: Smarty's caching functionality is tightly integrated with the template
+ engine, making it quite a bit more flexible than a simple caching wrapper.
+ For instance, you can cache select portions of a template page. Let's say
+ you have a polling box on your site. With Smarty, you can leave the poll
+ dynamic and cache the rest of the page. You can also pass templates
+ multiple cache ids, meaning that a template can have several caches
+ depending on URL, cookies, etc.
+
+Q: Is Smarty faster than <insert other PHP template engine>?
+A: See the benchmark page for some performance comparisons. Smarty's approach
+ to templates is a bit different from some languages: it compiles templates
+ into PHP scripts instead of parsing them on each invocation. This usually
+ results in great performance gains, especially with complex templates.
+ Coupled with the built-in caching of Smarty templates, the performance is
+ outstanding.
+
+Q: How can I be sure to get the best performance from Smarty?
+A: Be sure you set $compile_check=false once your templates are initially
+ compiled. This will skip the unneeded step of testing if the template has
+ changed since it was last compiled. If you have complex pages that don't
+ change too often, turn on the caching engine and adjust your application so
+ it doesn't do unnecessary work (like db calls) if a cached page is
+ available. See the documentation for examples.
+
+Q: Do you have a mailing list?
+A: We have a few mailing lists. "general" for you to share your ideas or ask
+ questions, "dev" for those interested in the development efforts of Smarty,
+ and "cvs" for those that would like to track the updates made in the cvs
+ repository.
+
+ send a blank e-mail message to:
+ smarty-general-subscribe@lists.php.net (subscribe to the general list)
+ smarty-general-unsubscribe@lists.php.net (unsubscribe from the general list)
+ smarty-general-digest-subscribe@lists.php.net (subscribe to digest)
+ smarty-general-digest-unsubscribe@lists.php.net (unsubscribe from digest)
+ smarty-dev-subscribe@lists.php.net (subscribe to the dev list)
+ smarty-dev-unsubscribe@lists.php.net (unsubscribe from the dev list)
+ smarty-cvs-subscribe@lists.php.net (subscribe to the cvs list)
+ smarty-cvs-unsubscribe@lists.php.net (unsubscribe from the cvs list)
+ You can also browse the mailing list archives at
+ http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
+
+
+
+Q: Can you change the mailing list so Reply-To sends to the list and not the
+ user?
+A: Yes we could, but no we won't. Use "Reply-All" in your e-mail client to send
+ to the list. http://www.unicom.com/pw/reply-to-harmful.html
+
+TROUBLESHOOTING
+---------------
+
+Q: Smarty doesn't work.
+A: You must be using PHP 4.0.6 or later if you use any version of Smarty
+ past 2.0.1. Read the BUGS file for more info.
+
+Q: I get the following error when running Smarty:
+ Warning: Smarty error: problem creating directory "templates_c/239/239105369"
+ in /path/to/Smarty.class.php on line 542
+A: Your web server user does not have permission to write to the templates_c
+ directory, or is unable to create the templates_c directory. Be sure the
+ templates_c directory exists in the location defined in Smarty.class.php,
+ and the web server user can write to it. If you do not know the web server
+ user, chmod 777 the templates_c directory, reload the page, then check the
+ file ownership of the files created in templates_c. Or, you can check the
+ httpd.conf (usually in /usr/local/apache/conf) file for this setting:
+ User nobody
+ Group nobody
+
+Q: I get the following error when running Smarty: Warning: Wrong parameter
+ count for preg_replace() in Smarty.class.php on line 371
+A: preg_replace had a parameter added in PHP 4.0.2 that Smarty
+ requires. Upgrade to at least 4.0.6 to fix all known PHP issues with
+ Smarty.
+
+Q: I get this error when passing variables to {include}:
+ Fatal error: Call to undefined function: get_defined_vars() in
+ /path/to/Smarty/templates_c/index.tpl.php on line 8
+A: get_defined_vars() was added to PHP 4.0.4. If you plan on passing
+ variables to included templates, you will need PHP 4.0.6 or later.
+
+Q: I get PHP errors in my {if} tag logic.
+A: All conditional qualifiers must be separated by spaces. This syntax will not
+ work: {if $name=="Wilma"} You must instead do this: {if $name == "Wilma"}.
+ The reason for this is syntax ambiguity. Both "==" and "eq" are equivalent
+ in the template parser, so something like {if $nameeq"Wilma"} wouldn't be
+ parsable by the tokenizer.
+
+Q: I'm changing my php code and/or templates, and my results are not getting
+ updated.
+A: This may be the result of your compile or cache settings. If you are
+ changing your php code, your templates will not necessarily get recompiled
+ to reflect the changes. Use $force_compile during develpment to avoid these
+ situations. Also turn off caching during development when you aren't
+ specifically testing it. You can also remove everything from your
+ compile_dir and cache_dir and reload the page to be sure everything gets
+ regenerated.
+
+Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
+ also zero length.
+A: There seems to be a problem with some W2k machines and exclusive file
+ locking. Comment out the flock() call in _write_file to get around this,
+ although be aware this could possibly cause a problem with simultaneous
+ writes to a file, especially with caching turned on. NOTE: As of Smarty
+ 1.4.0, a workaround was put in place that should solve this.
+
+Q: The template goes into an infinite loop when I include included templates
+ that pass local variables
+A: This was fixed in 1.3.2 (new global attribute)
+
+Q: Javascript is causing Smarty errors in my templates.
+A: Surround your javascript with {literal}{/literal} tags. See the docs.
+
+Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
+A: Use $smarty->use_sub_dirs = false when running php in safe mode.
+
+MISC
+----
+
+Q: Can I use Macromedia's Dreamweaver to edit my templates?
+A: Certainly. You might want to change your tag delimiters from {} to something
+ that resembles valid HTML, like <!--{ }--> or <{ }> or something similar.
+ This way the editor won't view the template tags as errors.
+
+Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
+ HREF link. How do I get around this?
+A: In Edit - Properties - Rewrite HTML you can specify if Dreamweaver should
+ change special letters to %-equivalent or not. The default is on which
+ produces this error.
+
+HOWTO
+-----
+
+Q: How do I generate different cache files per template based on arguments
+ passed to the page?
+A: Use your $REQUEST_URI as the cache_id when fetching the page:
+
+ global $REQUEST_URI; // if not already present
+ $smarty->display('index.tpl',$REQUEST_URI);
+
+ This will create a separate cache file for each unique URL when you call
+ index.tpl. See the documentation for display() and fetch()
+
+Q: How do I pass a template variable as a parameter? {function param={$varname}}
+ does not work.
+A: {function param=$varname} (You cannot nest template delimiters.)
+
+Q: How do I include cached template(s) within a non-cached template?
+A: One way to do it:
+
+ $smarty->caching = true;
+ $tpl1 = $smarty->fetch("internal1.tpl");
+ $tpl2 = $smarty->fetch("internal2.tpl");
+ $tpl3 = $smarty->fetch("internal3.tpl");
+
+ $smarty->assign("tpl1_contents",$tpl1);
+ $smarty->assign("tpl2_contents",$tpl2);
+ $smarty->assign("tpl3_contents",$tpl3);
+
+ $smarty->caching = false;
+ $smarty->display('index.tpl');
+
+ index.tpl
+ ---------
+
+ <table>
+ <tr>
+ <td>{$tpl1_contents}</td>
+ <td>{$tpl2_contents}</td>
+ <td>{$tpl3_contents}</td>
+ </tr>
+ </table>
+
+
+
+
+ Another approach:
+
+ You could write a custom insert function to fetch your internal
+ templates:
+
+ <table>
+ <tr>
+ <td>{insert name=fetch_tpl tpl="internal1.tpl"}</td>
+ <td>{insert name=fetch_tpl tpl="internal2.tpl"}</td>
+ <td>{insert name=fetch_tpl tpl="internal3.tpl"}</td>
+ </tr>
+ </table>
--- /dev/null
+REQUIREMENTS:
+
+Smarty requires PHP 4.0.6 or later.
+See the on-line documentation for complete install instructions.
+
+INSTALLATION (quick):
+
+* copy the files under the libs/ directory to a directory that is in your PHP
+ include_path, or set the SMARTY_DIR constant and put them in this directory.
+ (if you upgrade from versions before 2.5.0 be aware that up to Smarty 2.4.2
+ all necessary files where in the distribution's root directory, but are now
+ in libs/.)
+
+* for each application using Smarty, create a "templates", "configs", and a
+ "templates_c" directory, be sure to set the appropriate directory settings in
+ Smarty for them. If they are located in the same directory as your
+ application, they shouldn't need to be modified. Be sure the "templates_c"
+ directory is writable by your web server user (usually nobody). chown
+ nobody:nobody templates_c; chmod 700 templates_c You can also chmod 777 this
+ directory, but be aware of security issues for multi-user systems. If you are
+ using Smarty's built-in caching, create a "cache" directory and also chown
+ nobody:nobody.
+
+* setup your php and template files. A good working example is in the on-line
+ documentation.
+
+* TECHNICAL NOTE: If you do not have access to the php.ini file, you can change
+ non-server settings (such as your include_path) with the ini_set() command.
+ example: ini_set("include_path",".:/usr/local/lib/php");
--- /dev/null
+Version 2.6.26 (June 18th, 2009)
+-------------------------------
+- revert super global access changes, and instead rely on
+ USE_SUPER_GLOBALS for security
+
+Version 2.6.25 (May 19th, 2009)
+-------------------------------
+- fix E_NOTICE when sessions are disabled (mohrt)
+
+Version 2.6.24 (May 16th, 2009)
+-------------------------------
+- fix problem introduced with super global changes (mohrt)
+
+Version 2.6.23 (May 13th, 2009)
+-------------------------------
+- strip backticks from {math} equations (mohrt)
+- make PHP super globals read-only from template (mohrt)
+- throw error when template exists but not readable (mohrt)
+
+Version 2.6.22 (Dec 17th, 2008)
+-------------------------------
+
+- back out method chaining, bug in some versions of PCRE causes errors (mohrt)
+
+Version 2.6.21 (Dec 2nd, 2008)
+------------------------------
+
+- fix function injection security hole closed (U.Tews)
+- fix pass expiration time at cache_handler_fuc call in core.write_cache_file.php (U.Tews)
+- Update of compiler.class.php to allow method chaining for PHP4 and PHP5 (U.Tews)
+
+Version 2.6.20 (Feb 15th, 2008)
+-------------------------------
+
+- fix cache tag bug when multiple cache tags on a page (mankyd,
+ mohrt)
+- fix /e tag checking when using arrays with regex_replace
+ (mohrt)
+- fix that function results can be used with condition like "is even" in
+ {if} tags (U.Tews)
+- fix handling of non-empty <pre>-tags and empty <textarea>- and
+ <script>-tags (Spuerhund, messju)
+
+Version 2.6.19 (Feb 11th, 2008)
+-------------------------------
+
+- fix regex_replace allowing \0 in the search string (c960657,
+ monte)
+- add append feature to {capture} (jablko, monte)
+- fix when (un)registering filters with the same method name but different class
+ name (danilo)
+- fix calling registered objects' methods with an empty argument list
+ (marcello, messju)
+
+Version 2.6.18 (Mar 7th, 2007)
+------------------------------
+
+- fix html_select_date separator when parts are missing (hayk,
+ monte)
+- fix broken detection of non-cached blocks introduced in 2.6.17
+ (messju)
+
+Version 2.6.17 (Mar 5th, 2007)
+------------------------------
+
+- fix php handling (monte, boots, danilo)
+- fix handling of plugin tags directly followed by an else tag (Fahr, danilo)
+- fix handling of $etc in the truncate modifier when $etc is longer
+ than $length (Sylvinus, messju)
+- fix handling of %I with mysql timestamps in the date_format modifier
+ (danilo, boots)
+- update smarty_core_write_file() and smarty_modifier_date_format() to better
+ recognize Windows (boots, danilo)
+- emulate %h, %n, %r, %R, %t in the date_format modifier on Windows
+ (danilo, boots)
+
+Version 2.6.16 (Dec 1st, 2006)
+------------------------------
+
+- fixed replacement bug in trimwhitespace output filter that was introduced
+ in the last release (Spuerhund, boots)
+
+Version 2.6.15 (Nov 30th, 2006)
+-------------------------------
+
+- change file writing semantics in smarty_core_write_file() to unlink() only
+ when rename() fails or a Windows system is detected (c960657, boots)
+- update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug
+ output and apply a Smarty based color scheme (cybot, boots)
+- enhance reporting precision of debug_print_var modifier (cybot, boots)
+- make html_select_date work consistently with 0000-00-00 00:00:00 and
+ 0000-00-00 inputs (cybot, boots)
+- fix wrong handling of insert's name attribute. (messju)
+- fix false replacement of "$t" inside double quotes (checat, messju)
+- added support for column headings and caption element to html_table and
+ updated the output to use thead/tbody elements (boots)
+- fixed ordering of replacements in trimwhitespace output filter (Getty, boots)
+- update mailto function plugin to work around a firefox/thunderbird
+ escaping bug (elijahlofgren, boots)
+- emulate %l in the date_format modifier on windows (boots)
+- fix handling of apostrophes in capitalize modifier (Alec Smecher, boots)
+
+Version 2.6.14 (May 28th, 2006)
+-------------------------------
+
+- fix compiler bug allowing php tags in secure templates
+ (boots,monte)
+- un-hide hidden xml open tags (boots)
+- fix handling of block-methods of registered objects (El Hombre Gris,
+ messju)
+
+Version 2.6.13 (March 9th, 2006)
+--------------------------------
+
+ - update regex_replace, removing possible use of "e" modifier
+
+Version 2.6.12 (Jan 18th, 2006)
+-------------------------------
+
+ - fix improper use of references in the compiler handling cached
+ attributes and in compiled code handling block plugins (messju)
+ - make Smarty::_read_file() work on latest php (messju)
+ - fixed improper tokenization of certain inline math expressions (boots)
+
+Version 2.6.11 (Dec 14, 2005)
+-----------------------------
+
+ - fixed code generation of non-cacheable blocks to play well with php's
+ "Alternative syntax for control structures" (kihara, messju)
+ - fix handling of multiple identical inserts in one display()-call (messju)
+ - replace {} string access with equivalent substr() to avoid E_STRICT
+ warnings in PHP 5.1 (boots)
+ - return valid reference in get_config_vars() when given var is
+ non-existant (Thomas Schulz, boots)
+ - plugin html_image: fix incorrect secure_dir error when
+ file doesn't exist (monte)
+ - plugin html_image: add path_prefix param (monte)
+ - add char_set parameter to escape modifier (Loading, monte)
+ - fix notice in debug security check (Drakla, monte)
+ - return valid reference in get_template_vars() when given var is
+ non-existant (monte)
+ - add escape type "urlpathinfo" to escape modifier (monte)
+
+Version 2.6.10 (Aug 5, 2005)
+----------------------------
+
+ - allow secure_dir to be a filename, not just
+ a directory name (monte)
+ - set debug.tpl as a secure_dir, not the entire
+ SMARTY_DIR (monte)
+ - fix proper escaping for literal strings in
+ Smarty_Compiler::_parse_var_props() (boots, messju)
+ - remove ambiguity for numeric values passed to smarty_make_timestamp()
+ (and thus the date_format modifier). numeric values are treated as
+ timestamps now. (andreas, messju)
+ - add passthru attribute feature to html_select_date (Sedgar,
+ monte)
+ - add "middle" parameter to truncate (monte)
+ - make form input label ids optional (monte)
+ - add error message for empty if/elseif statements (eykanal,
+ monte)
+ - cast selected value to string for comparison in html_radios
+ (Exeption, monte)
+ - updated html_select_date's year_as_text-feature to be xhtml compliant
+ (Mark West, messju)
+ - fix handling of selected month html_select_date (Yuri Weseman, messju)
+
+Version 2.6.9 (Mar 31, 2005)
+----------------------------
+
+ - disallow variable function calls in {if} statements (messju, monte)
+ - disallow variable function calls in {math} equations (messju, monte)
+
+Version 2.6.8 (Mar 21, 2005)
+----------------------------
+
+ - remove e-modifier from regex_replace modifier (messju)
+ - remove cast of object to array in foreach's from-attribute (messju)
+ - add "null" as a valid token for {if} when security is enabled (messju)
+ - add javascript_charcode encoding option to mailto function
+ (monte)
+ - add ids to html_radios labels (monte, menulis)
+ - fix handling of strip-tags with non-default delimiters (Mark West, messju)
+
+Version 2.6.7 (Feb 3, 2005)
+---------------------------
+
+ - fix handling of hashed opening php-tags inside strip-blocks (messju)
+ - removed border tag from html_image function (monte)
+ - change escape:url use rawurlencode() instead of urlencode() (messju)
+ - make $smarty.const.FOO compile to "FOO", and not to "constant('foo')".
+ this is less code and a little faster execution. note that undefined
+ constants are now displayed as the constant's name. (messju)
+ - make block functions and registered objects' block methods use a
+ local variable for block_content instead of a property of $smarty (messju)
+ - fix escaping in the generated code that calls smarty_core_load_plugins
+ (jes5199, messju)
+ - fix invalid HTML issue with popup (Stefanos Harhalakis,
+ Monte)
+ - fixed {popup} to properly handle inarray and function parameters and added
+ support for mouseoff and followmouse options (boots)
+
+Version 2.6.6 (Oct 13, 2004)
+----------------------------
+
+ - fixed nocache-handling with nested includes (Lars Jankowfsky, messju)
+ - moved /libs/core to /libs/internals (boots)
+ - fixed more parsing problems (messju)
+
+Version 2.6.5 (Sept 13, 2004)
+-----------------------------
+
+ - fixed some parsing problems with object calls introduced
+ in 2.6.4 (Monte)
+ - add $smarty->security_settings['ALLOW_CONSTANTS']. note: this
+ defaults to false which means you have to allow them explicitly
+ in your secured templates from now on! (messju)
+
+Version 2.6.4 (Sept 7, 2004)
+----------------------------
+
+ - add $smarty.ldelim and $smarty.rdelim to smarty special var (Monte)
+ - fall back to old uniqid()-behaviour when tempnam() fails in
+ core.write_file.php (messju)
+ - fix capitalize modifier, don't rely on buggy ucwords (Monte)
+ - make html_select_date work with negative timestamps, also
+ force year range to include given date unless explicitly
+ set (Garo, Monte)
+ - fix bug with {fetch}, passing user/pass in url did not work
+ (Monte)
+ - fix occasional wrong error messages on mismatched tags when
+ {else}, {elseif}, {foreachelse} or {sectionelse} is involved (messju)
+ - fix handling of methods arguments (messju, Manfred Wischin)
+ - remove touch() call that made the compiled-template's timestamp the
+ same as the source-template's one. (messju)
+ - add assign attribute to html_checkboxes and html_radios
+ (pcg, Monte)
+ - remove non-xhtml conformant tag from mailto function
+ (tacker, Monte)
+ - handle date_format codes %e, %T and %D for windows (tip,
+ Monte)
+ - fix unnecessary call to smarty_core_get_include_path() inside
+ Smarty::_get_auto_filename() (c960657, messju)
+ - add error-messages when anything else than an identifier is passed
+ to foreach's key- or item-attribute (messju)
+ - fix handling of digits inside tagnames (messju)
+ - fix escaping of backslashes in Smarty_Compiler::_quote_replace() (messju)
+
+Version 2.6.3 (June 16, 2004)
+-----------------------------
+
+ - added escapement of '</' to '<\/' in escape:javascript
+ modifier (c960657, Monte)
+ - added obfuscation of protocol-string in {mailto} when using hex-
+ encoding (bharat, messju)
+ - enhanced auto-generated filenames for templates_c and cache (messju)
+ - add 'nonstd' to escape modifier for escaping non-std chars,
+ such as ms doc quote (Monte)
+ - adjusted textformat to not output wrap chars after last para
+ (Monte)
+ - use tempnam() instead of unqid() to create better temporary files in
+ smarty_core_write_file() (xces, messju)
+ - add 'mail' to escape modifier for safe display of e-mail
+ addresses (Monte)
+ - add cycle function attribute "reset" to english docs (Monte)
+ - enhanced support of numeric constants as variable-expressions (messju)
+ - add case decentity to smarty_modifier_escape() (Konstantin A. Pelepelin,
+ messju)
+ - make smarty_core_write_compiled_include() php5-aware (messju)
+ - removed unused functionality to load a subset of lines from a file (messju)
+ - fix is_secure() should only check if a file is_readable, not if
+ the directory where it is in is readable (sagi, messju)
+ - fix problem displaying debug console when $default_resource_type
+ is not "file:" (c960657, Monte)
+ - fix permission handling with security and config_load (messju)
+ - removed '.' from the list of default template locations in
+ _parse_resource_name() (messju)
+ - fix avoid warning with template_exists() on an absolute paths (messju)
+ - fix parameters passed to resource's secure()-function (messju)
+ - fix handling of integer values like width and delay im
+ smarty_function_popup() (messju)
+
+Version 2.6.2 (Feb 17, 2004)
+----------------------------
+
+ - fix allow empty years, months and days in html_select_date's
+ time-attribute (messju)
+ - fix YES and NO should not be booleanized inside triple-quotes in a
+ config-file (messju)
+ - fix accidently slurped line following a triple-quoted value in a
+ config-file (messju)
+ - change default for use_sub_dirs to false (messju)
+ - fix quoting of values in smarty_function_popup() (messju)
+ - fix handling of hidden sections in Config_File (messju)
+ - add handling of resources for {config_load} (messju)
+ - fix bug when using arrays with tr_attr and td_attr in {html_table} (messju)
+ - add unit testing to cvs core (Monte)
+
+Version 2.6.1 (Jan 16, 2004)
+----------------------------
+
+ - rename $smarty->tpl_error_reporting to $smarty->error_reporting
+ (messju)
+ - fix interpretation of $smarty->security in {html_image} (messju)
+ - add caching of requested paths to _assemble_plugin_filepath() (messju)
+ - fix handling of comments inside {php}- and {literal}-blocks (messju)
+ - fix bug handling triple-quotes in config-files (BRDude, messju)
+ - change default of request_use_auto_globals to true - $_SERVER is
+ now preferred over $HTTP_SERVER_VARS (messju)
+ - re-add support for $SCRIPT_NAME (messju)
+ - reactivate $smarty->default_modifiers (messju)
+ - add cookie persistance to debug console (Monte)
+ - allow single-digit days and months without smarty_make_timestamp()
+ in html_select_date (messju)
+ - fix headers sent erroneously with cache_modified_check and fetch()
+ (wphilips, messju)
+ - fix config_file path bug (Marc Cabadas, Monte)
+ - fix 'is even by' and 'is odd by' logic (Monte)
+ - add day_empty, month_empty, year_empty and all_empty attributes to
+ html_select_date (messju)
+ - add table of explanation for {if} qualifiers in docs (boots)
+ - fix bug when comparing array-keys to "selected" in html_options
+ and html_checkboxes (messju)
+ - add better checks for correctly nested tags when compiling (messju)
+ - remove {$SCRIPT_NAME}. use {$smarty.server.SCRIPT_NAME} instead (messju)
+ - remove $global_assign. assign global variables explicitly instead (messju)
+ - fix example for count_characters in docs (boots)
+ - add section new basic syntax section "Escaping Smarty Parsing" in docs (boots)
+ - fix error handler call in config_load (boots)
+ - remove warning in debug_print_var on php-resources (messju)
+ - move function.assign.php to compiler.assign.php (messju)
+ - add property $tpl_error_reporting (messju)
+ - remove property $undefined. "null" is used literally instead (messju)
+
+Version 2.6.0 (Nov 19, 2003)
+----------------------------
+
+ - move Smarty::quote_replace() to Smarty_Compiler::_quote_replace() (messju)
+ - remove import of of attributes of {include_php} to php's namespace.
+ use $params[name] instead (messju)
+
+Version 2.6.0-RC3 (Nov 13, 2003)
+--------------------------------
+
+ - fix handling of $var.key inside [] (messju)
+ - fix handling of assign inside {insert}-tags (messju)
+ - fix handling if [...] inside triple-quotes in config-files (messju)
+ - fix handling of simple-math-operators inside modifiers (Dominik, messju)
+ - fix handling of trailing-slashes in open_basedir in
+ smarty_core_create_dir_structure() (packman, messju)
+
+Version 2.6.0-RC2 (Oct 8, 2003)
+-------------------------------
+
+ - apply modifiers only once to section-loop and foreach-from attrs (messju)
+ - remove use of _smarty_cached_paths-files (messju)
+ - remove Smarty::_plugin_implementation_exists() - use is_callable() (messju)
+ - ignore {strip}/{/strip) inside {strip}-blocks (messju)
+ - fixed removal of leading/trailing newlines in {strip}-blocks (messju)
+ - fixed proper escaping of " and ' with escape:javascript (messju)
+ - fixed bug in traversal of $smarty->plugins_dir-array. now the
+ first matching plugin is taken (messju)
+ - moved {strip} back into the compiler (messju)
+ - fixed config_load: handling of section-attribute and use of
+ multiple config-files in one template (atu, messju)
+
+Version 2.6.0-RC1 (August 11, 2003)
+-----------------------------------
+
+ - fixed status-header for cache_modified_check under cgi-sapi (messju)
+ - added optional parameter $cache_attrs to register_function() and
+ register_block(). $cache_attrs is an array containing attribute-
+ names that should be cached on calls to functions that have
+ $cacheable set to false. (messju)
+ - enabled registration of class-methods as callbacks for the register_*-
+ functions (use: array('classname', 'method_name')) as callback) (messju)
+ - added filepath caching (Monte)
+ - added optional assign-attribute to {capture}-tag (messju)
+ - added $cacheable-parameter to register_compiler_function() (messju)
+ - added $cacheable-parameter with default=true to register_function()
+ and register_block() (messju)
+ - add math speedup to core (Dominik, Monte)
+ - fix newlines for tags without template output (Monte)
+ - added config-option "request_use_auto_globals" to make auto-globals be
+ used as request vars instead of HTTP_*_VARS (messju)
+ - speed up config_load, simplify compiling (Monte)
+ - added block-methods for registered objects (Bharat Mediratta, messju)
+ - ignore one char resource names like c:foo.tpl (Monte)
+ - added default_resource_type feature (Monte)
+ - fix bug where config file starts with hidden section (boots, Monte)
+ - add discrete error checking pertaining to $cache_dir
+ and $compile_dir, their existance and writability (Monte)
+ - fixed behaviour of start=... for {counter} (messju)
+ - fixed assign for {counter} (messju)
+ - added params vdir, hdir and inner to html_table to allow looping
+ over the data in various directions (messju)
+ - allow spaces in literal tags (Paul Lockaby, Monte)
+ - speed up compiled templates, hardcode plugin filepaths
+ instead of dynamically calculate at runtime. (Monte)
+ - abstract many core components from Smarty.class.php,
+ speeding up core class instantiation (Monte)
+ - fixed bug in _create_dir_structure() when used with open_basedir-
+ restriction and relative paths (messju)
+ - use DIRECTORY_SEPARATOR exclusively, keep DIR_SEP for BC (Monte)
+ - changed "link" to "href" in html_image. "link" is still working
+ but deprecated (messju)
+ - html_image always renders an alt-tag now (default alt="") (messju)
+ - fixed assign attribute for multiple counters (messju)
+ - added simple math operators to variables (Monte)
+ - enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted')
+ as callback for register_resource() (messju);
+ - enabled array(&$obj, 'method') as callback for
+ $default_template_handler_func (messju)
+ - remove unnecessary close/open tags from compiled templates
+ (Monte)
+ - fixed errornous creation of '//' in image_path in html_image (messju)
+ - fix escapement of special chars for key vals in debug
+ console (Monte)
+ - fixed debug timing logic for config_load (Tom Sommer, Monte)
+ - all in-code doc comments converted to phpDocumentor format (Greg)
+ - moved strip from smarty core to plugin (Monte)
+ - moved config_load from smarty core to plugin (Monte)
+ - added &$repeat-parameter to block-functions (messju)
+ - enabled hex-constants in function.math.php (messju)
+ - enabled hex-constants (0x...) as function-attributes, inside if-statements
+ and as modifier-parameters (messju)
+ - fixed bug with passing $smarty as reference in Smarty.compiler.class
+ (messju)
+ - corrected output with {strip} and PHP tag newlines (Monte)
+ - added possibility to register function-callbacks as "array(&$obj, 'method)"
+ this affects register_function(), -block, -compiler_function, -modifier,
+ -prefilter, -postfilter, -outputfilter-functions() and $cache_handler_func
+ (messju)
+ - added <labels> to html_checkboxes and html_radios (Philippe, messju)
+ - added "labels"-options to turn off labels in html_checkboxes and _radios
+ (messju)
+
+Version 2.5.0 (April 11, 2003)
+------------------------------
+
+ - fixed bug with default modifier when passing integer 0
+ (Monte)
+ - change backtic syntax from $`foo` to `$foo` (Monte)
+ - recognize $foo[][] syntax inside embedded quotes without
+ backtics (Monte)
+ - name=123 is passed as an integer (not a string) to plugins now (messju)
+ - $length is now propagated to sub-values in debug_print_var (messju)
+
+Version 2.5.0-RC2 (March 26, 2003)
+----------------------------------
+
+ - made clear_cache() ignore compile_id, when clearing cache-groups (this
+ is when no $tpl_file is supplied) (messju)
+ - made onmouseout XHTML-compliant in function.popup.php (messju)
+ - applied local-var-naming-scheme to fetch() (messju)
+ - renamed $localvars to $_localvars in cache-file-handling-functions,
+ added _get_auto_id()-function (messju)
+ - swapped compile_id and cache_id in read_cache_file and write_cache_file
+ (messju)
+ - reverted patch for cache-file-handling (messju)
+ - made html_radios and html_checkboxes accept "selected" instead
+ of "checked" optionally. (messju)
+ - made compile_id ignored in clear_cache, made order of
+ auto_file_name $cache_id.$compile_id again, applied the the new
+ variable-naming-scheme for cache_file_handing functions (messju)
+ - removed notice of undefined var in _rm_auto() (messju)
+ - added warning message when an array is passed as
+ the "checked" value of html_radios (Monte)
+ - fixed errormessage in _compile_smarty_ref() (messju)
+ - updated docs for html_image "name" -> "file" (messju)
+ - fixed bug with html_options-optgroups (Nichlas Löfdahl, messju)
+ - cleaned up calls to readdir() (messju)
+ - fixed bug with passing multiple modifiers to a parameter
+ (Monte)
+ - updated docs for html_checkboxes, html_options and html_radios (messju)
+ - fixed wrong default "name" attribute for html_options (messju)
+ - html_checkboxes now expect the options as attribute "options" instead
+ of "checkboxes. html_radios expect "options" instead of "radios".
+ cleaned up indentiation (messju)
+ - fixed too greedy str_replace in trimwhitespace outputfilter (messju)
+ - html_checkboxes and html_radios passthru all unknown paramters now
+ additionally their output is now XHTML compliant (messju)
+ - html_options passthru all unknown paramters now (messju)
+ - fix link functionality of html_image, also make
+ output XHTML compatible (Hinrich Donner, Monte)
+ - append "@" to default modifier vars/args
+ supress possible warnings (Monte)
+ - fix problem with escaped double quotes (Monte)
+ - fix html_radios to not return an array (Monte)
+ - fixed length in modifier.truncate.php (messju)
+ - fixed handling of '$'-signs in trimwhitespace outputfilter (messju)
+ - fix bug that makes config files recompile every time
+ (Nagger, Monte)
+ - add dpi functionality to html_image, change "name"
+ parameter to "file" (Thomas Shulz, Monte)
+ - fix height/width parameter index in html_image (Gerard,
+ Monte)
+ - get rid of unsetting name and script attributes
+ to insert tag (Thomas Schulz, Monte)
+ - changed argument order of string_format modifier back,
+ was right in the first place (Monte)
+
+Version 2.5.0-RC1 (March 5, 2003)
+---------------------------------
+
+ - fixed notice in popup function (Nagger, Monte)
+ - fix "once" var compiling for include_php (Monte)
+ - added nl2br modifier to distribution (Monte)
+ - added html_image to distribution (Monte)
+ - added cat modifier to distribution (Monte)
+ - added html_table to distribution (Monte)
+ - added << >> <> support to if statments (SMK, Monte)
+ - fix _assign_smarty_interface to not overwrite keys
+ other than 'request' (Jerome Poudevigne, Monte)
+ - added html_checkboxes to distribution (Christopher Kvarme, Monte)
+ - added html_radios to distribution (Christopher Kvarme, Monte)
+ - fixed string_format modifier args (wrong order) (Paul
+ Lockaby, Monte)
+ - use tmp file for file writes, avoid file lock race (Monte)
+ - support syntax "$`smarty.config.foo`.tpl" for embedded
+ vars in quotes, and allow full dollar var syntax (Monte)
+ - add $smarty.config.varname variable for accessing config vars (Paul
+ Lockaby, Monte)
+ - silence PHP warnings in function.fetch.php (Eduardo,
+ Monte)
+ - added get_config_vars(), same basic functionality as
+ get_template_vars() (Monte)
+ - update get_template_vars() to be able to get
+ individual vars (Monte)
+ - fix minor logic in _fetch_template_info (Dennis Gearon,
+ Monte)
+ - fix cache groups with compile_id set (Monte)
+ - add support for merging appended vars (messju, Monte)
+ - allow null as function attribute value
+ (André Rabold, Monte)
+ - support $foo->bar[index] syntax (Monte)
+ - add get_registered_object function (messju, Monte)
+ - treat unrecognized param attribute syntax as string (Monte)
+ - support $smarty.const.$foo syntax (messju, Monte)
+ - remove E_NOTICE warnings from debug.tpl,
+ escape modifier (Kanstantin, Monte)
+ - don't count non-ascii chars in count_words modifier
+ (Kanstantin, Monte)
+ - clean up param calls to _parse_var and _parse_attrs (Monte)
+ - define $template_source var, elude possible warning
+ (Monte)
+ - fix syntax problem with evaluating PHP constants (Monte)
+ - add @ and === as valid if statement tokens (Monte)
+ - enable error messages for config_load errors,
+ use $this->config_class for loading class name (Monte)
+ - fix html_options to not escape already escaped entities (Monte)
+ - send Last-Modified header on cache creation (Monte)
+ - check strict syntax of function attributes (Monte)
+ - dropped support for modifers on object parameters,
+ added support for objects as modifier parameters (Monte)
+ - fixed bug with decimal numbers in if statements (Monte)
+
+Version 2.4.2 (Feb 11, 2003)
+----------------------------
+ - support embedded variables in objects (Monte)
+ - fix bug with objects with no properties (M Mohr, Monte)
+ - support full dollar var syntax in quoted text (Monte)
+ - fixed bug in $smarty.const.FOO introduced in 2.4.1 (M
+ Mohr, Monte)
+
+Version 2.4.1 (Feb 6, 2003)
+---------------------------
+
+ - ignore case in IF statements (Rainer Collet, Monte)
+ - treat undefined constants as null (Ferdinand Beyer, Monte)
+ - fix problem with inserts and nested fetches
+ (Rainer Collet, Monte)
+ - added support for passing params to include_php
+ (Tim Riley, Monte)
+ - added support for math operators in if statements (Monte)
+ - added support for $foo->bar[$x].blah syntax (Monte)
+
+Version 2.4.0 (Feb 2, 2003)
+---------------------------
+
+ - fix known problems with php tag handling in templates
+ (recursion, echoing xml tags) (Monte)
+ - add support for object registration (Monte)
+ - add debug template to secure_dir, add template_dir
+ to secure_dir by default (Ferdinand Beyer, Monte)
+ - added support for assigned object access (Monte)
+ - fixed bug with directories named '0' (Frank Bauer, Monte)
+ - add javascript parameter to escape modifier (Monte)
+ - added calling function line numbers to syntax error
+ messages in compiler (Monte)
+ - added support for modifiers to function calls (Monte)
+ - support return value for custom functions
+ instead of echoing (but echo still works) (Monte)
+ - added direct access to constants
+ via $smarty.const.FOO (Monte)
+ - added support for passing modifiers
+ to static values (Monte)
+ - fix up regex code in compiler, more accurate and
+ maintainable (Monte)
+ - added day_value_format to html_select_date (Marcus
+ Bointon, Monte)
+ - assigned variables are no longer in global
+ namespace, saving extract() calls and speeding
+ up fetch() and display() linearly with no. of
+ assigned variables (Monte)
+ - added trimwhitespace output filter to dist. (Monte)
+ - fix popup function to allow newlines in text (Monte)
+ - escape html entities in html_options (Monte)
+ - fixed bug with label for html_options (Monte)
+ - added config_load API function (Monte)
+ - added caching to config file loading (Monte)
+ - added "extra" parameter to mailto function (Monte,
+ Massimiliano Perantoni)
+ - added mailto plugin to dist. (Monte)
+
+Version 2.3.1 (Nov 19, 2002)
+----------------------------
+
+ - added optgroup support to html_options (Monte, Robert
+ Amos)
+ - set mtime on compile files so they match source
+ files (Monte, Peter Bowen)
+ - added proper support for open_basedir setting
+ (Monte, Alessandro Astarita)
+ - added strip variable modifier, updated docs (Monte)
+ - fixed access to $smarty.x variables as arrays. (Andrei)
+ - fixed errors with example setup docs (Monte, Matthew
+ Hagerty)
+ - added textformat block function (Monte)
+
+Version 2.3.0 (Aug 7, 2002)
+---------------------------
+
+ - added assign_by_ref() and append_by_ref() functions
+ (Bob Silva, Monte)
+ - changed default warning type for plugin errors from
+ E_USER_WARNING to E_USER_ERROR (Monte)
+ - added $all_extra, $hour_extra, $minute_extra,
+ $second_extra and $meridian_extra parameters to
+ html_select_time function (Rainer Collet, Monte)
+ - update debug console to print objects (Simon Willison,
+ Monte)
+ - fix Config_File class to not error when there are no
+ sections (Peter Kmet, Monte)
+ - add default modifier logic (Monte)
+ - updated popup_init to be xhtml compliant (Tom Oram, Monte)
+ - fix filename bug with windows (Gary Loescher, Monte)
+ - add ability to supply expire time in seconds when clearing
+ cache or compile files (Monte)
+ - add {debug} plugin to distribution (Monte)
+ - fixed bug with insert tags, loading from "script" attribute
+ when caching is enabled (Monte)
+ - fix bug with debug_tpl file path with Windows (.SMK., Monte)
+ - fix append() function with string/array problem (Monte)
+
+Version 2.2.0 (July 11, 2002)
+-----------------------------
+
+ - make debug.tpl work with any delimiter (Monte)
+ - change logic in assign() and append() to test var names
+ against != '' instead of empty() (Monte)
+ - fix PHP notice in append() function (Monte)
+ - allow $plugins_dir to be an array of directories
+ (Andreas Kossmeier, Monte)
+ - move debug.tpl to SMARTY_DIR, add to constructor (Monte)
+ - fixed warning message in function.assign_debug_info (Monte)
+ - fixed $template_dir, $compile_dir, $cache_dir, $config_dir,
+ $plugin_dir to respect include_path (Monte)
+ - fixed warning message with output filter array (Monte)
+ - add optional 2nd parameter to date_format, used as
+ the default date if the passed date is empty (Monte)
+ - gave $reset a default value in cycle plugin (Monte)
+ - fixed warnings with html_select_date and timestamp
+ functions (Monte)
+ - added support for sub directory exlusion format (Monte)
+ - added support for grouping by cache_id, compile_id
+ and segments thereof (Monte)
+ - changed cache and compile files to human readable
+ format (Monte)
+ - remove overlib.js file from distribution (Monte)
+ - fixed bug with 304 Not Modified response sending
+ content (Monte)
+ - fixed cycle function to respect delimiter after
+ initial setting (Monte)
+ - update $GLOBALS references to work properly with
+ track_globals settings (Michal Prinke, Monte)
+ - fixed bug in math function with call to assign
+ (Grigory V. Kareev, Monte)
+ - optimized for loops with count() function calls (Monte)
+ - add month_value_format attribute to html_select_date
+ plugin (Gary Loescher, Monte)
+ - made it possible to use simple variables inside [] for
+ indexing. (Andrei)
+ - added "once" attribute to {include_php}. (Monte)
+
+Version 2.1.1
+-------------
+ - added cycle function. (Monte)
+ - fixed bug with resource testing, and include_path. (Monte)
+ - fixed a bug with register_outputfilter function. (Monte)
+
+Version 2.1.0
+-------------
+
+ - introduced output filters. (Andrei)
+ - changed the way filters are loaded, added load_filter()
+ API function and $autoload_filters variable. (Andrei)
+ - added caching logic for expire times per cache file
+ (Norbert Rocher, Monte)
+ - fixed html_select_date when field separator is "/"
+ (Roberto Berto, Monte)
+ - added YYYY-MM-DD format support to html_select_date
+ (Jan Rosier, Monte)
+ - fixed cache_lifetime logic bug, also made -1 = never
+ expire (Monte)
+ - fixed directory separator issue for Windows. (Andrei)
+ - added ability to use simple variables as array indices or
+ object properties. (Andrei)
+ - added ability to unregister pre/postfilters plugins at
+ runtime. (Andrei)
+ - added 'htmlall' attribute to escape modifier. (Monte)
+ - added template_exists() API function. (Andrei)
+ - fixed a problem with using dynamic values for 'file'
+ attribute of {include_php} tag. (Andrei)
+ - added $smarty.template variable. (Andrei)
+ - fixed several plugins that would not work if the plugin
+ directory was not the default one. (Andrei)
+ - implemented support for block functions. (Andrei)
+ - made it possible to assign variables in pre/postfilter
+ plugins. (Andrei)
+
+Version 2.0.1
+-------------
+ - rename plugin .make_timestamp.php to shared.make_timestamp.php.
+ (Monte)
+ - changed crc32() generated values, replace '-' with 'N'. (Monte)
+ - added support for +/- N syntax in html_select_date year values.
+ (Monte)
+ - fixed behavior of inserts with script attribute. (Andrei)
+ - fixed bug with $smarty.cookies and $smarty.server. (Andrei)
+ - wordwrap and indent are missing from 2.0 release, now fixed.
+ (Monte)
+ - removed show_info_header and show_info_include variables. (Monte)
+
+Version 2.0.0
+-------------
+ - added "eval" function plugin for evaluating variables as
+ templates. (Monte)
+ - removed $tpl_file_ext class variable, no longer used. (Monte)
+ - added "hex" and "hexentity" escape types to escape modifier.
+ (Monte)
+ - removed dependency on PEAR. (Andrei)
+ - update popup_init to accept src attribute. (Monte, Duncan Forrest)
+ - implemented several optimizations, speeding up Smarty
+ significantly in most cases. (Andrei,Monte)
+ - implemented plugin architecture. (Andrei)
+ - added wordwrap and indent modifiers. (Monte)
+ - added support for 'If-Modified-Since' headers for cached content.
+ (Monte)
+ - removed insert_tag_check class variable, no longer needed. (Monte)
+ - optimized cache fetches by scanning for insert tags only if they
+ exist. (Monte)
+ - fixed bugs in overlib. (Monte, Duncan Forrest)
+ - fixed a problem with compile_id usage. (Andrei)
+ - fixed problem with using assigned vars with {include_php ...}
+ filepath. (Monte)
+
+Version 1.5.2
+-------------
+ - added Smarty object as fifth argument for template resource functions.
+ (Monte)
+ - fixed a bug with incorrectly combined cache and compile id in
+ clear_cache(). (Andrei)
+ - fixed bug in smarty_make_timestamp introduced in PHP 4.1.0. (Monte)
+ - fixed bug with cached insert debug timing. (Monte)
+ - added 'script' attribute to {insert..} which specifies the script that
+ the insert function can be found in. (Andrei)
+ - added default template function handler. (Monte)
+
+Version 1.5.1
+-------------
+ - removed error message from the generic _read_file() method, the caller
+ should take care of that. (Andrei)
+ - fixed a bug with incorrectly combined cache and compile id. (Andrei)
+
+Version 1.5.0
+-------------
+ - added include_php built-in function, documented. (Monte)
+ - added trusted_dir functionality, documented. (Monte)
+ - consolidated secure_dir tests to one function. (Monte)
+ - prepended _smarty_ to variable names in fetch() class function to avoid
+ namespace conflicts. (Monte)
+ - introduced $compile_id class variable that can be used to set persistent
+ compile identifier across multiple display calls, documented. (Andrei)
+ - fixed bug with concatenated null cache and compile identifiers. (Andrei)
+ - added $smarty.section.* syntax for accessing section properties,
+ documented. (Andrei)
+ - added custom cache handling function ability, documented. (Monte)
+ - added assign attribute to include, include_php, insert, fetch, math, and
+ counter functions, documented. (Monte)
+ - fixed bug with fetch testing for local file when http address. (Monte)
+ - fixed bug with counter and skipval setting. (Monte)
+ - made {config_load ...} merge globals from each config file only once per
+ scope, thus avoiding several problems. (Andrei)
+ - added {foreach ...} tag that can be used to iterate through
+ non-sequential and associative arrays, documented. (Andrei)
+ - speeded up section property access a bit. (Andrei)
+ - removed $smarty variable from storage used by normal template variables,
+ to prevent any problems. (Andrei)
+ - fixed a bug that could cause parse error with quotes inside literal
+ blocks. (Andrei, Alexander Belonosov)
+ - added 'field_array' attribute to html_select_time function, documented.
+ (Andrei, Michael Caplan)
+ - documented {section} "max" attribute. (Monte)
+ - fixed notice message in Smarty_Compiler.class.php. (Monte)
+ - fixed bug with clear_cache introduced in 1.4.6, third parameter should
+ default to null. (Monte)
+ - updated Config_File class to support '\' path separator in OS/2. (Monte,
+ Francesco Cipriani)
+ - removed secure_ext setting (not used). (Monte)
+ - made cache reading process more efficient. (Monte)
+ - fixed bug, is_cached() now supports new 1.4.6 caching behavior. (Monte)
+ - update FAQ with mailing list Reply-To header FAQ. (Monte)
+ - supress error messages for fopen(), fix cache to regenerate if cache
+ file is not available (i.e. cluster race condition). (Monte)
+ - added index key example to QUICKSTART guide. (Monte)
+
+Version 1.4.6
+-------------
+ - fixed bug with {assign ...} when passing an empty value. (Monte)
+ - add more warning message fixes. (Monte, Tara Johnson)
+ - documentation updates. (Monte)
+ - update fetch function to give proper warning when fetching a non-readable
+ or non-existant file. (Monte)
+ - fixed problem with newline at the end of included templates (Monte, Andrei)
+ - added feature to regenerate cache if compile_check is enabled and an
+ involved template or config file gets modified. (Monte)
+ - added DEBUG execution times to included files: REQUIRES updated debug.tpl
+ file! (Monte)
+ - added support for hidden config variables that cannot be read by
+ templates. (Andrei)
+ - added execution time to DEBUG console, total and inserts. (Monte)
+ - fixed bug where DEBUG console would not appear with cached content. (Monte)
+ - added support for postfilter functions that are applied to compiled
+ template right after compilation. (Andrei)
+ - fixed the name of clear_compile_tpl() API function to clear_compiled_tpl.
+ (Andrei)
+ - added fix for removing comments so that the line numbers are reported
+ correctly in case of errors. (patch from Anders Janson)
+ - made html_options output xhtml compatible code. (Monte, Arnaud Limbourg)
+
+Version 1.4.5
+-------------
+ - update FAQ with index of questions at the top
+ - update overlib to 3.50, adjust addon code so that the overlib.js
+ file isn't modified, and not using the mini one. (Monte)
+ - added many more options to html_select_date. (Alexander Skwar, Andrei)
+ - added support for generating different compiled templates from the same
+ source template. (Hans-Peter Oeri, Andrei)
+ - modified Smarty to pass itself to insert functions as the second
+ parameter. (Andrei)
+ - modified Smarty to pass itself to prefilter functions as the second
+ parameter. (Andrei)
+ - fixed syntax error when including a non-existant template with security
+ enabled. (Monte)
+ - fixed comments handling to allow commenting out template blocks. (Andrei)
+ - implemented named capture buffers, with results accessible via
+ $smarty.capture.<name>. (Andrei)
+ - added ability to index arrays directly by numbers. (Andrei)
+ - fixed bug with SMARTY_DIR not prepended to Config_File include. (Monte)
+
+Version 1.4.4
+-------------
+ - fixed problem with including insecure templates with security enabled.
+ (Monte)
+ - numerous documentation updates. (Monte)
+ - added ENT_QUOTES to escapement of html. (Monte, Sam Beckwith)
+ - implemented access to request variables via auto-assigned $smarty
+ template variable. (Andrei)
+ - fixed a bug with parsing function arguments inside {if} tags if a comma
+ was present. (Andrei)
+ - updated debug console with config file vars. (Monte)
+ - added SMARTY_DIR constant as an alternative to relying on include_path.
+ (Monte)
+ - added popup_init and popup functions (requires overlib.js). (Monte)
+ - updated debug console with config file vars. (Monte)
+ - added debugging url control. (Monte)
+ - added 'quotes' type to escape modifier. (Monte, Mike Krus)
+ - added 'total' and 'iteration' section properties. (Andrei)
+ - added 'start', 'max', and 'step' section attributes/properties. (Andrei)
+ - fixed a bug with security checking of functions inside {if} tags.
+ (Andrei)
+ - fixed a bug in Config_File that would incorrectly booleanize values that
+ weren't really booleans. (Andrei)
+
+Version 1.4.3
+-------------
+ - added regex_replace modifier, documented. (Monte)
+ - added debugging console feature and custom function assign_debug_info,
+ documented. (Monte)
+ - added 'scope' attribute for {config_load}, 'global' is now deprecated but
+ is still supported. (Andrei)
+ - reduced template symbol table pollution by moving config array into the
+ class itself. (Andrei)
+ - fixed a bug with passing quoted arguments to modifiers inside {if}
+ statements. (Andrei, Sam Beckwith)
+ - added security features for third party template editing, documented
+ (Monte)
+ - added assign custom function, documented. (Monte)
+ - fixed bug with template header using version instead of _version. (Monte)
+ - fixed a problem with putting $ followed by numbers inside {strip} and
+ {/strip} tags. (Andrei)
+ - fixed Config_File class to allow empty config paths (defaults to current
+ directory). (Andrei)
+
+Version 1.4.2
+-------------
+ - move $version to internal variable, remove from docs. (Monte)
+ - cleaned up compiled templates global scope by moving some variables into
+ the class itself. (Andrei)
+ - fixed a bug that would not allow referring to a section in the including
+ file from the included file. (Andrei)
+ - configs directory missing from 1.4.1 release, added back in. (Monte)
+ - added windows include_path setup instructions to FAQ & QUICKSTART.
+ (Monte)
+
+Version 1.4.1
+-------------
+ - fix LOCK_EX logic for all windows platforms (Monte)
+ - fixed indexing by section properties with the new syntax. (Andrei)
+ - updated Smarty to use absolute paths when requiring/including Smarty
+ components. (Andrei, John Lim)
+
+Version 1.4.0
+-------------
+ - added {capture}{/capture} function, documented (Monte)
+ - added {counter} function, documented (Monte)
+
+Version 1.4.0b2
+---------------
+ - fixed issue in Config_File.class with referencing blank sections (Andrei)
+ - fixed problem with passing variables to included files (Andrei)
+ - fixed resource path recognition for windows (Monte)
+
+Version 1.4.0b1
+---------------
+ - added "componentized templates" tip into documentation (Monte)
+ - added {php}{/php} tags for embedding php code into templates (Monte)
+ - changed default value of $show_info_header to false (Monte)
+ - implemented '->' syntax for accessing properties of objects passed to the
+ template. (Andrei)
+ - allowed custom functions to receive Smarty object as the second
+ parameter; this can be used to dynamically change template variables, for
+ example. (Andrei)
+ - added custom compiler functions support, register_compiler_function() and
+ unregister_compiler_function() API functions. (Andrei, Ivo Jansch).
+ - updated GLOBAL_ASSIGN to take SCRIPT_NAME from HTTP_SERVER_VARS
+ instead of global variable. You can also assign several variables
+ in one shot with an array. (Monte, Roman Neuhauser)
+ - added template prefilters, register_prefilter() and
+ unregister_prefilter() API functions. (Monte)
+ - added RELEASE_NOTES file to distribution. (Monte)
+ - moved CREDITS out of manual into its own file. (Monte)
+ - added register_resource() and unregister_resource() API functions. (Monte)
+ - changed the syntax of indexing template variables, thus supporting
+ structures of arbitrary complexity; supplied fix_vars.php script to fix
+ old syntax. (Andrei)
+ - added $insert_tag_check to speed up cached pages if {insert ...} is not
+ used. (Monte)
+ - added $compiler_class variable to allow specifying a different compiler
+ class. (Andrei)
+ - changed Smarty to compile templates at runtime, allowing for arbitrary
+ template resources. (Monte)
+ - added fix for LOCK_EX under Windows and changed a couple of file
+ permissions for security. (Monte, Fernando Nunes)
+ - allow arbitrary date strings to date_format, html_select_date and
+ html_select_time (Monte)
+
+Version 1.3.2
+-------------
+ - fixed a bug that caused some nested includes to loop infinitely. (Andrei)
+ - added optional HTML header to output. (Monte)
+ - significantly improved config_load performance. (Andrei)
+ - added format attribute to math function. (Monte)
+ - added html_select_time custom function. (Andrei)
+ - fixed minor PHP warning when attempting to unset an unset variable
+ (Monte)
+ - added count_characters, count_words, count_sentences, count_paragraphs
+ modifiers (Monte)
+
+Version 1.3.1pl1
+--------------
+ - bug fix, recovered missing _syntax_error function (Monte)
+
+Version 1.3.1
+-------------
+ - document first, last, index_prev, index_next (Monte)
+ - added 'first' and 'last' section properties. (Andrei)
+ - split out compiling code to separate class for faster template execution
+ time (Monte)
+ - fixed a couple of minor PHP warnings (Monte)
+ - added and documented unregister_modifier() and unregister_function() API
+ calls. (Monte)
+ - added and documented 'fetch' and 'math' functions. (Monte)
+ - added ability to index looped variables by section properties, e.g.
+ $foo.index_prev/bar. (Andrei)
+ - added index_prev and index_next section properties. (Andrei)
+ - fixed issue with php executing in literal blocks. (Monte)
+
+Version 1.3.0
+-------------
+ - moved license from GPL to LGPL (Monte)
+ - implemented workaround for PHP "feature" that eats carriage returns
+ if the PHP tag is at the end of the line. (Andrei)
+ - removed $allow_php, added $php_handling logic (Monte)
+ - added file locking to prevent reader/writer problem. (Andrei)
+ - made Smarty catch unimplemented modifiers and custom functions and output
+ error messages during compilation instead of failing during run time.
+ (Andrei)
+ - removed short-tags at the top of the smarty scripts (Monte)
+ - added register_function() and register_modifier() API calls to make
+ registering stuff easier. (Andrei)
+ - added template results caching capability. (Monte, Andrei)
+ - added optional 'options' attribute to html_options custom function
+ that allows passing associative arrays for values/output. (Andrei)
+ - modifier arguments can now contain '|' and ':' characters inside quoted
+ strings. (Andrei)
+
+Version 1.2.2
+-------------
+ - fixed bug that would not respect nested template directories and would
+ put all compiled files into top-level one. (Andrei)
+ - fixed bug using $PHP_VERSION instead of environment var PHP_VERSION.
+ (Monte)
+ - a couple small warning fixes. (Monte)
+
+Version 1.2.1
+-------------
+ - added $compile_dir, removed $compile_dir_ext, simplified usage. (Monte)
+ - added tips & tricks chapter to documentation. (Monte)
+ - misc documentation updates. (Monte)
+
+Version 1.2.0
+-------------
+ - updated documentation (Monte)
+ - added file and line number information to syntax error messages. (Andrei)
+ - added ability to index template vars by a key. (Andrei)
+
+Version 1.1.0
+-------------
+ - misc documentation changes, official stable release
+
+Version 1.0b
+------------
+ - fixed the bug that prevented using non-array values for 'loop' attribute.
+ (Andrei)
+ - many misc documentation changes & additions (Monte)
+
+Version 1.0a
+------------
+ - fixed bug that caused templates to recompile every time (Monte)
+
+Version 1.0
+------------
+ - initial release
+
+/* vim: set et tw=64 ft=changelog: */
--- /dev/null
+This is a simple guide to get Smarty setup and running quickly. The online
+documentation includes a very thorough explanation of a Smarty installation.
+This guide is meant to be a quick and painless way of getting Smarty working,
+and nothing more. The guide assumes you are familiar with the UNIX system
+environment. Windows users will need to make adjustments where necessary.
+
+INSTALL SMARTY LIBRARY FILES
+
+Copy the Smarty library files to your system. In our example, we place them in
+/usr/local/lib/php/Smarty/
+
+$> cd YOUR_DOWNLOAD_DIRECTORY
+$> gtar -ztvf Smarty-2.6.7.tar.gz
+$> mkdir /usr/local/lib/php/Smarty
+$> cp -r Smarty-2.6.7/libs/* /usr/local/lib/php/Smarty
+
+You should now have the following file structure:
+
+/usr/local/lib/php/Smarty/
+ Config_File.class.php
+ debug.tpl
+ internals/
+ plugins/
+ Smarty.class.php
+ Smarty_Compiler.class.php
+
+
+SETUP SMARTY DIRECTORIES
+
+You will need four directories setup for Smarty to work. These files are for
+templates, compiled templates, cached templates and config files. You may or
+may not use caching or config files, but it is a good idea to set them up
+anyways. It is also recommended to place them outside of the web server
+document root. The web server PHP user will need write access to the cache and
+compile directories as well.
+
+In our example, the document root is /web/www.domain.com/docs and the
+web server username is "nobody". We will keep our Smarty files under
+/web/www.domain.com/smarty
+
+$> cd /web/www.domain.com
+$> mkdir smarty
+$> mkdir smarty/templates
+$> mkdir smarty/templates_c
+$> mkdir smarty/cache
+$> mkdir smarty/configs
+$> chown nobody:nobody smarty/templates_c
+$> chown nobody:nobody smarty/cache
+$> chmod 775 smarty/templates_c
+$> chmod 775 smarty/cache
+
+
+SETUP SMARTY PHP SCRIPTS
+
+Now we setup our application in the document root:
+
+$> cd /web/www.domain.com/docs
+$> mkdir myapp
+$> cd myapp
+$> vi index.php
+
+Edit the index.php file to look like the following:
+
+<?php
+
+// put full path to Smarty.class.php
+require('/usr/local/lib/php/Smarty/Smarty.class.php');
+$smarty = new Smarty();
+
+$smarty->template_dir = '/web/www.domain.com/smarty/templates';
+$smarty->compile_dir = '/web/www.domain.com/smarty/templates_c';
+$smarty->cache_dir = '/web/www.domain.com/smarty/cache';
+$smarty->config_dir = '/web/www.domain.com/smarty/configs';
+
+$smarty->assign('name', 'Ned');
+$smarty->display('index.tpl');
+
+?>
+
+
+SETUP SMARTY TEMPLATE
+
+$> vi /web/www.domain.com/smarty/templates/index.tpl
+
+Edit the index.tpl file with the following:
+
+<html>
+<head>
+<title>Smarty</title>
+</head>
+<body>
+Hello, {$name}!
+</body>
+</html>
+
+
+
+Now go to your new application through the web browser,
+http://www.domain.com/myapp/index.php in our example. You should see the text
+"Hello Ned!" in your browser.
+
+Once you get this far, you can continue on to the Smarty Crash Course to learn
+a few more simple things, or on to the documentation to learn it all.
--- /dev/null
+
+NAME:
+
+ Smarty - the PHP compiling template engine
+
+VERSION: 2.6.26
+
+AUTHORS:
+
+ Monte Ohrt <monte at ohrt dot com>
+ Andrei Zmievski <andrei@php.net>
+
+MAILING LISTS:
+
+ We have a few mailing lists. "discussion" for you to share your ideas or ask
+ questions, "developers" for those interested in the development efforts of Smarty,
+ and "svn" for those that would like to track the updates made in the svn
+ repository.
+
+ send a blank e-mail message to:
+ smarty-discussion-subscribe@googlecode.com(subscribe to the general discussion list)
+ smarty-discussion-unsubscribe@googlecode.com (unsubscribe from the general discussion list)
+ smarty-discussion-digest-subscribe@googlecode.com (subscribe to digest)
+ smarty-discussion-digest-unsubscribe@googlecode.com (unsubscribe from digest)
+ smarty-developers-subscribe@googlecode.com (subscribe to the dev list)
+ smarty-developers-unsubscribe@googlecode.com (unsubscribe from the dev list)
+ smarty-svn-subscribe@googlecode.com (subscribe to the svn list)
+ smarty-svn-unsubscribe@googlecode.com (unsubscribe from the svn list)
+
+ You can also browse the mailing list archives at
+ http://groups.google.com/group/smarty-discussion
+ http://groups.google.com/group/smarty-developers
+
+ and the OLD list archives at
+ http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
+
+SYNOPSIS:
+
+ require("Smarty.class.php");
+
+ $smarty = new Smarty;
+
+ $smarty->assign("Title","My Homepage");
+ $smarty->assign("Names",array("John","Gary","Gregg","James"));
+
+ $smarty->display("index.tpl");
+
+
+DESCRIPTION:
+
+ What is Smarty?
+
+ Smarty is a template engine for PHP. Many other template engines for PHP
+ provide basic variable substitution and dynamic block functionality.
+ Smarty takes a step further to be a "smart" template engine, adding
+ features such as configuration files, template functions, and variable
+ modifiers, and making all of this functionality as easy as possible to
+ use for both programmers and template designers. Smarty also converts
+ the templates into PHP scripts, eliminating the need to parse the
+ templates on every invocation. This makes Smarty extremely scalable and
+ manageable for large application needs.
+
+ Some of Smarty's features:
+
+ * it is extremely fast
+ * no template parsing overhead, only compiles once.
+ * it is smart about recompiling only the template files that have
+ changed.
+ * the template language is remarkably extensible via the plugin
+ architecture.
+ * configurable template delimiter tag syntax, so you can use
+ {}, {{}}, <!--{}-->, or whatever you like.
+ * built-in caching of template output.
+ * arbitrary template sources (filesystem, databases, etc.)
+ * template if/elseif/else/endif constructs are passed to the PHP parser,
+ so the if syntax can be as simple or as complex as you like.
+ * unlimited nesting of sections, conditionals, etc. allowed
+ * it is possible to embed PHP code right in your template files,
+ although not recommended and doubtfully needed since the engine
+ is so customizable.
+ * and many more.
+
+COPYRIGHT:
+ Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved.
+ This software is released under the GNU Lesser General Public License.
+ Please read the disclaimer at the top of the Smarty.class.php file.
--- /dev/null
+2.6.7
+-----
+
+Those using Smarty with security enabled: a hole was found that allowed PHP code to be executed from within a template file. This has been fixed and you are engouraged to upgrade immediately. Note that this hole does NOT affect the security of your web server or PHP applications, only the ability for someone editing a template to execute PHP code. Other changes in this release can be found in the NEWS file.
+
+2.5.0
+-----
+
+Very minor adjustments since RC2, see the NEWS file for details.
+
+2.5.0-RC2
+---------
+
+Many fixes since the RC1 release. This one is as close to production quality as
+they come, so this will be the last release before 2.5.0. The SGML documentation
+files have also been removed from the tarball. If you want them, get them from
+the CVS repository.
+
+2.5.0-RC1
+---------
+
+Release Candidate 1. All $smarty vars can now be dynamic, such as
+$smarty.get.$foo. A new class function get_function_object() gets you a
+reference to an assigned object, useful within your own custom functions.
+append() can now merge as well as append with a third optional attribute. A new
+class function get_config_vars() was added, and get_template_vars() can now be
+used to get individual vars. Full variable syntax is now supported within
+double quotes via a backtick (`) syntax. Files created by smarty are now
+written to a tmp file then renamed to avoid file lock retention. html_radios,
+html_checkboxes, html_table, html_image, nl2br functions added, see the NEWS
+file for full details.
+
+2.4.2
+-----
+Another point release. Added support for dynamic object reference syntax
+($foo->$bar), support for full variable syntax within quotes ("$foo[0].bar"),
+and other minor fixes. See the NEWS file for full details.
+
+2.4.1
+-----
+
+This is basically a point release, cleaning up a few things caught
+in the 2.4.0 release. See the NEWS file for full details.
+
+2.4.0
+-----
+
+Smarty now supports the ability to access objects within the templates. Two
+methods are available, one which closely follows Smartys conventions, and
+another that follows more traditional object syntax for those familiar with
+PHP.
+
+The internal compiling engine has also undergone some major work. The regex
+parsing was rewritten to be much more strict, more secure and more
+maintainable. Config files are now compiled, which can speed up pages quite a
+bit that use config files extensively. Assigned variables are no longer
+extracted to PHP namespace, saving an extract call for every template. There is
+now support for applying modifiers to static values and functions. You can now
+access constants with $smarty.const.VAR. See the NEWS file for complete
+changes.
+
+2.3.1
+-----
+
+The mtime on compiled files will now match the source files, in the case where
+the source file may not get the current timestamp, recompiling will still work
+as expected. Proper support for open_basedir has been added, so Smarty should
+work correctly in safe mode. Added a few new features such as textformat block
+function, strip variable modifier and optgroup support for html_options. Also
+other minor bug fixes, see the Change Log.
+
+2.3.0
+-----
+
+Smarty now has a {debug} template function that brings up the debugging console
+right where {debug} is called, regardless of $debugging settings. This works a
+little different than turning on $debugging in the sense that it shows all the
+template variables available at the time {debug} is called, including local
+scope vars. It does not show the templates names however, since this
+executed during runtime of the template.
+
+You can now supply an expire time when clearing cache or compile files. This is
+mostly useful for removing stale files via the API.
+
+Plugins now stop execution upon error, instead of outputting a warning and
+continuing.
+
+Two new API functions, assign_by_ref() and append_by_ref() were added. They
+allow assigning template variables by reference. This can make a significant
+performance gain, especially if you are assigning large arrays of data. PHP 5.0
+will do this implicitly, so these functions are basically workarounds.
+
+Several misc bug fixes, see the Change Log for information.
+
+
+2.2.0
+-----
+
+Smarty now allows an array of paths for the $plugin_dir class variable. The
+directories will be searched in the order they are given, so for efficiency keep
+the most-used plugins at the top. Also, absolute paths to the plugin directories are
+more efficient than relying on the PHP include_path.
+
+Cache files can now be grouped with the cache_id. See the documentation under
+the new "Caching" section for details. compile_id also respects the same
+grouping syntax. The cache/compile file structure changed, so be sure to clear
+out all your cache and compile files when upgrading Smarty. Also if you are
+using PHP-accelerator, restart apache. I've seen some quirky things happen if
+the phpa files do not get cleared (known issue with phpa and parent
+class-member changes, so just clear 'em.)
+
+Smarty now correctly respects the PHP include_path for $template_dir, $compile_dir,
+$cache_dir, $config_dir and $plugin_dir. Be aware that relying on the
+include_path is an overhead, try to use absolute pathnames when possible
+(or relative to working directory.)
+
+Documentation has been updated and rearranged a bit. Most notably, the
+installation instructions are completely revamped, and a new Caching section
+explains Smarty's caching in detail along with the new grouping functionality.
+
+Many misc. bug fixes and enhancements, see the full ChangeLog (NEWS file) for
+details.
+
+2.1.1
+-----
+
+There was a bug with template paths and the include_path, this has been fixed.
+Also register_outputfilter() did not work, this is fixed. A new template
+function named "cycle" has been added to the distribution, nice for cycling
+through a list (or array) of values.
+
+2.1.0
+-----
+
+This release has quite a few new features and fixes. Most notable are the
+introduction of block functions, so you can write plugins that work on a block
+of text with {func}{/func} notation. Also output filters were added, so you can
+apply a function against the output of your templates. This differs from the
+postfilter function, which works on the compiled template at compile time, and
+output filters work on the template output at runtime.
+
+Many other features and bug fixes are noted in the NEWS file.
+
+
+2.0.1
+-----
+
+This is a point release, fixing a few bugs and cleaning things up. A plugin
+was renamed, the dash "-" was removed from compiled template and cached file
+names. If you're upgrading, you might want to clear them out first. See the
+ChangeLog for details.
+
+2.0.0
+-----
+
+This release is a huge milestone for Smarty. Most notable new things are a
+plugin architecture, removal of PEAR dependency, and optimizations that
+drastically improve the performance of Smarty in most cases.
+
+The plugin architecture allows modifiers, custom functions, compiler functions,
+prefilters, postfilters, resources, and insert functions to be added by
+simply dropping a file into the plugins directory. Once dropped in, they are
+automatically registered by the template engine. This makes user-contributed
+plugins easy to manage, as well as the internal workings of Smarty easy to
+control and customize. This new architecture depends on the __FILE__ constant,
+which contains the full path to the executing script. Some older versions of
+PHP incorrectly gave the script name and not the full filesystem path. Be sure
+your version of PHP populates __FILE__ correctly. If you use custom template
+resource functions, the format of these changed with the plugin architecture.
+Be sure to update your functions accordingly. See the template resource section
+of the documentation.
+
+The PEAR dependancy was removed from Smarty. The Config_File class that comes
+with Smarty was actually what needed PEAR for error handling which Smarty didn't
+use, but now everything is self-contained.
+
+Performance improvements are graphed on the benchmark page, you will see that
+overall performance has been sped up by as much as 80% in some cases.
+
+Smarty-cached pages now support If-Modified-Since headers, meaning that if a
+cached template page has not changed since the last request, a "304 Not
+Modified" header will be sent instead of resending the same page. This is
+disabled by default, change the setting of $cache_modified_check.
+
+
+1.5.2
+-----
+
+Mostly bug fixes, added a default template resource handler.
+
+
+1.5.1
+-----
+
+Critical bug fix release. If you use caching, you'll need to upgrade.
+
+
+1.5.0
+-----
+
+Several feature enhancements were made to this version, most notably the
+{foreach ...} command which is an alternative to {section ...} with an easier
+syntax for looping through a single array of values. Several functions were
+enhanced so that the output can be automatically assigned to a template
+variable instead of displayed (assign attribute). Cache files can now be
+controlled with a custom function as an alternative to the built-in file based
+method. Many code cleanups and bug fixed went into this release as well.
+
+
+1.4.6
+-----
+
+The behavior with caching and compile_check has been slightly enhanced. If
+caching is enabled AND compile_check is enabled, the cache will immediately get
+regenerated if _any_ involved template or config file is updated. This imposes
+a slight performance hit because it must check all the files for changes, so be
+sure to run live sites with caching enabled and compile_check disabled for best
+performance. If you update a template or config file, simply turn on
+compile_check, load the page, then turn it back off. This will update the cache
+file with the new content. This is accomplished by maintaining a list of
+included/loaded templates and config files at the beginning of the cache file.
+Therefore it is advisable to remove all cache files after upgrading to 1.4.6
+(although not absolutely necessary, old cache files will regenerate)
+
+The debug console now has script timing and array values printed. You MUST
+update your debug.tpl file with this version of Smarty. Also, the new debug.tpl
+will not work with older versions of Smarty.
+
+
+1.4.5
+-----
+
+Mostly bug fixes and minor improvements. Added compile id for separate compiled
+versions of the same script. The directory format and filename convention for
+the files in templates_c has changed, so you may want to remove all of the
+existing ones before you upgrade.
+
+
+1.4.4
+-----
+
+A few bug fixes, new section looping attributes and properties, debugging
+console function for control via URL, and overLib integration and access
+to request variables from within the template.
+
+
+1.4.3
+-----
+
+This release has a few bug fixes and several enhancements. Smarty now supports
+template security for third-party template editing. These features disallow the
+ability for someone to execute commands or PHP code from the template language.
+Smarty also now has a built-in debugging console, which is a javascript pop-up
+window that displays all the included template names and assigned variables.
+
+
+1.4.2
+-----
+
+This was mostly one bug fix with variable scoping within included templates
+and a few documentation changes and updates. See the ChangeLog file for full
+details.
+
+
+1.4.1
+-----
+
+It seems that the EX_LOCK logic from the previous release didn't fix all the
+problems with windows platforms. Hopefully this one does. It basically
+disables file locking on windows, so there is a potential that two programs
+could write over the same file at the same time, fyi.
+
+The reset is minor bug fixes, please refer to the ChangeLog file.
+
+
+1.4.0
+-----
+
+IMPORTANT NOTICE
+
+Smarty now has a new syntax for accessing elements within section loops. The
+new syntax is easier to use and nicely handles data structures of any
+complexity. Consequently, this breaks the old syntax.
+
+Here is an example of the syntax change:
+
+old syntax:
+{$sec1/sec2/sec3/customer.phone}
+
+new syntax:
+{$customer[$sec1][$sec2][$sec3].phone}
+
+The section names used to come first, followed by the variable name. Now the
+variable name always comes first, followed by the section names in brackets.
+You can access variable indexes anywhere, depending on how you passed the
+variables in.
+
+To fix your current templates, we have provided a script that will adjust the
+syntax for you. Located in misc/fix_vars.php, run this script from the the
+command line, giving each template as an argument. Be sure to use absolute
+pathnames, or pathnames relative to the executing script. Probably the easiest
+way to do this is to copy the fix_vars.php script into your template directory
+and run 'php -q fix_vars.php *.tpl' Be sure you have proper write permission,
+and backup your scripts first to be safe! The examples in the 1.4.0
+documentation have been updated to reflect the changes.
+
+cd /path/to/templates
+cp /path/to/fix_vars.php .
+find . -name "*.tpl" -exec php -q ./fix_vars.php {} \;
+
+NEW AND IMPROVED COMPILATION PROCESS
+
+Smarty 1.4.0 also has a new compilation process. Instead of compiling all the
+templates up front, it now compiles them at runtime. This has several
+advantages. First of all, there is no longer a need to have a single template
+directory. You can now have arbitrary template sources, such as multiple
+directories or even database calls. This also speeds the performance of Smarty
+when $compile_check is enabled, since it is only checking the template that is
+being executed instead of everything found in the template directory. The
+$tpl_file_ext is no longer needed, but kept for backward compatability.
+Templates can now be named anything you like with any extension.
+
+MINOR FIXES
+
+A workaround for LOCK_EX on Windows systems was added, and changed a couple of
+file permissions for better security on public servers.
+
+$show_info_header is now defaulted to false instead of true. This header causes
+problems when displaying content other than HTML, so now you must explicitly
+set this flag to true to show the header information (or change the default in
+your copy of Smarty.)
+
+Documentation is written in docbook format. I updated the docbook -> HTML
+generating software & style-sheets, and consequently the examples are no longer
+in a different background color. If anyone wants to contribute a better
+stylesheet or help with documentation, drop me a line. <monte at ohrt dot com>
+
+CHANGES/ENHANCEMENTS/UPDATES
+
+date_format, html_select_date and html_select_time used to require a unix
+timestamp as the format of the date passed into the template. Smarty is now a
+bit smarter at this. It will take a unix timestamp, a mysql timestamp, or any
+date string that is parsable by strtotime, such as 10/01/2001 or 2001-10-01,
+etc. Just give some formats a try and see what works.
+
+Smarty now has template prefilters, meaning that you can run your templates
+through custom functions before they are compiled. This is good for things like
+removing unwanted comments, keeping an eye on words or functionality people are
+putting in templates, translating XML -> HTML, etc. See the register_prefilter
+documentation for more info.
+
+Another addition are the so-called compiler functions. These are custom
+functions registered by the user that are executed at compilation time of the
+template. They can be used to inject PHP code or time-sensitive static content
+into the compiled template.
+
+The run-time custom functions are now passed the Smarty object as the second
+parameter. This can be used, for example, to assign or clear template variables
+from inside the custom function.
+
+clear_compile_dir() was added for clearing out compiled versions of your
+templates. Not something normally needed, but you may have a need for this if
+you have $compile_check set to false and you periodically update templates via
+some automated process. As of 1.4.0, uncompiled templates _always_ get
+compiled regardless of $compile_check setting, although they won't be checked
+for recompile if $compile_check is set to false.
+
+You can now refer to properties of objects assigned from PHP by using the '->'
+symbol and specifying the property name after it, e.g. $foo->bar.
+
+{php}{/php} tags were added to embed php into the templates. Not normally
+needed, but some circumstances may call for it. Check out the "componentized
+templates" tip in the documentation for an example.
+
+{capture}{/capture} and {counter} functions were added. See the documentation
+for a complete description and examples.
+
+UPGRADE NOTES
+
+The format of the files created in the $compile_dir are now a bit different.
+The compiled template filename is the template resource name url-encoded.
+Therefore, all compiled files are now in the top directory of $compile_dir.
+This was done to make way for arbitrary template resources. Each compiled
+template also has a header that states what template resource was used to
+create it. From a unix command prompt, you can use "head -2 *" to see the first
+two lines of each file.
+
+When upgrading to 1.4.0, you will want to clear out all your old files in the
+$compile_dir. If you have $compile_check set to false and the compiled template
+does not yet exist, it will compile it regardless of this setting. This way you
+can clear out the $compile_dir and not worry about setting $compile_check to
+true to get the inital compilation under way.
+
+
+1.3.2
+-----
+
+Smarty now has (an optional) header prepended to the output of the Smarty
+templates. This displays the Smarty version and the date/time when the page was
+generated. This is useful for debugging your cache routines, and purely
+informational so there is evidence that the page was generated by Smarty. Set
+$show_info_header to false to disable it.
+
+{config_load ...} performance was tuned by placing the loaded variables into a
+global array, so basically a config file is read from the file system and
+placed into a php array structure only once, no matter how many times it is
+called in any of the templates. The scope of the loaded variables has changed a
+bit as well. Variables loaded by config_load used to be treated as global
+variables, meaning that parent templates (templates that included the current
+template) could see them. Now the default behavior is such that loaded
+variables are only visible by the current template and child templates (all
+templates included after the {config_load ...} is called.) To mimic the
+original behavior, provide the attribute "global=yes" like so: {config_load
+file="mystuff.conf" global=yes}. Now when you load in mystuff.conf, the
+variables will be visible to parent templates (merged with any existing config
+variables.)
+
+A formatting attribute was added to the {math ...} function, adding the ability
+to control the format of the output. Use the same formatting syntax as the PHP
+function sprintf().
+
+{html_select_time ...} was added, a custom function that works much like
+{html_select_date ...} except it displays time elements instead of dates.
+
+A few custom modifiers were added: count_characters, count_words,
+count_sentences, count_paragraphs. All pretty self-explanatory.
+
+/* vim: set et: */
--- /dev/null
+* handle asp style tags in $php_handler
+* fix all E_NOTICE warnings
+* make simple math easier
+* caching all but parts of the template
+* change plugins so $smarty variable always comes first
+* get cache ttl with function call
+FIX: make inserts use normal functions before plugins
+UPD: change it so that if template comes from some resource,
+ that resource stays as the default, no need to specify it
+ in includes.
--- /dev/null
+title = Welcome to Smarty!
+cutoff_size = 40
+
+[setup]
+bold = true
--- /dev/null
+<?php
+
+require '../libs/Smarty.class.php';
+
+$smarty = new Smarty;
+
+$smarty->compile_check = true;
+$smarty->debugging = true;
+
+$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill");
+$smarty->assign("FirstName",array("John","Mary","James","Henry"));
+$smarty->assign("LastName",array("Doe","Smith","Johnson","Case"));
+$smarty->assign("Class",array(array("A","B","C","D"), array("E", "F", "G", "H"),
+ array("I", "J", "K", "L"), array("M", "N", "O", "P")));
+
+$smarty->assign("contacts", array(array("phone" => "1", "fax" => "2", "cell" => "3"),
+ array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234")));
+
+$smarty->assign("option_values", array("NY","NE","KS","IA","OK","TX"));
+$smarty->assign("option_output", array("New York","Nebraska","Kansas","Iowa","Oklahoma","Texas"));
+$smarty->assign("option_selected", "NE");
+
+$smarty->display('index.tpl');
+
+?>
--- /dev/null
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+{popup_init src="/javascripts/overlib.js"}
+<TITLE>{$title} - {$Name}</TITLE>
+</HEAD>
+<BODY bgcolor="#ffffff">
--- /dev/null
+{config_load file=test.conf section="setup"}
+{include file="header.tpl" title=foo}
+
+<PRE>
+
+{* bold and title are read from the config file *}
+{if #bold#}<b>{/if}
+{* capitalize the first letters of each word of the title *}
+Title: {#title#|capitalize}
+{if #bold#}</b>{/if}
+
+The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
+
+The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
+
+Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
+
+The value of {ldelim}$Name{rdelim} is <b>{$Name}</b>
+
+variable modifier example of {ldelim}$Name|upper{rdelim}
+
+<b>{$Name|upper}</b>
+
+
+An example of a section loop:
+
+{section name=outer loop=$FirstName}
+{if $smarty.section.outer.index is odd by 2}
+ {$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
+{else}
+ {$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
+{/if}
+{sectionelse}
+ none
+{/section}
+
+An example of section looped key values:
+
+{section name=sec1 loop=$contacts}
+ phone: {$contacts[sec1].phone}<br>
+ fax: {$contacts[sec1].fax}<br>
+ cell: {$contacts[sec1].cell}<br>
+{/section}
+<p>
+
+testing strip tags
+{strip}
+<table border=0>
+ <tr>
+ <td>
+ <A HREF="{$SCRIPT_NAME}">
+ <font color="red">This is a test </font>
+ </A>
+ </td>
+ </tr>
+</table>
+{/strip}
+
+</PRE>
+
+This is an example of the html_select_date function:
+
+<form>
+{html_select_date start_year=1998 end_year=2010}
+</form>
+
+This is an example of the html_select_time function:
+
+<form>
+{html_select_time use_24_hours=false}
+</form>
+
+This is an example of the html_options function:
+
+<form>
+<select name=states>
+{html_options values=$option_values selected=$option_selected output=$option_output}
+</select>
+</form>
+
+{include file="footer.tpl"}
--- /dev/null
+<?php
+
+/**
+ * Config_File class.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @version 2.6.26
+ * @copyright Copyright: 2001-2005 New Digital Group, Inc.
+ * @author Andrei Zmievski <andrei@php.net>
+ * @access public
+ * @package Smarty
+ */
+
+/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */
+
+/**
+ * Config file reading class
+ * @package Smarty
+ */
+class Config_File {
+ /**#@+
+ * Options
+ * @var boolean
+ */
+ /**
+ * Controls whether variables with the same name overwrite each other.
+ */
+ var $overwrite = true;
+
+ /**
+ * Controls whether config values of on/true/yes and off/false/no get
+ * converted to boolean values automatically.
+ */
+ var $booleanize = true;
+
+ /**
+ * Controls whether hidden config sections/vars are read from the file.
+ */
+ var $read_hidden = true;
+
+ /**
+ * Controls whether or not to fix mac or dos formatted newlines.
+ * If set to true, \r or \r\n will be changed to \n.
+ */
+ var $fix_newlines = true;
+ /**#@-*/
+
+ /** @access private */
+ var $_config_path = "";
+ var $_config_data = array();
+ /**#@-*/
+
+ /**
+ * Constructs a new config file class.
+ *
+ * @param string $config_path (optional) path to the config files
+ */
+ function Config_File($config_path = NULL)
+ {
+ if (isset($config_path))
+ $this->set_path($config_path);
+ }
+
+
+ /**
+ * Set the path where configuration files can be found.
+ *
+ * @param string $config_path path to the config files
+ */
+ function set_path($config_path)
+ {
+ if (!empty($config_path)) {
+ if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
+ $this->_trigger_error_msg("Bad config file path '$config_path'");
+ return;
+ }
+ if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
+ $config_path .= DIRECTORY_SEPARATOR;
+ }
+
+ $this->_config_path = $config_path;
+ }
+ }
+
+
+ /**
+ * Retrieves config info based on the file, section, and variable name.
+ *
+ * @param string $file_name config file to get info for
+ * @param string $section_name (optional) section to get info for
+ * @param string $var_name (optional) variable to get info for
+ * @return string|array a value or array of values
+ */
+ function get($file_name, $section_name = NULL, $var_name = NULL)
+ {
+ if (empty($file_name)) {
+ $this->_trigger_error_msg('Empty config file name');
+ return;
+ } else {
+ $file_name = $this->_config_path . $file_name;
+ if (!isset($this->_config_data[$file_name]))
+ $this->load_file($file_name, false);
+ }
+
+ if (!empty($var_name)) {
+ if (empty($section_name)) {
+ return $this->_config_data[$file_name]["vars"][$var_name];
+ } else {
+ if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
+ return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
+ else
+ return array();
+ }
+ } else {
+ if (empty($section_name)) {
+ return (array)$this->_config_data[$file_name]["vars"];
+ } else {
+ if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
+ return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
+ else
+ return array();
+ }
+ }
+ }
+
+
+ /**
+ * Retrieves config info based on the key.
+ *
+ * @param $file_name string config key (filename/section/var)
+ * @return string|array same as get()
+ * @uses get() retrieves information from config file and returns it
+ */
+ function &get_key($config_key)
+ {
+ list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
+ $result = &$this->get($file_name, $section_name, $var_name);
+ return $result;
+ }
+
+ /**
+ * Get all loaded config file names.
+ *
+ * @return array an array of loaded config file names
+ */
+ function get_file_names()
+ {
+ return array_keys($this->_config_data);
+ }
+
+
+ /**
+ * Get all section names from a loaded file.
+ *
+ * @param string $file_name config file to get section names from
+ * @return array an array of section names from the specified file
+ */
+ function get_section_names($file_name)
+ {
+ $file_name = $this->_config_path . $file_name;
+ if (!isset($this->_config_data[$file_name])) {
+ $this->_trigger_error_msg("Unknown config file '$file_name'");
+ return;
+ }
+
+ return array_keys($this->_config_data[$file_name]["sections"]);
+ }
+
+
+ /**
+ * Get all global or section variable names.
+ *
+ * @param string $file_name config file to get info for
+ * @param string $section_name (optional) section to get info for
+ * @return array an array of variables names from the specified file/section
+ */
+ function get_var_names($file_name, $section = NULL)
+ {
+ if (empty($file_name)) {
+ $this->_trigger_error_msg('Empty config file name');
+ return;
+ } else if (!isset($this->_config_data[$file_name])) {
+ $this->_trigger_error_msg("Unknown config file '$file_name'");
+ return;
+ }
+
+ if (empty($section))
+ return array_keys($this->_config_data[$file_name]["vars"]);
+ else
+ return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
+ }
+
+
+ /**
+ * Clear loaded config data for a certain file or all files.
+ *
+ * @param string $file_name file to clear config data for
+ */
+ function clear($file_name = NULL)
+ {
+ if ($file_name === NULL)
+ $this->_config_data = array();
+ else if (isset($this->_config_data[$file_name]))
+ $this->_config_data[$file_name] = array();
+ }
+
+
+ /**
+ * Load a configuration file manually.
+ *
+ * @param string $file_name file name to load
+ * @param boolean $prepend_path whether current config path should be
+ * prepended to the filename
+ */
+ function load_file($file_name, $prepend_path = true)
+ {
+ if ($prepend_path && $this->_config_path != "")
+ $config_file = $this->_config_path . $file_name;
+ else
+ $config_file = $file_name;
+
+ ini_set('track_errors', true);
+ $fp = @fopen($config_file, "r");
+ if (!is_resource($fp)) {
+ $this->_trigger_error_msg("Could not open config file '$config_file'");
+ return false;
+ }
+
+ $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
+ fclose($fp);
+
+ $this->_config_data[$config_file] = $this->parse_contents($contents);
+ return true;
+ }
+
+ /**
+ * Store the contents of a file manually.
+ *
+ * @param string $config_file file name of the related contents
+ * @param string $contents the file-contents to parse
+ */
+ function set_file_contents($config_file, $contents)
+ {
+ $this->_config_data[$config_file] = $this->parse_contents($contents);
+ return true;
+ }
+
+ /**
+ * parse the source of a configuration file manually.
+ *
+ * @param string $contents the file-contents to parse
+ */
+ function parse_contents($contents)
+ {
+ if($this->fix_newlines) {
+ // fix mac/dos formatted newlines
+ $contents = preg_replace('!\r\n?!', "\n", $contents);
+ }
+
+ $config_data = array();
+ $config_data['sections'] = array();
+ $config_data['vars'] = array();
+
+ /* reference to fill with data */
+ $vars =& $config_data['vars'];
+
+ /* parse file line by line */
+ preg_match_all('!^.*\r?\n?!m', $contents, $match);
+ $lines = $match[0];
+ for ($i=0, $count=count($lines); $i<$count; $i++) {
+ $line = $lines[$i];
+ if (empty($line)) continue;
+
+ if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
+ /* section found */
+ if (substr($match[1], 0, 1) == '.') {
+ /* hidden section */
+ if ($this->read_hidden) {
+ $section_name = substr($match[1], 1);
+ } else {
+ /* break reference to $vars to ignore hidden section */
+ unset($vars);
+ $vars = array();
+ continue;
+ }
+ } else {
+ $section_name = $match[1];
+ }
+ if (!isset($config_data['sections'][$section_name]))
+ $config_data['sections'][$section_name] = array('vars' => array());
+ $vars =& $config_data['sections'][$section_name]['vars'];
+ continue;
+ }
+
+ if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
+ /* variable found */
+ $var_name = rtrim($match[1]);
+ if (strpos($match[2], '"""') === 0) {
+ /* handle multiline-value */
+ $lines[$i] = substr($match[2], 3);
+ $var_value = '';
+ while ($i<$count) {
+ if (($pos = strpos($lines[$i], '"""')) === false) {
+ $var_value .= $lines[$i++];
+ } else {
+ /* end of multiline-value */
+ $var_value .= substr($lines[$i], 0, $pos);
+ break;
+ }
+ }
+ $booleanize = false;
+
+ } else {
+ /* handle simple value */
+ $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
+ $booleanize = $this->booleanize;
+
+ }
+ $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
+ }
+ /* else unparsable line / means it is a comment / means ignore it */
+ }
+ return $config_data;
+ }
+
+ /**#@+ @access private */
+ /**
+ * @param array &$container
+ * @param string $var_name
+ * @param mixed $var_value
+ * @param boolean $booleanize determines whether $var_value is converted to
+ * to true/false
+ */
+ function _set_config_var(&$container, $var_name, $var_value, $booleanize)
+ {
+ if (substr($var_name, 0, 1) == '.') {
+ if (!$this->read_hidden)
+ return;
+ else
+ $var_name = substr($var_name, 1);
+ }
+
+ if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
+ $this->_trigger_error_msg("Bad variable name '$var_name'");
+ return;
+ }
+
+ if ($booleanize) {
+ if (preg_match("/^(on|true|yes)$/i", $var_value))
+ $var_value = true;
+ else if (preg_match("/^(off|false|no)$/i", $var_value))
+ $var_value = false;
+ }
+
+ if (!isset($container[$var_name]) || $this->overwrite)
+ $container[$var_name] = $var_value;
+ else {
+ settype($container[$var_name], 'array');
+ $container[$var_name][] = $var_value;
+ }
+ }
+
+ /**
+ * @uses trigger_error() creates a PHP warning/error
+ * @param string $error_msg
+ * @param integer $error_type one of
+ */
+ function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
+ {
+ trigger_error("Config_File error: $error_msg", $error_type);
+ }
+ /**#@-*/
+}
+
+?>
--- /dev/null
+<?php
+
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: Smarty.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @package Smarty
+ * @version 2.6.26
+ */
+
+/* $Id: Smarty.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
+
+/**
+ * DIR_SEP isn't used anymore, but third party apps might
+ */
+if(!defined('DIR_SEP')) {
+ define('DIR_SEP', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * if not defined, include_path will be used. Sets SMARTY_DIR only if user
+ * application has not already defined it.
+ */
+
+if (!defined('SMARTY_DIR')) {
+ define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+
+if (!defined('SMARTY_CORE_DIR')) {
+ define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
+}
+
+define('SMARTY_PHP_PASSTHRU', 0);
+define('SMARTY_PHP_QUOTE', 1);
+define('SMARTY_PHP_REMOVE', 2);
+define('SMARTY_PHP_ALLOW', 3);
+
+/**
+ * @package Smarty
+ */
+class Smarty
+{
+ /**#@+
+ * Smarty Configuration Section
+ */
+
+ /**
+ * The name of the directory where templates are located.
+ *
+ * @var string
+ */
+ var $template_dir = 'templates';
+
+ /**
+ * The directory where compiled templates are located.
+ *
+ * @var string
+ */
+ var $compile_dir = 'templates_c';
+
+ /**
+ * The directory where config files are located.
+ *
+ * @var string
+ */
+ var $config_dir = 'configs';
+
+ /**
+ * An array of directories searched for plugins.
+ *
+ * @var array
+ */
+ var $plugins_dir = array('plugins');
+
+ /**
+ * If debugging is enabled, a debug console window will display
+ * when the page loads (make sure your browser allows unrequested
+ * popup windows)
+ *
+ * @var boolean
+ */
+ var $debugging = false;
+
+ /**
+ * When set, smarty does uses this value as error_reporting-level.
+ *
+ * @var integer
+ */
+ var $error_reporting = null;
+
+ /**
+ * This is the path to the debug console template. If not set,
+ * the default one will be used.
+ *
+ * @var string
+ */
+ var $debug_tpl = '';
+
+ /**
+ * This determines if debugging is enable-able from the browser.
+ * <ul>
+ * <li>NONE => no debugging control allowed</li>
+ * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+ * </ul>
+ * @link http://www.foo.dom/index.php?SMARTY_DEBUG
+ * @var string
+ */
+ var $debugging_ctrl = 'NONE';
+
+ /**
+ * This tells Smarty whether to check for recompiling or not. Recompiling
+ * does not need to happen unless a template or config file is changed.
+ * Typically you enable this during development, and disable for
+ * production.
+ *
+ * @var boolean
+ */
+ var $compile_check = true;
+
+ /**
+ * This forces templates to compile every time. Useful for development
+ * or debugging.
+ *
+ * @var boolean
+ */
+ var $force_compile = false;
+
+ /**
+ * This enables template caching.
+ * <ul>
+ * <li>0 = no caching</li>
+ * <li>1 = use class cache_lifetime value</li>
+ * <li>2 = use cache_lifetime in cache file</li>
+ * </ul>
+ * @var integer
+ */
+ var $caching = 0;
+
+ /**
+ * The name of the directory for cache files.
+ *
+ * @var string
+ */
+ var $cache_dir = 'cache';
+
+ /**
+ * This is the number of seconds cached content will persist.
+ * <ul>
+ * <li>0 = always regenerate cache</li>
+ * <li>-1 = never expires</li>
+ * </ul>
+ *
+ * @var integer
+ */
+ var $cache_lifetime = 3600;
+
+ /**
+ * Only used when $caching is enabled. If true, then If-Modified-Since headers
+ * are respected with cached content, and appropriate HTTP headers are sent.
+ * This way repeated hits to a cached page do not send the entire page to the
+ * client every time.
+ *
+ * @var boolean
+ */
+ var $cache_modified_check = false;
+
+ /**
+ * This determines how Smarty handles "<?php ... ?>" tags in templates.
+ * possible values:
+ * <ul>
+ * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
+ * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li>
+ * <li>SMARTY_PHP_REMOVE -> remove php tags</li>
+ * <li>SMARTY_PHP_ALLOW -> execute php tags</li>
+ * </ul>
+ *
+ * @var integer
+ */
+ var $php_handling = SMARTY_PHP_PASSTHRU;
+
+ /**
+ * This enables template security. When enabled, many things are restricted
+ * in the templates that normally would go unchecked. This is useful when
+ * untrusted parties are editing templates and you want a reasonable level
+ * of security. (no direct execution of PHP in templates for example)
+ *
+ * @var boolean
+ */
+ var $security = false;
+
+ /**
+ * This is the list of template directories that are considered secure. This
+ * is used only if {@link $security} is enabled. One directory per array
+ * element. {@link $template_dir} is in this list implicitly.
+ *
+ * @var array
+ */
+ var $secure_dir = array();
+
+ /**
+ * These are the security settings for Smarty. They are used only when
+ * {@link $security} is enabled.
+ *
+ * @var array
+ */
+ var $security_settings = array(
+ 'PHP_HANDLING' => false,
+ 'IF_FUNCS' => array('array', 'list',
+ 'isset', 'empty',
+ 'count', 'sizeof',
+ 'in_array', 'is_array',
+ 'true', 'false', 'null'),
+ 'INCLUDE_ANY' => false,
+ 'PHP_TAGS' => false,
+ 'MODIFIER_FUNCS' => array('count'),
+ 'ALLOW_CONSTANTS' => false,
+ 'ALLOW_SUPER_GLOBALS' => true
+ );
+
+ /**
+ * This is an array of directories where trusted php scripts reside.
+ * {@link $security} is disabled during their inclusion/execution.
+ *
+ * @var array
+ */
+ var $trusted_dir = array();
+
+ /**
+ * The left delimiter used for the template tags.
+ *
+ * @var string
+ */
+ var $left_delimiter = '{';
+
+ /**
+ * The right delimiter used for the template tags.
+ *
+ * @var string
+ */
+ var $right_delimiter = '}';
+
+ /**
+ * The order in which request variables are registered, similar to
+ * variables_order in php.ini E = Environment, G = GET, P = POST,
+ * C = Cookies, S = Server
+ *
+ * @var string
+ */
+ var $request_vars_order = 'EGPCS';
+
+ /**
+ * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
+ * are uses as request-vars or $_*[]-vars. note: if
+ * request_use_auto_globals is true, then $request_vars_order has
+ * no effect, but the php-ini-value "gpc_order"
+ *
+ * @var boolean
+ */
+ var $request_use_auto_globals = true;
+
+ /**
+ * Set this if you want different sets of compiled files for the same
+ * templates. This is useful for things like different languages.
+ * Instead of creating separate sets of templates per language, you
+ * set different compile_ids like 'en' and 'de'.
+ *
+ * @var string
+ */
+ var $compile_id = null;
+
+ /**
+ * This tells Smarty whether or not to use sub dirs in the cache/ and
+ * templates_c/ directories. sub directories better organized, but
+ * may not work well with PHP safe mode enabled.
+ *
+ * @var boolean
+ *
+ */
+ var $use_sub_dirs = false;
+
+ /**
+ * This is a list of the modifiers to apply to all template variables.
+ * Put each modifier in a separate array element in the order you want
+ * them applied. example: <code>array('escape:"htmlall"');</code>
+ *
+ * @var array
+ */
+ var $default_modifiers = array();
+
+ /**
+ * This is the resource type to be used when not specified
+ * at the beginning of the resource path. examples:
+ * $smarty->display('file:index.tpl');
+ * $smarty->display('db:index.tpl');
+ * $smarty->display('index.tpl'); // will use default resource type
+ * {include file="file:index.tpl"}
+ * {include file="db:index.tpl"}
+ * {include file="index.tpl"} {* will use default resource type *}
+ *
+ * @var array
+ */
+ var $default_resource_type = 'file';
+
+ /**
+ * The function used for cache file handling. If not set, built-in caching is used.
+ *
+ * @var null|string function name
+ */
+ var $cache_handler_func = null;
+
+ /**
+ * This indicates which filters are automatically loaded into Smarty.
+ *
+ * @var array array of filter names
+ */
+ var $autoload_filters = array();
+
+ /**#@+
+ * @var boolean
+ */
+ /**
+ * This tells if config file vars of the same name overwrite each other or not.
+ * if disabled, same name variables are accumulated in an array.
+ */
+ var $config_overwrite = true;
+
+ /**
+ * This tells whether or not to automatically booleanize config file variables.
+ * If enabled, then the strings "on", "true", and "yes" are treated as boolean
+ * true, and "off", "false" and "no" are treated as boolean false.
+ */
+ var $config_booleanize = true;
+
+ /**
+ * This tells whether hidden sections [.foobar] are readable from the
+ * tempalates or not. Normally you would never allow this since that is
+ * the point behind hidden sections: the application can access them, but
+ * the templates cannot.
+ */
+ var $config_read_hidden = false;
+
+ /**
+ * This tells whether or not automatically fix newlines in config files.
+ * It basically converts \r (mac) or \r\n (dos) to \n
+ */
+ var $config_fix_newlines = true;
+ /**#@-*/
+
+ /**
+ * If a template cannot be found, this PHP function will be executed.
+ * Useful for creating templates on-the-fly or other special action.
+ *
+ * @var string function name
+ */
+ var $default_template_handler_func = '';
+
+ /**
+ * The file that contains the compiler class. This can a full
+ * pathname, or relative to the php_include path.
+ *
+ * @var string
+ */
+ var $compiler_file = 'Smarty_Compiler.class.php';
+
+ /**
+ * The class used for compiling templates.
+ *
+ * @var string
+ */
+ var $compiler_class = 'Smarty_Compiler';
+
+ /**
+ * The class used to load config vars.
+ *
+ * @var string
+ */
+ var $config_class = 'Config_File';
+
+/**#@+
+ * END Smarty Configuration Section
+ * There should be no need to touch anything below this line.
+ * @access private
+ */
+ /**
+ * where assigned template vars are kept
+ *
+ * @var array
+ */
+ var $_tpl_vars = array();
+
+ /**
+ * stores run-time $smarty.* vars
+ *
+ * @var null|array
+ */
+ var $_smarty_vars = null;
+
+ /**
+ * keeps track of sections
+ *
+ * @var array
+ */
+ var $_sections = array();
+
+ /**
+ * keeps track of foreach blocks
+ *
+ * @var array
+ */
+ var $_foreach = array();
+
+ /**
+ * keeps track of tag hierarchy
+ *
+ * @var array
+ */
+ var $_tag_stack = array();
+
+ /**
+ * configuration object
+ *
+ * @var Config_file
+ */
+ var $_conf_obj = null;
+
+ /**
+ * loaded configuration settings
+ *
+ * @var array
+ */
+ var $_config = array(array('vars' => array(), 'files' => array()));
+
+ /**
+ * md5 checksum of the string 'Smarty'
+ *
+ * @var string
+ */
+ var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f';
+
+ /**
+ * Smarty version number
+ *
+ * @var string
+ */
+ var $_version = '2.6.26';
+
+ /**
+ * current template inclusion depth
+ *
+ * @var integer
+ */
+ var $_inclusion_depth = 0;
+
+ /**
+ * for different compiled templates
+ *
+ * @var string
+ */
+ var $_compile_id = null;
+
+ /**
+ * text in URL to enable debug mode
+ *
+ * @var string
+ */
+ var $_smarty_debug_id = 'SMARTY_DEBUG';
+
+ /**
+ * debugging information for debug console
+ *
+ * @var array
+ */
+ var $_smarty_debug_info = array();
+
+ /**
+ * info that makes up a cache file
+ *
+ * @var array
+ */
+ var $_cache_info = array();
+
+ /**
+ * default file permissions
+ *
+ * @var integer
+ */
+ var $_file_perms = 0644;
+
+ /**
+ * default dir permissions
+ *
+ * @var integer
+ */
+ var $_dir_perms = 0771;
+
+ /**
+ * registered objects
+ *
+ * @var array
+ */
+ var $_reg_objects = array();
+
+ /**
+ * table keeping track of plugins
+ *
+ * @var array
+ */
+ var $_plugins = array(
+ 'modifier' => array(),
+ 'function' => array(),
+ 'block' => array(),
+ 'compiler' => array(),
+ 'prefilter' => array(),
+ 'postfilter' => array(),
+ 'outputfilter' => array(),
+ 'resource' => array(),
+ 'insert' => array());
+
+
+ /**
+ * cache serials
+ *
+ * @var array
+ */
+ var $_cache_serials = array();
+
+ /**
+ * name of optional cache include file
+ *
+ * @var string
+ */
+ var $_cache_include = null;
+
+ /**
+ * indicate if the current code is used in a compiled
+ * include
+ *
+ * @var string
+ */
+ var $_cache_including = false;
+
+ /**#@-*/
+ /**
+ * The class constructor.
+ */
+ function Smarty()
+ {
+ $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
+ : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
+ }
+
+ /**
+ * assigns values to template variables
+ *
+ * @param array|string $tpl_var the template variable name(s)
+ * @param mixed $value the value to assign
+ */
+ function assign($tpl_var, $value = null)
+ {
+ if (is_array($tpl_var)){
+ foreach ($tpl_var as $key => $val) {
+ if ($key != '') {
+ $this->_tpl_vars[$key] = $val;
+ }
+ }
+ } else {
+ if ($tpl_var != '')
+ $this->_tpl_vars[$tpl_var] = $value;
+ }
+ }
+
+ /**
+ * assigns values to template variables by reference
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed $value the referenced value to assign
+ */
+ function assign_by_ref($tpl_var, &$value)
+ {
+ if ($tpl_var != '')
+ $this->_tpl_vars[$tpl_var] = &$value;
+ }
+
+ /**
+ * appends values to template variables
+ *
+ * @param array|string $tpl_var the template variable name(s)
+ * @param mixed $value the value to append
+ */
+ function append($tpl_var, $value=null, $merge=false)
+ {
+ if (is_array($tpl_var)) {
+ // $tpl_var is an array, ignore $value
+ foreach ($tpl_var as $_key => $_val) {
+ if ($_key != '') {
+ if(!@is_array($this->_tpl_vars[$_key])) {
+ settype($this->_tpl_vars[$_key],'array');
+ }
+ if($merge && is_array($_val)) {
+ foreach($_val as $_mkey => $_mval) {
+ $this->_tpl_vars[$_key][$_mkey] = $_mval;
+ }
+ } else {
+ $this->_tpl_vars[$_key][] = $_val;
+ }
+ }
+ }
+ } else {
+ if ($tpl_var != '' && isset($value)) {
+ if(!@is_array($this->_tpl_vars[$tpl_var])) {
+ settype($this->_tpl_vars[$tpl_var],'array');
+ }
+ if($merge && is_array($value)) {
+ foreach($value as $_mkey => $_mval) {
+ $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
+ }
+ } else {
+ $this->_tpl_vars[$tpl_var][] = $value;
+ }
+ }
+ }
+ }
+
+ /**
+ * appends values to template variables by reference
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed $value the referenced value to append
+ */
+ function append_by_ref($tpl_var, &$value, $merge=false)
+ {
+ if ($tpl_var != '' && isset($value)) {
+ if(!@is_array($this->_tpl_vars[$tpl_var])) {
+ settype($this->_tpl_vars[$tpl_var],'array');
+ }
+ if ($merge && is_array($value)) {
+ foreach($value as $_key => $_val) {
+ $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
+ }
+ } else {
+ $this->_tpl_vars[$tpl_var][] = &$value;
+ }
+ }
+ }
+
+
+ /**
+ * clear the given assigned template variable.
+ *
+ * @param string $tpl_var the template variable to clear
+ */
+ function clear_assign($tpl_var)
+ {
+ if (is_array($tpl_var))
+ foreach ($tpl_var as $curr_var)
+ unset($this->_tpl_vars[$curr_var]);
+ else
+ unset($this->_tpl_vars[$tpl_var]);
+ }
+
+
+ /**
+ * Registers custom function to be used in templates
+ *
+ * @param string $function the name of the template function
+ * @param string $function_impl the name of the PHP function to register
+ */
+ function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+ {
+ $this->_plugins['function'][$function] =
+ array($function_impl, null, null, false, $cacheable, $cache_attrs);
+
+ }
+
+ /**
+ * Unregisters custom function
+ *
+ * @param string $function name of template function
+ */
+ function unregister_function($function)
+ {
+ unset($this->_plugins['function'][$function]);
+ }
+
+ /**
+ * Registers object to be used in templates
+ *
+ * @param string $object name of template object
+ * @param object &$object_impl the referenced PHP object to register
+ * @param null|array $allowed list of allowed methods (empty = all)
+ * @param boolean $smarty_args smarty argument format, else traditional
+ * @param null|array $block_functs list of methods that are block format
+ */
+ function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+ {
+ settype($allowed, 'array');
+ settype($smarty_args, 'boolean');
+ $this->_reg_objects[$object] =
+ array(&$object_impl, $allowed, $smarty_args, $block_methods);
+ }
+
+ /**
+ * Unregisters object
+ *
+ * @param string $object name of template object
+ */
+ function unregister_object($object)
+ {
+ unset($this->_reg_objects[$object]);
+ }
+
+
+ /**
+ * Registers block function to be used in templates
+ *
+ * @param string $block name of template block
+ * @param string $block_impl PHP function to register
+ */
+ function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+ {
+ $this->_plugins['block'][$block] =
+ array($block_impl, null, null, false, $cacheable, $cache_attrs);
+ }
+
+ /**
+ * Unregisters block function
+ *
+ * @param string $block name of template function
+ */
+ function unregister_block($block)
+ {
+ unset($this->_plugins['block'][$block]);
+ }
+
+ /**
+ * Registers compiler function
+ *
+ * @param string $function name of template function
+ * @param string $function_impl name of PHP function to register
+ */
+ function register_compiler_function($function, $function_impl, $cacheable=true)
+ {
+ $this->_plugins['compiler'][$function] =
+ array($function_impl, null, null, false, $cacheable);
+ }
+
+ /**
+ * Unregisters compiler function
+ *
+ * @param string $function name of template function
+ */
+ function unregister_compiler_function($function)
+ {
+ unset($this->_plugins['compiler'][$function]);
+ }
+
+ /**
+ * Registers modifier to be used in templates
+ *
+ * @param string $modifier name of template modifier
+ * @param string $modifier_impl name of PHP function to register
+ */
+ function register_modifier($modifier, $modifier_impl)
+ {
+ $this->_plugins['modifier'][$modifier] =
+ array($modifier_impl, null, null, false);
+ }
+
+ /**
+ * Unregisters modifier
+ *
+ * @param string $modifier name of template modifier
+ */
+ function unregister_modifier($modifier)
+ {
+ unset($this->_plugins['modifier'][$modifier]);
+ }
+
+ /**
+ * Registers a resource to fetch a template
+ *
+ * @param string $type name of resource
+ * @param array $functions array of functions to handle resource
+ */
+ function register_resource($type, $functions)
+ {
+ if (count($functions)==4) {
+ $this->_plugins['resource'][$type] =
+ array($functions, false);
+
+ } elseif (count($functions)==5) {
+ $this->_plugins['resource'][$type] =
+ array(array(array(&$functions[0], $functions[1])
+ ,array(&$functions[0], $functions[2])
+ ,array(&$functions[0], $functions[3])
+ ,array(&$functions[0], $functions[4]))
+ ,false);
+
+ } else {
+ $this->trigger_error("malformed function-list for '$type' in register_resource");
+
+ }
+ }
+
+ /**
+ * Unregisters a resource
+ *
+ * @param string $type name of resource
+ */
+ function unregister_resource($type)
+ {
+ unset($this->_plugins['resource'][$type]);
+ }
+
+ /**
+ * Registers a prefilter function to apply
+ * to a template before compiling
+ *
+ * @param callback $function
+ */
+ function register_prefilter($function)
+ {
+ $this->_plugins['prefilter'][$this->_get_filter_name($function)]
+ = array($function, null, null, false);
+ }
+
+ /**
+ * Unregisters a prefilter function
+ *
+ * @param callback $function
+ */
+ function unregister_prefilter($function)
+ {
+ unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
+ }
+
+ /**
+ * Registers a postfilter function to apply
+ * to a compiled template after compilation
+ *
+ * @param callback $function
+ */
+ function register_postfilter($function)
+ {
+ $this->_plugins['postfilter'][$this->_get_filter_name($function)]
+ = array($function, null, null, false);
+ }
+
+ /**
+ * Unregisters a postfilter function
+ *
+ * @param callback $function
+ */
+ function unregister_postfilter($function)
+ {
+ unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
+ }
+
+ /**
+ * Registers an output filter function to apply
+ * to a template output
+ *
+ * @param callback $function
+ */
+ function register_outputfilter($function)
+ {
+ $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
+ = array($function, null, null, false);
+ }
+
+ /**
+ * Unregisters an outputfilter function
+ *
+ * @param callback $function
+ */
+ function unregister_outputfilter($function)
+ {
+ unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
+ }
+
+ /**
+ * load a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ */
+ function load_filter($type, $name)
+ {
+ switch ($type) {
+ case 'output':
+ $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
+ require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ break;
+
+ case 'pre':
+ case 'post':
+ if (!isset($this->_plugins[$type . 'filter'][$name]))
+ $this->_plugins[$type . 'filter'][$name] = false;
+ break;
+ }
+ }
+
+ /**
+ * clear cached content for the given template and cache id
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id name of cache_id
+ * @param string $compile_id name of compile_id
+ * @param string $exp_time expiration time
+ * @return boolean
+ */
+ function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+ {
+
+ if (!isset($compile_id))
+ $compile_id = $this->compile_id;
+
+ if (!isset($tpl_file))
+ $compile_id = null;
+
+ $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
+
+ if (!empty($this->cache_handler_func)) {
+ return call_user_func_array($this->cache_handler_func,
+ array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
+ } else {
+ $_params = array('auto_base' => $this->cache_dir,
+ 'auto_source' => $tpl_file,
+ 'auto_id' => $_auto_id,
+ 'exp_time' => $exp_time);
+ require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+ return smarty_core_rm_auto($_params, $this);
+ }
+
+ }
+
+
+ /**
+ * clear the entire contents of cache (all templates)
+ *
+ * @param string $exp_time expire time
+ * @return boolean results of {@link smarty_core_rm_auto()}
+ */
+ function clear_all_cache($exp_time = null)
+ {
+ return $this->clear_cache(null, null, null, $exp_time);
+ }
+
+
+ /**
+ * test to see if valid cache exists for this template
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @return string|false results of {@link _read_cache_file()}
+ */
+ function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+ {
+ if (!$this->caching)
+ return false;
+
+ if (!isset($compile_id))
+ $compile_id = $this->compile_id;
+
+ $_params = array(
+ 'tpl_file' => $tpl_file,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id
+ );
+ require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+ return smarty_core_read_cache_file($_params, $this);
+ }
+
+
+ /**
+ * clear all the assigned template variables.
+ *
+ */
+ function clear_all_assign()
+ {
+ $this->_tpl_vars = array();
+ }
+
+ /**
+ * clears compiled version of specified template resource,
+ * or all compiled template files if one is not specified.
+ * This function is for advanced use only, not normally needed.
+ *
+ * @param string $tpl_file
+ * @param string $compile_id
+ * @param string $exp_time
+ * @return boolean results of {@link smarty_core_rm_auto()}
+ */
+ function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+ {
+ if (!isset($compile_id)) {
+ $compile_id = $this->compile_id;
+ }
+ $_params = array('auto_base' => $this->compile_dir,
+ 'auto_source' => $tpl_file,
+ 'auto_id' => $compile_id,
+ 'exp_time' => $exp_time,
+ 'extensions' => array('.inc', '.php'));
+ require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+ return smarty_core_rm_auto($_params, $this);
+ }
+
+ /**
+ * Checks whether requested template exists.
+ *
+ * @param string $tpl_file
+ * @return boolean
+ */
+ function template_exists($tpl_file)
+ {
+ $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
+ return $this->_fetch_resource_info($_params);
+ }
+
+ /**
+ * Returns an array containing template variables
+ *
+ * @param string $name
+ * @param string $type
+ * @return array
+ */
+ function &get_template_vars($name=null)
+ {
+ if(!isset($name)) {
+ return $this->_tpl_vars;
+ } elseif(isset($this->_tpl_vars[$name])) {
+ return $this->_tpl_vars[$name];
+ } else {
+ // var non-existant, return valid reference
+ $_tmp = null;
+ return $_tmp;
+ }
+ }
+
+ /**
+ * Returns an array containing config variables
+ *
+ * @param string $name
+ * @param string $type
+ * @return array
+ */
+ function &get_config_vars($name=null)
+ {
+ if(!isset($name) && is_array($this->_config[0])) {
+ return $this->_config[0]['vars'];
+ } else if(isset($this->_config[0]['vars'][$name])) {
+ return $this->_config[0]['vars'][$name];
+ } else {
+ // var non-existant, return valid reference
+ $_tmp = null;
+ return $_tmp;
+ }
+ }
+
+ /**
+ * trigger Smarty error
+ *
+ * @param string $error_msg
+ * @param integer $error_type
+ */
+ function trigger_error($error_msg, $error_type = E_USER_WARNING)
+ {
+ trigger_error("Smarty error: $error_msg", $error_type);
+ }
+
+
+ /**
+ * executes & displays the template results
+ *
+ * @param string $resource_name
+ * @param string $cache_id
+ * @param string $compile_id
+ */
+ function display($resource_name, $cache_id = null, $compile_id = null)
+ {
+ $this->fetch($resource_name, $cache_id, $compile_id, true);
+ }
+
+ /**
+ * executes & returns or displays the template results
+ *
+ * @param string $resource_name
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param boolean $display
+ */
+ function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
+ {
+ static $_cache_info = array();
+
+ $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
+ ? $this->error_reporting : error_reporting() & ~E_NOTICE);
+
+ if (!$this->debugging && $this->debugging_ctrl == 'URL') {
+ $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
+ if (@strstr($_query_string, $this->_smarty_debug_id)) {
+ if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
+ // enable debugging for this browser session
+ @setcookie('SMARTY_DEBUG', true);
+ $this->debugging = true;
+ } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
+ // disable debugging for this browser session
+ @setcookie('SMARTY_DEBUG', false);
+ $this->debugging = false;
+ } else {
+ // enable debugging for this page
+ $this->debugging = true;
+ }
+ } else {
+ $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
+ }
+ }
+
+ if ($this->debugging) {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $_debug_start_time = smarty_core_get_microtime($_params, $this);
+ $this->_smarty_debug_info[] = array('type' => 'template',
+ 'filename' => $resource_name,
+ 'depth' => 0);
+ $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
+ }
+
+ if (!isset($compile_id)) {
+ $compile_id = $this->compile_id;
+ }
+
+ $this->_compile_id = $compile_id;
+ $this->_inclusion_depth = 0;
+
+ if ($this->caching) {
+ // save old cache_info, initialize cache_info
+ array_push($_cache_info, $this->_cache_info);
+ $this->_cache_info = array();
+ $_params = array(
+ 'tpl_file' => $resource_name,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id,
+ 'results' => null
+ );
+ require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+ if (smarty_core_read_cache_file($_params, $this)) {
+ $_smarty_results = $_params['results'];
+ if (!empty($this->_cache_info['insert_tags'])) {
+ $_params = array('plugins' => $this->_cache_info['insert_tags']);
+ require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ $_params = array('results' => $_smarty_results);
+ require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+ $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+ }
+ if (!empty($this->_cache_info['cache_serials'])) {
+ $_params = array('results' => $_smarty_results);
+ require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
+ $_smarty_results = smarty_core_process_compiled_include($_params, $this);
+ }
+
+
+ if ($display) {
+ if ($this->debugging)
+ {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
+ require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+ $_smarty_results .= smarty_core_display_debug_console($_params, $this);
+ }
+ if ($this->cache_modified_check) {
+ $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+ $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+ $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
+ if (@count($this->_cache_info['insert_tags']) == 0
+ && !$this->_cache_serials
+ && $_gmt_mtime == $_last_modified_date) {
+ if (php_sapi_name()=='cgi')
+ header('Status: 304 Not Modified');
+ else
+ header('HTTP/1.1 304 Not Modified');
+
+ } else {
+ header('Last-Modified: '.$_gmt_mtime);
+ echo $_smarty_results;
+ }
+ } else {
+ echo $_smarty_results;
+ }
+ error_reporting($_smarty_old_error_level);
+ // restore initial cache_info
+ $this->_cache_info = array_pop($_cache_info);
+ return true;
+ } else {
+ error_reporting($_smarty_old_error_level);
+ // restore initial cache_info
+ $this->_cache_info = array_pop($_cache_info);
+ return $_smarty_results;
+ }
+ } else {
+ $this->_cache_info['template'][$resource_name] = true;
+ if ($this->cache_modified_check && $display) {
+ header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
+ }
+ }
+ }
+
+ // load filters that are marked as autoload
+ if (count($this->autoload_filters)) {
+ foreach ($this->autoload_filters as $_filter_type => $_filters) {
+ foreach ($_filters as $_filter) {
+ $this->load_filter($_filter_type, $_filter);
+ }
+ }
+ }
+
+ $_smarty_compile_path = $this->_get_compile_path($resource_name);
+
+ // if we just need to display the results, don't perform output
+ // buffering - for speed
+ $_cache_including = $this->_cache_including;
+ $this->_cache_including = false;
+ if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
+ if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+ || $this->_compile_resource($resource_name, $_smarty_compile_path))
+ {
+ include($_smarty_compile_path);
+ }
+ } else {
+ ob_start();
+ if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+ || $this->_compile_resource($resource_name, $_smarty_compile_path))
+ {
+ include($_smarty_compile_path);
+ }
+ $_smarty_results = ob_get_contents();
+ ob_end_clean();
+
+ foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
+ $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
+ }
+ }
+
+ if ($this->caching) {
+ $_params = array('tpl_file' => $resource_name,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id,
+ 'results' => $_smarty_results);
+ require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
+ smarty_core_write_cache_file($_params, $this);
+ require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+ $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+
+ if ($this->_cache_serials) {
+ // strip nocache-tags from output
+ $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
+ ,''
+ ,$_smarty_results);
+ }
+ // restore initial cache_info
+ $this->_cache_info = array_pop($_cache_info);
+ }
+ $this->_cache_including = $_cache_including;
+
+ if ($display) {
+ if (isset($_smarty_results)) { echo $_smarty_results; }
+ if ($this->debugging) {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
+ require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+ echo smarty_core_display_debug_console($_params, $this);
+ }
+ error_reporting($_smarty_old_error_level);
+ return;
+ } else {
+ error_reporting($_smarty_old_error_level);
+ if (isset($_smarty_results)) { return $_smarty_results; }
+ }
+ }
+
+ /**
+ * load configuration values
+ *
+ * @param string $file
+ * @param string $section
+ * @param string $scope
+ */
+ function config_load($file, $section = null, $scope = 'global')
+ {
+ require_once($this->_get_plugin_filepath('function', 'config_load'));
+ smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
+ }
+
+ /**
+ * return a reference to a registered object
+ *
+ * @param string $name
+ * @return object
+ */
+ function &get_registered_object($name) {
+ if (!isset($this->_reg_objects[$name]))
+ $this->_trigger_fatal_error("'$name' is not a registered object");
+
+ if (!is_object($this->_reg_objects[$name][0]))
+ $this->_trigger_fatal_error("registered '$name' is not an object");
+
+ return $this->_reg_objects[$name][0];
+ }
+
+ /**
+ * clear configuration values
+ *
+ * @param string $var
+ */
+ function clear_config($var = null)
+ {
+ if(!isset($var)) {
+ // clear all values
+ $this->_config = array(array('vars' => array(),
+ 'files' => array()));
+ } else {
+ unset($this->_config[0]['vars'][$var]);
+ }
+ }
+
+ /**
+ * get filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+ function _get_plugin_filepath($type, $name)
+ {
+ $_params = array('type' => $type, 'name' => $name);
+ require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
+ return smarty_core_assemble_plugin_filepath($_params, $this);
+ }
+
+ /**
+ * test if resource needs compiling
+ *
+ * @param string $resource_name
+ * @param string $compile_path
+ * @return boolean
+ */
+ function _is_compiled($resource_name, $compile_path)
+ {
+ if (!$this->force_compile && file_exists($compile_path)) {
+ if (!$this->compile_check) {
+ // no need to check compiled file
+ return true;
+ } else {
+ // get file source and timestamp
+ $_params = array('resource_name' => $resource_name, 'get_source'=>false);
+ if (!$this->_fetch_resource_info($_params)) {
+ return false;
+ }
+ if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
+ // template not expired, no recompile
+ return true;
+ } else {
+ // compile template
+ return false;
+ }
+ }
+ } else {
+ // compiled template does not exist, or forced compile
+ return false;
+ }
+ }
+
+ /**
+ * compile the template
+ *
+ * @param string $resource_name
+ * @param string $compile_path
+ * @return boolean
+ */
+ function _compile_resource($resource_name, $compile_path)
+ {
+
+ $_params = array('resource_name' => $resource_name);
+ if (!$this->_fetch_resource_info($_params)) {
+ return false;
+ }
+
+ $_source_content = $_params['source_content'];
+ $_cache_include = substr($compile_path, 0, -4).'.inc';
+
+ if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
+ // if a _cache_serial was set, we also have to write an include-file:
+ if ($this->_cache_include_info) {
+ require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
+ smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this);
+ }
+
+ $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
+ require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+ smarty_core_write_compiled_resource($_params, $this);
+
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * compile the given source
+ *
+ * @param string $resource_name
+ * @param string $source_content
+ * @param string $compiled_content
+ * @return boolean
+ */
+ function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
+ {
+ if (file_exists(SMARTY_DIR . $this->compiler_file)) {
+ require_once(SMARTY_DIR . $this->compiler_file);
+ } else {
+ // use include_path
+ require_once($this->compiler_file);
+ }
+
+
+ $smarty_compiler = new $this->compiler_class;
+
+ $smarty_compiler->template_dir = $this->template_dir;
+ $smarty_compiler->compile_dir = $this->compile_dir;
+ $smarty_compiler->plugins_dir = $this->plugins_dir;
+ $smarty_compiler->config_dir = $this->config_dir;
+ $smarty_compiler->force_compile = $this->force_compile;
+ $smarty_compiler->caching = $this->caching;
+ $smarty_compiler->php_handling = $this->php_handling;
+ $smarty_compiler->left_delimiter = $this->left_delimiter;
+ $smarty_compiler->right_delimiter = $this->right_delimiter;
+ $smarty_compiler->_version = $this->_version;
+ $smarty_compiler->security = $this->security;
+ $smarty_compiler->secure_dir = $this->secure_dir;
+ $smarty_compiler->security_settings = $this->security_settings;
+ $smarty_compiler->trusted_dir = $this->trusted_dir;
+ $smarty_compiler->use_sub_dirs = $this->use_sub_dirs;
+ $smarty_compiler->_reg_objects = &$this->_reg_objects;
+ $smarty_compiler->_plugins = &$this->_plugins;
+ $smarty_compiler->_tpl_vars = &$this->_tpl_vars;
+ $smarty_compiler->default_modifiers = $this->default_modifiers;
+ $smarty_compiler->compile_id = $this->_compile_id;
+ $smarty_compiler->_config = $this->_config;
+ $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals;
+
+ if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
+ $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
+ }
+ $smarty_compiler->_cache_include = $cache_include_path;
+
+
+ $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
+
+ if ($smarty_compiler->_cache_serial) {
+ $this->_cache_include_info = array(
+ 'cache_serial'=>$smarty_compiler->_cache_serial
+ ,'plugins_code'=>$smarty_compiler->_plugins_code
+ ,'include_file_path' => $cache_include_path);
+
+ } else {
+ $this->_cache_include_info = null;
+
+ }
+
+ return $_results;
+ }
+
+ /**
+ * Get the compile path for this resource
+ *
+ * @param string $resource_name
+ * @return string results of {@link _get_auto_filename()}
+ */
+ function _get_compile_path($resource_name)
+ {
+ return $this->_get_auto_filename($this->compile_dir, $resource_name,
+ $this->_compile_id) . '.php';
+ }
+
+ /**
+ * fetch the template info. Gets timestamp, and source
+ * if get_source is true
+ *
+ * sets $source_content to the source of the template, and
+ * $resource_timestamp to its time stamp
+ * @param string $resource_name
+ * @param string $source_content
+ * @param integer $resource_timestamp
+ * @param boolean $get_source
+ * @param boolean $quiet
+ * @return boolean
+ */
+
+ function _fetch_resource_info(&$params)
+ {
+ if(!isset($params['get_source'])) { $params['get_source'] = true; }
+ if(!isset($params['quiet'])) { $params['quiet'] = false; }
+
+ $_return = false;
+ $_params = array('resource_name' => $params['resource_name']) ;
+ if (isset($params['resource_base_path']))
+ $_params['resource_base_path'] = $params['resource_base_path'];
+ else
+ $_params['resource_base_path'] = $this->template_dir;
+
+ if ($this->_parse_resource_name($_params)) {
+ $_resource_type = $_params['resource_type'];
+ $_resource_name = $_params['resource_name'];
+ switch ($_resource_type) {
+ case 'file':
+ if ($params['get_source']) {
+ $params['source_content'] = $this->_read_file($_resource_name);
+ }
+ $params['resource_timestamp'] = filemtime($_resource_name);
+ $_return = is_file($_resource_name) && is_readable($_resource_name);
+ break;
+
+ default:
+ // call resource functions to fetch the template source and timestamp
+ if ($params['get_source']) {
+ $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
+ call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
+ array($_resource_name, &$params['source_content'], &$this));
+ } else {
+ $_source_return = true;
+ }
+
+ $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
+ call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
+ array($_resource_name, &$params['resource_timestamp'], &$this));
+
+ $_return = $_source_return && $_timestamp_return;
+ break;
+ }
+ }
+
+ if (!$_return) {
+ // see if we can get a template with the default template handler
+ if (!empty($this->default_template_handler_func)) {
+ if (!is_callable($this->default_template_handler_func)) {
+ $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
+ } else {
+ $_return = call_user_func_array(
+ $this->default_template_handler_func,
+ array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
+ }
+ }
+ }
+
+ if (!$_return) {
+ if (!$params['quiet']) {
+ $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
+ }
+ } else if ($_return && $this->security) {
+ require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+ if (!smarty_core_is_secure($_params, $this)) {
+ if (!$params['quiet'])
+ $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
+ $params['source_content'] = null;
+ $params['resource_timestamp'] = null;
+ return false;
+ }
+ }
+ return $_return;
+ }
+
+
+ /**
+ * parse out the type and name from the resource
+ *
+ * @param string $resource_base_path
+ * @param string $resource_name
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ function _parse_resource_name(&$params)
+ {
+
+ // split tpl_path by the first colon
+ $_resource_name_parts = explode(':', $params['resource_name'], 2);
+
+ if (count($_resource_name_parts) == 1) {
+ // no resource type given
+ $params['resource_type'] = $this->default_resource_type;
+ $params['resource_name'] = $_resource_name_parts[0];
+ } else {
+ if(strlen($_resource_name_parts[0]) == 1) {
+ // 1 char is not resource type, but part of filepath
+ $params['resource_type'] = $this->default_resource_type;
+ $params['resource_name'] = $params['resource_name'];
+ } else {
+ $params['resource_type'] = $_resource_name_parts[0];
+ $params['resource_name'] = $_resource_name_parts[1];
+ }
+ }
+
+ if ($params['resource_type'] == 'file') {
+ if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
+ // relative pathname to $params['resource_base_path']
+ // use the first directory where the file is found
+ foreach ((array)$params['resource_base_path'] as $_curr_path) {
+ $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
+ if (file_exists($_fullpath) && is_file($_fullpath)) {
+ $params['resource_name'] = $_fullpath;
+ return true;
+ }
+ // didn't find the file, try include_path
+ $_params = array('file_path' => $_fullpath);
+ require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+ if(smarty_core_get_include_path($_params, $this)) {
+ $params['resource_name'] = $_params['new_file_path'];
+ return true;
+ }
+ }
+ return false;
+ } else {
+ /* absolute path */
+ return file_exists($params['resource_name']);
+ }
+ } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
+ $_params = array('type' => $params['resource_type']);
+ require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
+ smarty_core_load_resource_plugin($_params, $this);
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Handle modifiers
+ *
+ * @param string|null $modifier_name
+ * @param array|null $map_array
+ * @return string result of modifiers
+ */
+ function _run_mod_handler()
+ {
+ $_args = func_get_args();
+ list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
+ list($_func_name, $_tpl_file, $_tpl_line) =
+ $this->_plugins['modifier'][$_modifier_name];
+
+ $_var = $_args[0];
+ foreach ($_var as $_key => $_val) {
+ $_args[0] = $_val;
+ $_var[$_key] = call_user_func_array($_func_name, $_args);
+ }
+ return $_var;
+ }
+
+ /**
+ * Remove starting and ending quotes from the string
+ *
+ * @param string $string
+ * @return string
+ */
+ function _dequote($string)
+ {
+ if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
+ substr($string, -1) == substr($string, 0, 1))
+ return substr($string, 1, -1);
+ else
+ return $string;
+ }
+
+
+ /**
+ * read in a file
+ *
+ * @param string $filename
+ * @return string
+ */
+ function _read_file($filename)
+ {
+ if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) {
+ $contents = '';
+ while (!feof($fd)) {
+ $contents .= fread($fd, 8192);
+ }
+ fclose($fd);
+ return $contents;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * get a concrete filename for automagically created content
+ *
+ * @param string $auto_base
+ * @param string $auto_source
+ * @param string $auto_id
+ * @return string
+ * @staticvar string|null
+ * @staticvar string|null
+ */
+ function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
+ {
+ $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
+ $_return = $auto_base . DIRECTORY_SEPARATOR;
+
+ if(isset($auto_id)) {
+ // make auto_id safe for directory names
+ $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
+ // split into separate directories
+ $_return .= $auto_id . $_compile_dir_sep;
+ }
+
+ if(isset($auto_source)) {
+ // make source name safe for filename
+ $_filename = urlencode(basename($auto_source));
+ $_crc32 = sprintf('%08X', crc32($auto_source));
+ // prepend %% to avoid name conflicts with
+ // with $params['auto_id'] names
+ $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
+ substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
+ $_return .= '%%' . $_crc32 . '%%' . $_filename;
+ }
+
+ return $_return;
+ }
+
+ /**
+ * unlink a file, possibly using expiration time
+ *
+ * @param string $resource
+ * @param integer $exp_time
+ */
+ function _unlink($resource, $exp_time = null)
+ {
+ if(isset($exp_time)) {
+ if(time() - @filemtime($resource) >= $exp_time) {
+ return @unlink($resource);
+ }
+ } else {
+ return @unlink($resource);
+ }
+ }
+
+ /**
+ * returns an auto_id for auto-file-functions
+ *
+ * @param string $cache_id
+ * @param string $compile_id
+ * @return string|null
+ */
+ function _get_auto_id($cache_id=null, $compile_id=null) {
+ if (isset($cache_id))
+ return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id;
+ elseif(isset($compile_id))
+ return $compile_id;
+ else
+ return null;
+ }
+
+ /**
+ * trigger Smarty plugin error
+ *
+ * @param string $error_msg
+ * @param string $tpl_file
+ * @param integer $tpl_line
+ * @param string $file
+ * @param integer $line
+ * @param integer $error_type
+ */
+ function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
+ $file = null, $line = null, $error_type = E_USER_ERROR)
+ {
+ if(isset($file) && isset($line)) {
+ $info = ' ('.basename($file).", line $line)";
+ } else {
+ $info = '';
+ }
+ if (isset($tpl_line) && isset($tpl_file)) {
+ $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
+ } else {
+ $this->trigger_error($error_msg . $info, $error_type);
+ }
+ }
+
+
+ /**
+ * callback function for preg_replace, to call a non-cacheable block
+ * @return string
+ */
+ function _process_compiled_include_callback($match) {
+ $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
+ ob_start();
+ $_func($this);
+ $_ret = ob_get_contents();
+ ob_end_clean();
+ return $_ret;
+ }
+
+
+ /**
+ * called for included templates
+ *
+ * @param string $_smarty_include_tpl_file
+ * @param string $_smarty_include_vars
+ */
+
+ // $_smarty_include_tpl_file, $_smarty_include_vars
+
+ function _smarty_include($params)
+ {
+ if ($this->debugging) {
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $debug_start_time = smarty_core_get_microtime($_params, $this);
+ $this->_smarty_debug_info[] = array('type' => 'template',
+ 'filename' => $params['smarty_include_tpl_file'],
+ 'depth' => ++$this->_inclusion_depth);
+ $included_tpls_idx = count($this->_smarty_debug_info) - 1;
+ }
+
+ $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
+
+ // config vars are treated as local, so push a copy of the
+ // current ones onto the front of the stack
+ array_unshift($this->_config, $this->_config[0]);
+
+ $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
+
+
+ if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
+ || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
+ {
+ include($_smarty_compile_path);
+ }
+
+ // pop the local vars off the front of the stack
+ array_shift($this->_config);
+
+ $this->_inclusion_depth--;
+
+ if ($this->debugging) {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
+ }
+
+ if ($this->caching) {
+ $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
+ }
+ }
+
+
+ /**
+ * get or set an array of cached attributes for function that is
+ * not cacheable
+ * @return array
+ */
+ function &_smarty_cache_attrs($cache_serial, $count) {
+ $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
+
+ if ($this->_cache_including) {
+ /* return next set of cache_attrs */
+ $_return = current($_cache_attrs);
+ next($_cache_attrs);
+ return $_return;
+
+ } else {
+ /* add a reference to a new set of cache_attrs */
+ $_cache_attrs[] = array();
+ return $_cache_attrs[count($_cache_attrs)-1];
+
+ }
+
+ }
+
+
+ /**
+ * wrapper for include() retaining $this
+ * @return mixed
+ */
+ function _include($filename, $once=false, $params=null)
+ {
+ if ($once) {
+ return include_once($filename);
+ } else {
+ return include($filename);
+ }
+ }
+
+
+ /**
+ * wrapper for eval() retaining $this
+ * @return mixed
+ */
+ function _eval($code, $params=null)
+ {
+ return eval($code);
+ }
+
+ /**
+ * Extracts the filter name from the given callback
+ *
+ * @param callback $function
+ * @return string
+ */
+ function _get_filter_name($function)
+ {
+ if (is_array($function)) {
+ $_class_name = (is_object($function[0]) ?
+ get_class($function[0]) : $function[0]);
+ return $_class_name . '_' . $function[1];
+ }
+ else {
+ return $function;
+ }
+ }
+
+ /**#@-*/
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: Smarty_Compiler.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * @link http://smarty.php.net/
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @version 2.6.26
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @package Smarty
+ */
+
+/* $Id: Smarty_Compiler.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
+
+/**
+ * Template compiling class
+ * @package Smarty
+ */
+class Smarty_Compiler extends Smarty {
+
+ // internal vars
+ /**#@+
+ * @access private
+ */
+ var $_folded_blocks = array(); // keeps folded template blocks
+ var $_current_file = null; // the current template being compiled
+ var $_current_line_no = 1; // line number for error messages
+ var $_capture_stack = array(); // keeps track of nested capture buffers
+ var $_plugin_info = array(); // keeps track of plugins to load
+ var $_init_smarty_vars = false;
+ var $_permitted_tokens = array('true','false','yes','no','on','off','null');
+ var $_db_qstr_regexp = null; // regexps are setup in the constructor
+ var $_si_qstr_regexp = null;
+ var $_qstr_regexp = null;
+ var $_func_regexp = null;
+ var $_reg_obj_regexp = null;
+ var $_var_bracket_regexp = null;
+ var $_num_const_regexp = null;
+ var $_dvar_guts_regexp = null;
+ var $_dvar_regexp = null;
+ var $_cvar_regexp = null;
+ var $_svar_regexp = null;
+ var $_avar_regexp = null;
+ var $_mod_regexp = null;
+ var $_var_regexp = null;
+ var $_parenth_param_regexp = null;
+ var $_func_call_regexp = null;
+ var $_obj_ext_regexp = null;
+ var $_obj_start_regexp = null;
+ var $_obj_params_regexp = null;
+ var $_obj_call_regexp = null;
+ var $_cacheable_state = 0;
+ var $_cache_attrs_count = 0;
+ var $_nocache_count = 0;
+ var $_cache_serial = null;
+ var $_cache_include = null;
+
+ var $_strip_depth = 0;
+ var $_additional_newline = "\n";
+
+ /**#@-*/
+ /**
+ * The class constructor.
+ */
+ function Smarty_Compiler()
+ {
+ // matches double quoted strings:
+ // "foobar"
+ // "foo\"bar"
+ $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
+
+ // matches single quoted strings:
+ // 'foobar'
+ // 'foo\'bar'
+ $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
+
+ // matches single or double quoted strings
+ $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
+
+ // matches bracket portion of vars
+ // [0]
+ // [foo]
+ // [$bar]
+ $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
+
+ // matches numerical constants
+ // 30
+ // -12
+ // 13.22
+ $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
+
+ // matches $ vars (not objects):
+ // $foo
+ // $foo.bar
+ // $foo.bar.foobar
+ // $foo[0]
+ // $foo[$bar]
+ // $foo[5][blah]
+ // $foo[5].bar[$foobar][4]
+ $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
+ $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
+ $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
+ . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
+ $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
+
+ // matches config vars:
+ // #foo#
+ // #foobar123_foo#
+ $this->_cvar_regexp = '\#\w+\#';
+
+ // matches section vars:
+ // %foo.bar%
+ $this->_svar_regexp = '\%\w+\.\w+\%';
+
+ // matches all valid variables (no quotes, no modifiers)
+ $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
+ . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
+
+ // matches valid variable syntax:
+ // $foo
+ // $foo
+ // #foo#
+ // #foo#
+ // "text"
+ // "text"
+ $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
+
+ // matches valid object call (one level of object nesting allowed in parameters):
+ // $foo->bar
+ // $foo->bar()
+ // $foo->bar("text")
+ // $foo->bar($foo, $bar, "text")
+ // $foo->bar($foo, "foo")
+ // $foo->bar->foo()
+ // $foo->bar->foo->bar()
+ // $foo->bar($foo->bar)
+ // $foo->bar($foo->bar())
+ // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
+ $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
+ $this->_obj_restricted_param_regexp = '(?:'
+ . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
+ . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
+ $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+ . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
+ $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
+ . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
+ $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
+ $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
+
+ // matches valid modifier syntax:
+ // |foo
+ // |@foo
+ // |foo:"bar"
+ // |foo:$bar
+ // |foo:"bar":$foobar
+ // |foo|bar
+ // |foo:$foo->bar
+ $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
+ . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
+
+ // matches valid function name:
+ // foo123
+ // _foo_bar
+ $this->_func_regexp = '[a-zA-Z_]\w*';
+
+ // matches valid registered object:
+ // foo->bar
+ $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
+
+ // matches valid parameter values:
+ // true
+ // $foo
+ // $foo|bar
+ // #foo#
+ // #foo#|bar
+ // "text"
+ // "text"|bar
+ // $foo->bar
+ $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
+ . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
+
+ // matches valid parenthesised function parameters:
+ //
+ // "text"
+ // $foo, $bar, "text"
+ // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
+ $this->_parenth_param_regexp = '(?:\((?:\w+|'
+ . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+ . $this->_param_regexp . ')))*)?\))';
+
+ // matches valid function call:
+ // foo()
+ // foo_bar($foo)
+ // _foo_bar($foo,"bar")
+ // foo123($foo,$foo->bar(),"foo")
+ $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
+ . $this->_parenth_param_regexp . '))';
+ }
+
+ /**
+ * compile a resource
+ *
+ * sets $compiled_content to the compiled source
+ * @param string $resource_name
+ * @param string $source_content
+ * @param string $compiled_content
+ * @return true
+ */
+ function _compile_file($resource_name, $source_content, &$compiled_content)
+ {
+
+ if ($this->security) {
+ // do not allow php syntax to be executed unless specified
+ if ($this->php_handling == SMARTY_PHP_ALLOW &&
+ !$this->security_settings['PHP_HANDLING']) {
+ $this->php_handling = SMARTY_PHP_PASSTHRU;
+ }
+ }
+
+ $this->_load_filters();
+
+ $this->_current_file = $resource_name;
+ $this->_current_line_no = 1;
+ $ldq = preg_quote($this->left_delimiter, '~');
+ $rdq = preg_quote($this->right_delimiter, '~');
+
+ // run template source through prefilter functions
+ if (count($this->_plugins['prefilter']) > 0) {
+ foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+ if ($prefilter === false) continue;
+ if ($prefilter[3] || is_callable($prefilter[0])) {
+ $source_content = call_user_func_array($prefilter[0],
+ array($source_content, &$this));
+ $this->_plugins['prefilter'][$filter_name][3] = true;
+ } else {
+ $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
+ }
+ }
+ }
+
+ /* fetch all special blocks */
+ $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
+
+ preg_match_all($search, $source_content, $match, PREG_SET_ORDER);
+ $this->_folded_blocks = $match;
+ reset($this->_folded_blocks);
+
+ /* replace special blocks by "{php}" */
+ $source_content = preg_replace($search.'e', "'"
+ . $this->_quote_replace($this->left_delimiter) . 'php'
+ . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
+ . $this->_quote_replace($this->right_delimiter)
+ . "'"
+ , $source_content);
+
+ /* Gather all template tags. */
+ preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
+ $template_tags = $_match[1];
+ /* Split content by template tags to obtain non-template content. */
+ $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
+
+ /* loop through text blocks */
+ for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
+ /* match anything resembling php tags */
+ if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
+ /* replace tags with placeholders to prevent recursive replacements */
+ $sp_match[1] = array_unique($sp_match[1]);
+ usort($sp_match[1], '_smarty_sort_length');
+ for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+ $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
+ }
+ /* process each one */
+ for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+ if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
+ /* echo php contents */
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
+ } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
+ /* quote php tags */
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
+ } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
+ /* remove php tags */
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
+ } else {
+ /* SMARTY_PHP_ALLOW, but echo non php starting tags */
+ $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
+ }
+ }
+ }
+ }
+
+ /* Compile the template tags into PHP code. */
+ $compiled_tags = array();
+ for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
+ $this->_current_line_no += substr_count($text_blocks[$i], "\n");
+ $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
+ $this->_current_line_no += substr_count($template_tags[$i], "\n");
+ }
+ if (count($this->_tag_stack)>0) {
+ list($_open_tag, $_line_no) = end($this->_tag_stack);
+ $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
+ return;
+ }
+
+ /* Reformat $text_blocks between 'strip' and '/strip' tags,
+ removing spaces, tabs and newlines. */
+ $strip = false;
+ for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+ if ($compiled_tags[$i] == '{strip}') {
+ $compiled_tags[$i] = '';
+ $strip = true;
+ /* remove leading whitespaces */
+ $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
+ }
+ if ($strip) {
+ /* strip all $text_blocks before the next '/strip' */
+ for ($j = $i + 1; $j < $for_max; $j++) {
+ /* remove leading and trailing whitespaces of each line */
+ $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
+ if ($compiled_tags[$j] == '{/strip}') {
+ /* remove trailing whitespaces from the last text_block */
+ $text_blocks[$j] = rtrim($text_blocks[$j]);
+ }
+ $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
+ if ($compiled_tags[$j] == '{/strip}') {
+ $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
+ if a newline is following the closing strip-tag */
+ $strip = false;
+ $i = $j;
+ break;
+ }
+ }
+ }
+ }
+ $compiled_content = '';
+
+ $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
+
+ /* Interleave the compiled contents and text blocks to get the final result. */
+ for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+ if ($compiled_tags[$i] == '') {
+ // tag result empty, remove first newline from following text block
+ $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
+ }
+ // replace legit PHP tags with placeholder
+ $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
+ $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
+
+ $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
+ }
+ $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
+
+ // escape php tags created by interleaving
+ $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
+ $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
+
+ // recover legit tags
+ $compiled_content = str_replace($tag_guard, '<?', $compiled_content);
+
+ // remove \n from the end of the file, if any
+ if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
+ $compiled_content = substr($compiled_content, 0, -1);
+ }
+
+ if (!empty($this->_cache_serial)) {
+ $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
+ }
+
+ // run compiled template through postfilter functions
+ if (count($this->_plugins['postfilter']) > 0) {
+ foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+ if ($postfilter === false) continue;
+ if ($postfilter[3] || is_callable($postfilter[0])) {
+ $compiled_content = call_user_func_array($postfilter[0],
+ array($compiled_content, &$this));
+ $this->_plugins['postfilter'][$filter_name][3] = true;
+ } else {
+ $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
+ }
+ }
+ }
+
+ // put header at the top of the compiled template
+ $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+ $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
+
+ /* Emit code to load needed plugins. */
+ $this->_plugins_code = '';
+ if (count($this->_plugin_info)) {
+ $_plugins_params = "array('plugins' => array(";
+ foreach ($this->_plugin_info as $plugin_type => $plugins) {
+ foreach ($plugins as $plugin_name => $plugin_info) {
+ $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
+ $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
+ }
+ }
+ $_plugins_params .= '))';
+ $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
+ $template_header .= $plugins_code;
+ $this->_plugin_info = array();
+ $this->_plugins_code = $plugins_code;
+ }
+
+ if ($this->_init_smarty_vars) {
+ $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
+ $this->_init_smarty_vars = false;
+ }
+
+ $compiled_content = $template_header . $compiled_content;
+ return true;
+ }
+
+ /**
+ * Compile a template tag
+ *
+ * @param string $template_tag
+ * @return string
+ */
+ function _compile_tag($template_tag)
+ {
+ /* Matched comment. */
+ if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
+ return '';
+
+ /* Split tag into two three parts: command, command modifiers and the arguments. */
+ if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
+ . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
+ (?:\s+(.*))?$
+ ~xs', $template_tag, $match)) {
+ $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $tag_command = $match[1];
+ $tag_modifier = isset($match[2]) ? $match[2] : null;
+ $tag_args = isset($match[3]) ? $match[3] : null;
+
+ if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
+ /* tag name is a variable or object */
+ $_return = $this->_parse_var_props($tag_command . $tag_modifier);
+ return "<?php echo $_return; ?>" . $this->_additional_newline;
+ }
+
+ /* If the tag name is a registered object, we process it. */
+ if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
+ return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
+ }
+
+ switch ($tag_command) {
+ case 'include':
+ return $this->_compile_include_tag($tag_args);
+
+ case 'include_php':
+ return $this->_compile_include_php_tag($tag_args);
+
+ case 'if':
+ $this->_push_tag('if');
+ return $this->_compile_if_tag($tag_args);
+
+ case 'else':
+ list($_open_tag) = end($this->_tag_stack);
+ if ($_open_tag != 'if' && $_open_tag != 'elseif')
+ $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
+ else
+ $this->_push_tag('else');
+ return '<?php else: ?>';
+
+ case 'elseif':
+ list($_open_tag) = end($this->_tag_stack);
+ if ($_open_tag != 'if' && $_open_tag != 'elseif')
+ $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
+ if ($_open_tag == 'if')
+ $this->_push_tag('elseif');
+ return $this->_compile_if_tag($tag_args, true);
+
+ case '/if':
+ $this->_pop_tag('if');
+ return '<?php endif; ?>';
+
+ case 'capture':
+ return $this->_compile_capture_tag(true, $tag_args);
+
+ case '/capture':
+ return $this->_compile_capture_tag(false);
+
+ case 'ldelim':
+ return $this->left_delimiter;
+
+ case 'rdelim':
+ return $this->right_delimiter;
+
+ case 'section':
+ $this->_push_tag('section');
+ return $this->_compile_section_start($tag_args);
+
+ case 'sectionelse':
+ $this->_push_tag('sectionelse');
+ return "<?php endfor; else: ?>";
+ break;
+
+ case '/section':
+ $_open_tag = $this->_pop_tag('section');
+ if ($_open_tag == 'sectionelse')
+ return "<?php endif; ?>";
+ else
+ return "<?php endfor; endif; ?>";
+
+ case 'foreach':
+ $this->_push_tag('foreach');
+ return $this->_compile_foreach_start($tag_args);
+ break;
+
+ case 'foreachelse':
+ $this->_push_tag('foreachelse');
+ return "<?php endforeach; else: ?>";
+
+ case '/foreach':
+ $_open_tag = $this->_pop_tag('foreach');
+ if ($_open_tag == 'foreachelse')
+ return "<?php endif; unset(\$_from); ?>";
+ else
+ return "<?php endforeach; endif; unset(\$_from); ?>";
+ break;
+
+ case 'strip':
+ case '/strip':
+ if (substr($tag_command, 0, 1)=='/') {
+ $this->_pop_tag('strip');
+ if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
+ $this->_additional_newline = "\n";
+ return '{' . $tag_command . '}';
+ }
+ } else {
+ $this->_push_tag('strip');
+ if ($this->_strip_depth++==0) { /* outermost opening {strip} */
+ $this->_additional_newline = "";
+ return '{' . $tag_command . '}';
+ }
+ }
+ return '';
+
+ case 'php':
+ /* handle folded tags replaced by {php} */
+ list(, $block) = each($this->_folded_blocks);
+ $this->_current_line_no += substr_count($block[0], "\n");
+ /* the number of matched elements in the regexp in _compile_file()
+ determins the type of folded tag that was found */
+ switch (count($block)) {
+ case 2: /* comment */
+ return '';
+
+ case 3: /* literal */
+ return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
+
+ case 4: /* php */
+ if ($this->security && !$this->security_settings['PHP_TAGS']) {
+ $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ return '<?php ' . $block[3] .' ?>';
+ }
+ break;
+
+ case 'insert':
+ return $this->_compile_insert_tag($tag_args);
+
+ default:
+ if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
+ return $output;
+ } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+ return $output;
+ } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+ return $output;
+ } else {
+ $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ }
+ }
+
+
+ /**
+ * compile the custom compiler tag
+ *
+ * sets $output to the compiled custom compiler tag
+ * @param string $tag_command
+ * @param string $tag_args
+ * @param string $output
+ * @return boolean
+ */
+ function _compile_compiler_tag($tag_command, $tag_args, &$output)
+ {
+ $found = false;
+ $have_function = true;
+
+ /*
+ * First we check if the compiler function has already been registered
+ * or loaded from a plugin file.
+ */
+ if (isset($this->_plugins['compiler'][$tag_command])) {
+ $found = true;
+ $plugin_func = $this->_plugins['compiler'][$tag_command][0];
+ if (!is_callable($plugin_func)) {
+ $message = "compiler function '$tag_command' is not implemented";
+ $have_function = false;
+ }
+ }
+ /*
+ * Otherwise we need to load plugin file and look for the function
+ * inside it.
+ */
+ else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
+ $found = true;
+
+ include_once $plugin_file;
+
+ $plugin_func = 'smarty_compiler_' . $tag_command;
+ if (!is_callable($plugin_func)) {
+ $message = "plugin function $plugin_func() not found in $plugin_file\n";
+ $have_function = false;
+ } else {
+ $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
+ }
+ }
+
+ /*
+ * True return value means that we either found a plugin or a
+ * dynamically registered function. False means that we didn't and the
+ * compiler should now emit code to load custom function plugin for this
+ * tag.
+ */
+ if ($found) {
+ if ($have_function) {
+ $output = call_user_func_array($plugin_func, array($tag_args, &$this));
+ if($output != '') {
+ $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
+ . $output
+ . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
+ }
+ } else {
+ $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * compile block function tag
+ *
+ * sets $output to compiled block function tag
+ * @param string $tag_command
+ * @param string $tag_args
+ * @param string $tag_modifier
+ * @param string $output
+ * @return boolean
+ */
+ function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
+ {
+ if (substr($tag_command, 0, 1) == '/') {
+ $start_tag = false;
+ $tag_command = substr($tag_command, 1);
+ } else
+ $start_tag = true;
+
+ $found = false;
+ $have_function = true;
+
+ /*
+ * First we check if the block function has already been registered
+ * or loaded from a plugin file.
+ */
+ if (isset($this->_plugins['block'][$tag_command])) {
+ $found = true;
+ $plugin_func = $this->_plugins['block'][$tag_command][0];
+ if (!is_callable($plugin_func)) {
+ $message = "block function '$tag_command' is not implemented";
+ $have_function = false;
+ }
+ }
+ /*
+ * Otherwise we need to load plugin file and look for the function
+ * inside it.
+ */
+ else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
+ $found = true;
+
+ include_once $plugin_file;
+
+ $plugin_func = 'smarty_block_' . $tag_command;
+ if (!function_exists($plugin_func)) {
+ $message = "plugin function $plugin_func() not found in $plugin_file\n";
+ $have_function = false;
+ } else {
+ $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
+
+ }
+ }
+
+ if (!$found) {
+ return false;
+ } else if (!$have_function) {
+ $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+ return true;
+ }
+
+ /*
+ * Even though we've located the plugin function, compilation
+ * happens only once, so the plugin will still need to be loaded
+ * at runtime for future requests.
+ */
+ $this->_add_plugin('block', $tag_command);
+
+ if ($start_tag)
+ $this->_push_tag($tag_command);
+ else
+ $this->_pop_tag($tag_command);
+
+ if ($start_tag) {
+ $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
+ $attrs = $this->_parse_attrs($tag_args);
+ $_cache_attrs='';
+ $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
+ $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
+ $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
+ $output .= 'while ($_block_repeat) { ob_start(); ?>';
+ } else {
+ $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
+ $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
+ if ($tag_modifier != '') {
+ $this->_parse_modifiers($_out_tag_text, $tag_modifier);
+ }
+ $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
+ $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
+ }
+
+ return true;
+ }
+
+
+ /**
+ * compile custom function tag
+ *
+ * @param string $tag_command
+ * @param string $tag_args
+ * @param string $tag_modifier
+ * @return string
+ */
+ function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
+ {
+ $found = false;
+ $have_function = true;
+
+ /*
+ * First we check if the custom function has already been registered
+ * or loaded from a plugin file.
+ */
+ if (isset($this->_plugins['function'][$tag_command])) {
+ $found = true;
+ $plugin_func = $this->_plugins['function'][$tag_command][0];
+ if (!is_callable($plugin_func)) {
+ $message = "custom function '$tag_command' is not implemented";
+ $have_function = false;
+ }
+ }
+ /*
+ * Otherwise we need to load plugin file and look for the function
+ * inside it.
+ */
+ else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
+ $found = true;
+
+ include_once $plugin_file;
+
+ $plugin_func = 'smarty_function_' . $tag_command;
+ if (!function_exists($plugin_func)) {
+ $message = "plugin function $plugin_func() not found in $plugin_file\n";
+ $have_function = false;
+ } else {
+ $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
+
+ }
+ }
+
+ if (!$found) {
+ return false;
+ } else if (!$have_function) {
+ $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+ return true;
+ }
+
+ /* declare plugin to be loaded on display of the template that
+ we compile right now */
+ $this->_add_plugin('function', $tag_command);
+
+ $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
+ $attrs = $this->_parse_attrs($tag_args);
+ $_cache_attrs = '';
+ $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
+
+ $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
+ if($tag_modifier != '') {
+ $this->_parse_modifiers($output, $tag_modifier);
+ }
+
+ if($output != '') {
+ $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
+ . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
+ }
+
+ return true;
+ }
+
+ /**
+ * compile a registered object tag
+ *
+ * @param string $tag_command
+ * @param array $attrs
+ * @param string $tag_modifier
+ * @return string
+ */
+ function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
+ {
+ if (substr($tag_command, 0, 1) == '/') {
+ $start_tag = false;
+ $tag_command = substr($tag_command, 1);
+ } else {
+ $start_tag = true;
+ }
+
+ list($object, $obj_comp) = explode('->', $tag_command);
+
+ $arg_list = array();
+ if(count($attrs)) {
+ $_assign_var = false;
+ foreach ($attrs as $arg_name => $arg_value) {
+ if($arg_name == 'assign') {
+ $_assign_var = $arg_value;
+ unset($attrs['assign']);
+ continue;
+ }
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+ }
+
+ if($this->_reg_objects[$object][2]) {
+ // smarty object argument format
+ $args = "array(".implode(',', (array)$arg_list)."), \$this";
+ } else {
+ // traditional argument format
+ $args = implode(',', array_values($attrs));
+ if (empty($args)) {
+ $args = '';
+ }
+ }
+
+ $prefix = '';
+ $postfix = '';
+ $newline = '';
+ if(!is_object($this->_reg_objects[$object][0])) {
+ $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+ } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
+ $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+ } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
+ // method
+ if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
+ // block method
+ if ($start_tag) {
+ $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
+ $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
+ $prefix .= "while (\$_block_repeat) { ob_start();";
+ $return = null;
+ $postfix = '';
+ } else {
+ $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
+ $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
+ $postfix = "} array_pop(\$this->_tag_stack);";
+ }
+ } else {
+ // non-block method
+ $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
+ }
+ } else {
+ // property
+ $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
+ }
+
+ if($return != null) {
+ if($tag_modifier != '') {
+ $this->_parse_modifiers($return, $tag_modifier);
+ }
+
+ if(!empty($_assign_var)) {
+ $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);";
+ } else {
+ $output = 'echo ' . $return . ';';
+ $newline = $this->_additional_newline;
+ }
+ } else {
+ $output = '';
+ }
+
+ return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
+ }
+
+ /**
+ * Compile {insert ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_insert_tag($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $name = $this->_dequote($attrs['name']);
+
+ if (empty($name)) {
+ return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ if (!preg_match('~^\w+$~', $name)) {
+ return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ if (!empty($attrs['script'])) {
+ $delayed_loading = true;
+ } else {
+ $delayed_loading = false;
+ }
+
+ foreach ($attrs as $arg_name => $arg_value) {
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+
+ $this->_add_plugin('insert', $name, $delayed_loading);
+
+ $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
+
+ return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
+ }
+
+ /**
+ * Compile {include ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_include_tag($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = array();
+
+ if (empty($attrs['file'])) {
+ $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ foreach ($attrs as $arg_name => $arg_value) {
+ if ($arg_name == 'file') {
+ $include_file = $arg_value;
+ continue;
+ } else if ($arg_name == 'assign') {
+ $assign_var = $arg_value;
+ continue;
+ }
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+
+ $output = '<?php ';
+
+ if (isset($assign_var)) {
+ $output .= "ob_start();\n";
+ }
+
+ $output .=
+ "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
+
+
+ $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
+ $output .= "\$this->_smarty_include($_params);\n" .
+ "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
+ "unset(\$_smarty_tpl_vars);\n";
+
+ if (isset($assign_var)) {
+ $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
+ }
+
+ $output .= ' ?>';
+
+ return $output;
+
+ }
+
+ /**
+ * Compile {include ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_include_php_tag($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+
+ if (empty($attrs['file'])) {
+ $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
+ $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
+
+ $arg_list = array();
+ foreach($attrs as $arg_name => $arg_value) {
+ if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
+ if(is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+ }
+
+ $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
+
+ return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
+ }
+
+
+ /**
+ * Compile {section ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_section_start($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = array();
+
+ $output = '<?php ';
+ $section_name = $attrs['name'];
+ if (empty($section_name)) {
+ $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $output .= "unset(\$this->_sections[$section_name]);\n";
+ $section_props = "\$this->_sections[$section_name]";
+
+ foreach ($attrs as $attr_name => $attr_value) {
+ switch ($attr_name) {
+ case 'loop':
+ $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
+ break;
+
+ case 'show':
+ if (is_bool($attr_value))
+ $show_attr_value = $attr_value ? 'true' : 'false';
+ else
+ $show_attr_value = "(bool)$attr_value";
+ $output .= "{$section_props}['show'] = $show_attr_value;\n";
+ break;
+
+ case 'name':
+ $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+ break;
+
+ case 'max':
+ case 'start':
+ $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
+ break;
+
+ case 'step':
+ $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
+ break;
+
+ default:
+ $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+ }
+
+ if (!isset($attrs['show']))
+ $output .= "{$section_props}['show'] = true;\n";
+
+ if (!isset($attrs['loop']))
+ $output .= "{$section_props}['loop'] = 1;\n";
+
+ if (!isset($attrs['max']))
+ $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+ else
+ $output .= "if ({$section_props}['max'] < 0)\n" .
+ " {$section_props}['max'] = {$section_props}['loop'];\n";
+
+ if (!isset($attrs['step']))
+ $output .= "{$section_props}['step'] = 1;\n";
+
+ if (!isset($attrs['start']))
+ $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+ else {
+ $output .= "if ({$section_props}['start'] < 0)\n" .
+ " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
+ "else\n" .
+ " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+ }
+
+ $output .= "if ({$section_props}['show']) {\n";
+ if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
+ $output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
+ } else {
+ $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+ }
+ $output .= " if ({$section_props}['total'] == 0)\n" .
+ " {$section_props}['show'] = false;\n" .
+ "} else\n" .
+ " {$section_props}['total'] = 0;\n";
+
+ $output .= "if ({$section_props}['show']):\n";
+ $output .= "
+ for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+ {$section_props}['iteration'] <= {$section_props}['total'];
+ {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+ $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+ $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+ $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+ $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
+ $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+ $output .= "?>";
+
+ return $output;
+ }
+
+
+ /**
+ * Compile {foreach ...} tag.
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_foreach_start($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = array();
+
+ if (empty($attrs['from'])) {
+ return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ $from = $attrs['from'];
+
+ if (empty($attrs['item'])) {
+ return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ $item = $this->_dequote($attrs['item']);
+ if (!preg_match('~^\w+$~', $item)) {
+ return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ if (isset($attrs['key'])) {
+ $key = $this->_dequote($attrs['key']);
+ if (!preg_match('~^\w+$~', $key)) {
+ return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ $key_part = "\$this->_tpl_vars['$key'] => ";
+ } else {
+ $key = null;
+ $key_part = '';
+ }
+
+ if (isset($attrs['name'])) {
+ $name = $attrs['name'];
+ } else {
+ $name = null;
+ }
+
+ $output = '<?php ';
+ $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
+ if (isset($name)) {
+ $foreach_props = "\$this->_foreach[$name]";
+ $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
+ $output .= "if ({$foreach_props}['total'] > 0):\n";
+ $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+ $output .= " {$foreach_props}['iteration']++;\n";
+ } else {
+ $output .= "if (count(\$_from)):\n";
+ $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+ }
+ $output .= '?>';
+
+ return $output;
+ }
+
+
+ /**
+ * Compile {capture} .. {/capture} tags
+ *
+ * @param boolean $start true if this is the {capture} tag
+ * @param string $tag_args
+ * @return string
+ */
+
+ function _compile_capture_tag($start, $tag_args = '')
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+
+ if ($start) {
+ $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
+ $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
+ $append = isset($attrs['append']) ? $attrs['append'] : null;
+
+ $output = "<?php ob_start(); ?>";
+ $this->_capture_stack[] = array($buffer, $assign, $append);
+ } else {
+ list($buffer, $assign, $append) = array_pop($this->_capture_stack);
+ $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
+ if (isset($assign)) {
+ $output .= " \$this->assign($assign, ob_get_contents());";
+ }
+ if (isset($append)) {
+ $output .= " \$this->append($append, ob_get_contents());";
+ }
+ $output .= "ob_end_clean(); ?>";
+ }
+
+ return $output;
+ }
+
+ /**
+ * Compile {if ...} tag
+ *
+ * @param string $tag_args
+ * @param boolean $elseif if true, uses elseif instead of if
+ * @return string
+ */
+ function _compile_if_tag($tag_args, $elseif = false)
+ {
+
+ /* Tokenize args for 'if' tag. */
+ preg_match_all('~(?>
+ ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
+ ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string
+ \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token
+ \b\w+\b | # valid word token
+ \S+ # anything else
+ )~x', $tag_args, $match);
+
+ $tokens = $match[0];
+
+ if(empty($tokens)) {
+ $_error_msg = $elseif ? "'elseif'" : "'if'";
+ $_error_msg .= ' statement requires arguments';
+ $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+
+ // make sure we have balanced parenthesis
+ $token_count = array_count_values($tokens);
+ if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
+ $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $is_arg_stack = array();
+
+ for ($i = 0; $i < count($tokens); $i++) {
+
+ $token = &$tokens[$i];
+
+ switch (strtolower($token)) {
+ case '!':
+ case '%':
+ case '!==':
+ case '==':
+ case '===':
+ case '>':
+ case '<':
+ case '!=':
+ case '<>':
+ case '<<':
+ case '>>':
+ case '<=':
+ case '>=':
+ case '&&':
+ case '||':
+ case '|':
+ case '^':
+ case '&':
+ case '~':
+ case ')':
+ case ',':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '@':
+ break;
+
+ case 'eq':
+ $token = '==';
+ break;
+
+ case 'ne':
+ case 'neq':
+ $token = '!=';
+ break;
+
+ case 'lt':
+ $token = '<';
+ break;
+
+ case 'le':
+ case 'lte':
+ $token = '<=';
+ break;
+
+ case 'gt':
+ $token = '>';
+ break;
+
+ case 'ge':
+ case 'gte':
+ $token = '>=';
+ break;
+
+ case 'and':
+ $token = '&&';
+ break;
+
+ case 'or':
+ $token = '||';
+ break;
+
+ case 'not':
+ $token = '!';
+ break;
+
+ case 'mod':
+ $token = '%';
+ break;
+
+ case '(':
+ array_push($is_arg_stack, $i);
+ break;
+
+ case 'is':
+ /* If last token was a ')', we operate on the parenthesized
+ expression. The start of the expression is on the stack.
+ Otherwise, we operate on the last encountered token. */
+ if ($tokens[$i-1] == ')') {
+ $is_arg_start = array_pop($is_arg_stack);
+ if ($is_arg_start != 0) {
+ if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
+ $is_arg_start--;
+ }
+ }
+ } else
+ $is_arg_start = $i-1;
+ /* Construct the argument for 'is' expression, so it knows
+ what to operate on. */
+ $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
+
+ /* Pass all tokens from next one until the end to the
+ 'is' expression parsing function. The function will
+ return modified tokens, where the first one is the result
+ of the 'is' expression and the rest are the tokens it
+ didn't touch. */
+ $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
+
+ /* Replace the old tokens with the new ones. */
+ array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
+
+ /* Adjust argument start so that it won't change from the
+ current position for the next iteration. */
+ $i = $is_arg_start;
+ break;
+
+ default:
+ if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
+ // function call
+ if($this->security &&
+ !in_array($token, $this->security_settings['IF_FUNCS'])) {
+ $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
+ // variable function call
+ $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
+ } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
+ // object or variable
+ $token = $this->_parse_var_props($token);
+ } elseif(is_numeric($token)) {
+ // number, skip it
+ } else {
+ $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ break;
+ }
+ }
+
+ if ($elseif)
+ return '<?php elseif ('.implode(' ', $tokens).'): ?>';
+ else
+ return '<?php if ('.implode(' ', $tokens).'): ?>';
+ }
+
+
+ function _compile_arg_list($type, $name, $attrs, &$cache_code) {
+ $arg_list = array();
+
+ if (isset($type) && isset($name)
+ && isset($this->_plugins[$type])
+ && isset($this->_plugins[$type][$name])
+ && empty($this->_plugins[$type][$name][4])
+ && is_array($this->_plugins[$type][$name][5])
+ ) {
+ /* we have a list of parameters that should be cached */
+ $_cache_attrs = $this->_plugins[$type][$name][5];
+ $_count = $this->_cache_attrs_count++;
+ $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
+
+ } else {
+ /* no parameters are cached */
+ $_cache_attrs = null;
+ }
+
+ foreach ($attrs as $arg_name => $arg_value) {
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ if (is_null($arg_value))
+ $arg_value = 'null';
+ if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
+ $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
+ } else {
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+ }
+ return $arg_list;
+ }
+
+ /**
+ * Parse is expression
+ *
+ * @param string $is_arg
+ * @param array $tokens
+ * @return array
+ */
+ function _parse_is_expr($is_arg, $tokens)
+ {
+ $expr_end = 0;
+ $negate_expr = false;
+
+ if (($first_token = array_shift($tokens)) == 'not') {
+ $negate_expr = true;
+ $expr_type = array_shift($tokens);
+ } else
+ $expr_type = $first_token;
+
+ switch ($expr_type) {
+ case 'even':
+ if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+ } else
+ $expr = "!(1 & $is_arg)";
+ break;
+
+ case 'odd':
+ if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+ } else
+ $expr = "(1 & $is_arg)";
+ break;
+
+ case 'div':
+ if (@$tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
+ } else {
+ $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ break;
+
+ default:
+ $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+
+ if ($negate_expr) {
+ $expr = "!($expr)";
+ }
+
+ array_splice($tokens, 0, $expr_end, $expr);
+
+ return $tokens;
+ }
+
+
+ /**
+ * Parse attribute string
+ *
+ * @param string $tag_args
+ * @return array
+ */
+ function _parse_attrs($tag_args)
+ {
+
+ /* Tokenize tag attributes. */
+ preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
+ )+ |
+ [=]
+ ~x', $tag_args, $match);
+ $tokens = $match[0];
+
+ $attrs = array();
+ /* Parse state:
+ 0 - expecting attribute name
+ 1 - expecting '='
+ 2 - expecting attribute value (not '=') */
+ $state = 0;
+
+ foreach ($tokens as $token) {
+ switch ($state) {
+ case 0:
+ /* If the token is a valid identifier, we set attribute name
+ and go to state 1. */
+ if (preg_match('~^\w+$~', $token)) {
+ $attr_name = $token;
+ $state = 1;
+ } else
+ $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+
+ case 1:
+ /* If the token is '=', then we go to state 2. */
+ if ($token == '=') {
+ $state = 2;
+ } else
+ $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+
+ case 2:
+ /* If token is not '=', we set the attribute value and go to
+ state 0. */
+ if ($token != '=') {
+ /* We booleanize the token if it's a non-quoted possible
+ boolean value. */
+ if (preg_match('~^(on|yes|true)$~', $token)) {
+ $token = 'true';
+ } else if (preg_match('~^(off|no|false)$~', $token)) {
+ $token = 'false';
+ } else if ($token == 'null') {
+ $token = 'null';
+ } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
+ /* treat integer literally */
+ } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
+ /* treat as a string, double-quote it escaping quotes */
+ $token = '"'.addslashes($token).'"';
+ }
+
+ $attrs[$attr_name] = $token;
+ $state = 0;
+ } else
+ $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+ $last_token = $token;
+ }
+
+ if($state != 0) {
+ if($state == 1) {
+ $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+ } else {
+ $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ }
+
+ $this->_parse_vars_props($attrs);
+
+ return $attrs;
+ }
+
+ /**
+ * compile multiple variables and section properties tokens into
+ * PHP code
+ *
+ * @param array $tokens
+ */
+ function _parse_vars_props(&$tokens)
+ {
+ foreach($tokens as $key => $val) {
+ $tokens[$key] = $this->_parse_var_props($val);
+ }
+ }
+
+ /**
+ * compile single variable and section properties token into
+ * PHP code
+ *
+ * @param string $val
+ * @param string $tag_attrs
+ * @return string
+ */
+ function _parse_var_props($val)
+ {
+ $val = trim($val);
+
+ if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
+ // $ variable or object
+ $return = $this->_parse_var($match[1]);
+ $modifiers = $match[2];
+ if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
+ $_default_mod_string = implode('|',(array)$this->default_modifiers);
+ $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
+ }
+ $this->_parse_modifiers($return, $modifiers);
+ return $return;
+ } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+ // double quoted text
+ preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+ $return = $this->_expand_quoted_text($match[1]);
+ if($match[2] != '') {
+ $this->_parse_modifiers($return, $match[2]);
+ }
+ return $return;
+ }
+ elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+ // numerical constant
+ preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+ if($match[2] != '') {
+ $this->_parse_modifiers($match[1], $match[2]);
+ return $match[1];
+ }
+ }
+ elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+ // single quoted text
+ preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+ if($match[2] != '') {
+ $this->_parse_modifiers($match[1], $match[2]);
+ return $match[1];
+ }
+ }
+ elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+ // config var
+ return $this->_parse_conf_var($val);
+ }
+ elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+ // section var
+ return $this->_parse_section_prop($val);
+ }
+ elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
+ // literal string
+ return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
+ }
+ return $val;
+ }
+
+ /**
+ * expand quoted text with embedded variables
+ *
+ * @param string $var_expr
+ * @return string
+ */
+ function _expand_quoted_text($var_expr)
+ {
+ // if contains unescaped $, expand it
+ if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
+ $_match = $_match[0];
+ $_replace = array();
+ foreach($_match as $_var) {
+ $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
+ }
+ $var_expr = strtr($var_expr, $_replace);
+ $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
+ } else {
+ $_return = $var_expr;
+ }
+ // replace double quoted literal string with single quotes
+ $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
+ return $_return;
+ }
+
+ /**
+ * parse variable expression into PHP code
+ *
+ * @param string $var_expr
+ * @param string $output
+ * @return string
+ */
+ function _parse_var($var_expr)
+ {
+ $_has_math = false;
+ $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+ if(count($_math_vars) > 1) {
+ $_first_var = "";
+ $_complete_var = "";
+ $_output = "";
+ // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
+ foreach($_math_vars as $_k => $_math_var) {
+ $_math_var = $_math_vars[$_k];
+
+ if(!empty($_math_var) || is_numeric($_math_var)) {
+ // hit a math operator, so process the stuff which came before it
+ if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
+ $_has_math = true;
+ if(!empty($_complete_var) || is_numeric($_complete_var)) {
+ $_output .= $this->_parse_var($_complete_var);
+ }
+
+ // just output the math operator to php
+ $_output .= $_math_var;
+
+ if(empty($_first_var))
+ $_first_var = $_complete_var;
+
+ $_complete_var = "";
+ } else {
+ $_complete_var .= $_math_var;
+ }
+ }
+ }
+ if($_has_math) {
+ if(!empty($_complete_var) || is_numeric($_complete_var))
+ $_output .= $this->_parse_var($_complete_var);
+
+ // get the modifiers working (only the last var from math + modifier is left)
+ $var_expr = $_complete_var;
+ }
+ }
+
+ // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
+ if(is_numeric(substr($var_expr, 0, 1)))
+ $_var_ref = $var_expr;
+ else
+ $_var_ref = substr($var_expr, 1);
+
+ if(!$_has_math) {
+
+ // get [foo] and .foo and ->foo and (...) pieces
+ preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
+
+ $_indexes = $match[0];
+ $_var_name = array_shift($_indexes);
+
+ /* Handle $smarty.* variable references as a special case. */
+ if ($_var_name == 'smarty') {
+ /*
+ * If the reference could be compiled, use the compiled output;
+ * otherwise, fall back on the $smarty variable generated at
+ * run-time.
+ */
+ if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
+ $_output = $smarty_ref;
+ } else {
+ $_var_name = substr(array_shift($_indexes), 1);
+ $_output = "\$this->_smarty_vars['$_var_name']";
+ }
+ } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
+ // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
+ if(count($_indexes) > 0)
+ {
+ $_var_name .= implode("", $_indexes);
+ $_indexes = array();
+ }
+ $_output = $_var_name;
+ } else {
+ $_output = "\$this->_tpl_vars['$_var_name']";
+ }
+
+ foreach ($_indexes as $_index) {
+ if (substr($_index, 0, 1) == '[') {
+ $_index = substr($_index, 1, -1);
+ if (is_numeric($_index)) {
+ $_output .= "[$_index]";
+ } elseif (substr($_index, 0, 1) == '$') {
+ if (strpos($_index, '.') !== false) {
+ $_output .= '[' . $this->_parse_var($_index) . ']';
+ } else {
+ $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
+ }
+ } else {
+ $_var_parts = explode('.', $_index);
+ $_var_section = $_var_parts[0];
+ $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
+ $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
+ }
+ } else if (substr($_index, 0, 1) == '.') {
+ if (substr($_index, 1, 1) == '$')
+ $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
+ else
+ $_output .= "['" . substr($_index, 1) . "']";
+ } else if (substr($_index,0,2) == '->') {
+ if(substr($_index,2,2) == '__') {
+ $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+ } elseif($this->security && substr($_index, 2, 1) == '_') {
+ $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+ } elseif (substr($_index, 2, 1) == '$') {
+ if ($this->security) {
+ $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+ } else {
+ $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
+ }
+ } else {
+ $_output .= $_index;
+ }
+ } elseif (substr($_index, 0, 1) == '(') {
+ $_index = $this->_parse_parenth_args($_index);
+ $_output .= $_index;
+ } else {
+ $_output .= $_index;
+ }
+ }
+ }
+
+ return $_output;
+ }
+
+ /**
+ * parse arguments in function call parenthesis
+ *
+ * @param string $parenth_args
+ * @return string
+ */
+ function _parse_parenth_args($parenth_args)
+ {
+ preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
+ $orig_vals = $match = $match[0];
+ $this->_parse_vars_props($match);
+ $replace = array();
+ for ($i = 0, $count = count($match); $i < $count; $i++) {
+ $replace[$orig_vals[$i]] = $match[$i];
+ }
+ return strtr($parenth_args, $replace);
+ }
+
+ /**
+ * parse configuration variable expression into PHP code
+ *
+ * @param string $conf_var_expr
+ */
+ function _parse_conf_var($conf_var_expr)
+ {
+ $parts = explode('|', $conf_var_expr, 2);
+ $var_ref = $parts[0];
+ $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+ $var_name = substr($var_ref, 1, -1);
+
+ $output = "\$this->_config[0]['vars']['$var_name']";
+
+ $this->_parse_modifiers($output, $modifiers);
+
+ return $output;
+ }
+
+ /**
+ * parse section property expression into PHP code
+ *
+ * @param string $section_prop_expr
+ * @return string
+ */
+ function _parse_section_prop($section_prop_expr)
+ {
+ $parts = explode('|', $section_prop_expr, 2);
+ $var_ref = $parts[0];
+ $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+ preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
+ $section_name = $match[1];
+ $prop_name = $match[2];
+
+ $output = "\$this->_sections['$section_name']['$prop_name']";
+
+ $this->_parse_modifiers($output, $modifiers);
+
+ return $output;
+ }
+
+
+ /**
+ * parse modifier chain into PHP code
+ *
+ * sets $output to parsed modified chain
+ * @param string $output
+ * @param string $modifier_string
+ */
+ function _parse_modifiers(&$output, $modifier_string)
+ {
+ preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
+ list(, $_modifiers, $modifier_arg_strings) = $_match;
+
+ for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
+ $_modifier_name = $_modifiers[$_i];
+
+ if($_modifier_name == 'smarty') {
+ // skip smarty modifier
+ continue;
+ }
+
+ preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
+ $_modifier_args = $_match[1];
+
+ if (substr($_modifier_name, 0, 1) == '@') {
+ $_map_array = false;
+ $_modifier_name = substr($_modifier_name, 1);
+ } else {
+ $_map_array = true;
+ }
+
+ if (empty($this->_plugins['modifier'][$_modifier_name])
+ && !$this->_get_plugin_filepath('modifier', $_modifier_name)
+ && function_exists($_modifier_name)) {
+ if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
+ $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+ } else {
+ $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false);
+ }
+ }
+ $this->_add_plugin('modifier', $_modifier_name);
+
+ $this->_parse_vars_props($_modifier_args);
+
+ if($_modifier_name == 'default') {
+ // supress notifications of default modifier vars and args
+ if(substr($output, 0, 1) == '$') {
+ $output = '@' . $output;
+ }
+ if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
+ $_modifier_args[0] = '@' . $_modifier_args[0];
+ }
+ }
+ if (count($_modifier_args) > 0)
+ $_modifier_args = ', '.implode(', ', $_modifier_args);
+ else
+ $_modifier_args = '';
+
+ if ($_map_array) {
+ $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
+
+ } else {
+
+ $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
+
+ }
+ }
+ }
+
+
+ /**
+ * add plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @param boolean? $delayed_loading
+ */
+ function _add_plugin($type, $name, $delayed_loading = null)
+ {
+ if (!isset($this->_plugin_info[$type])) {
+ $this->_plugin_info[$type] = array();
+ }
+ if (!isset($this->_plugin_info[$type][$name])) {
+ $this->_plugin_info[$type][$name] = array($this->_current_file,
+ $this->_current_line_no,
+ $delayed_loading);
+ }
+ }
+
+
+ /**
+ * Compiles references of type $smarty.foo
+ *
+ * @param string $indexes
+ * @return string
+ */
+ function _compile_smarty_ref(&$indexes)
+ {
+ /* Extract the reference name. */
+ $_ref = substr($indexes[0], 1);
+ foreach($indexes as $_index_no=>$_index) {
+ if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
+ $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+ }
+ }
+
+ switch ($_ref) {
+ case 'now':
+ $compiled_ref = 'time()';
+ $_max_index = 1;
+ break;
+
+ case 'foreach':
+ array_shift($indexes);
+ $_var = $this->_parse_var_props(substr($indexes[0], 1));
+ $_propname = substr($indexes[1], 1);
+ $_max_index = 1;
+ switch ($_propname) {
+ case 'index':
+ array_shift($indexes);
+ $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
+ break;
+
+ case 'first':
+ array_shift($indexes);
+ $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
+ break;
+
+ case 'last':
+ array_shift($indexes);
+ $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
+ break;
+
+ case 'show':
+ array_shift($indexes);
+ $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
+ break;
+
+ default:
+ unset($_max_index);
+ $compiled_ref = "\$this->_foreach[$_var]";
+ }
+ break;
+
+ case 'section':
+ array_shift($indexes);
+ $_var = $this->_parse_var_props(substr($indexes[0], 1));
+ $compiled_ref = "\$this->_sections[$_var]";
+ break;
+
+ case 'get':
+ if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
+ $this->_syntax_error("(secure mode) super global access not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ $compiled_ref = "\$_GET";
+ break;
+
+ case 'post':
+ if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
+ $this->_syntax_error("(secure mode) super global access not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ $compiled_ref = "\$_POST";
+ break;
+
+ case 'cookies':
+ if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
+ $this->_syntax_error("(secure mode) super global access not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ $compiled_ref = "\$_COOKIE";
+ break;
+
+ case 'env':
+ if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
+ $this->_syntax_error("(secure mode) super global access not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ $compiled_ref = "\$_ENV";
+ break;
+
+ case 'server':
+ if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
+ $this->_syntax_error("(secure mode) super global access not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ $compiled_ref = "\$_SERVER";
+ break;
+
+ case 'session':
+ if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
+ $this->_syntax_error("(secure mode) super global access not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ $compiled_ref = "\$_SESSION";
+ break;
+
+ /*
+ * These cases are handled either at run-time or elsewhere in the
+ * compiler.
+ */
+ case 'request':
+ if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
+ $this->_syntax_error("(secure mode) super global access not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ if ($this->request_use_auto_globals) {
+ $compiled_ref = "\$_REQUEST";
+ break;
+ } else {
+ $this->_init_smarty_vars = true;
+ }
+ return null;
+
+ case 'capture':
+ return null;
+
+ case 'template':
+ $compiled_ref = "'$this->_current_file'";
+ $_max_index = 1;
+ break;
+
+ case 'version':
+ $compiled_ref = "'$this->_version'";
+ $_max_index = 1;
+ break;
+
+ case 'const':
+ if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
+ $this->_syntax_error("(secure mode) constants not permitted",
+ E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ array_shift($indexes);
+ if (preg_match('!^\.\w+$!', $indexes[0])) {
+ $compiled_ref = '@' . substr($indexes[0], 1);
+ } else {
+ $_val = $this->_parse_var_props(substr($indexes[0], 1));
+ $compiled_ref = '@constant(' . $_val . ')';
+ }
+ $_max_index = 1;
+ break;
+
+ case 'config':
+ $compiled_ref = "\$this->_config[0]['vars']";
+ $_max_index = 3;
+ break;
+
+ case 'ldelim':
+ $compiled_ref = "'$this->left_delimiter'";
+ break;
+
+ case 'rdelim':
+ $compiled_ref = "'$this->right_delimiter'";
+ break;
+
+ default:
+ $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+
+ if (isset($_max_index) && count($indexes) > $_max_index) {
+ $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ array_shift($indexes);
+ return $compiled_ref;
+ }
+
+ /**
+ * compiles call to plugin of type $type with name $name
+ * returns a string containing the function-name or method call
+ * without the paramter-list that would have follow to make the
+ * call valid php-syntax
+ *
+ * @param string $type
+ * @param string $name
+ * @return string
+ */
+ function _compile_plugin_call($type, $name) {
+ if (isset($this->_plugins[$type][$name])) {
+ /* plugin loaded */
+ if (is_array($this->_plugins[$type][$name][0])) {
+ return ((is_object($this->_plugins[$type][$name][0][0])) ?
+ "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */
+ : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */
+ ). $this->_plugins[$type][$name][0][1];
+
+ } else {
+ /* function callback */
+ return $this->_plugins[$type][$name][0];
+
+ }
+ } else {
+ /* plugin not loaded -> auto-loadable-plugin */
+ return 'smarty_'.$type.'_'.$name;
+
+ }
+ }
+
+ /**
+ * load pre- and post-filters
+ */
+ function _load_filters()
+ {
+ if (count($this->_plugins['prefilter']) > 0) {
+ foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+ if ($prefilter === false) {
+ unset($this->_plugins['prefilter'][$filter_name]);
+ $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
+ require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ }
+ }
+ }
+ if (count($this->_plugins['postfilter']) > 0) {
+ foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+ if ($postfilter === false) {
+ unset($this->_plugins['postfilter'][$filter_name]);
+ $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
+ require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Quote subpattern references
+ *
+ * @param string $string
+ * @return string
+ */
+ function _quote_replace($string)
+ {
+ return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
+ }
+
+ /**
+ * display Smarty syntax error
+ *
+ * @param string $error_msg
+ * @param integer $error_type
+ * @param string $file
+ * @param integer $line
+ */
+ function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
+ {
+ $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
+ }
+
+
+ /**
+ * check if the compilation changes from cacheable to
+ * non-cacheable state with the beginning of the current
+ * plugin. return php-code to reflect the transition.
+ * @return string
+ */
+ function _push_cacheable_state($type, $name) {
+ $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+ if ($_cacheable
+ || 0<$this->_cacheable_state++) return '';
+ if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
+ $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
+ . $this->_cache_serial . '#' . $this->_nocache_count
+ . '}\'; endif;';
+ return $_ret;
+ }
+
+
+ /**
+ * check if the compilation changes from non-cacheable to
+ * cacheable state with the end of the current plugin return
+ * php-code to reflect the transition.
+ * @return string
+ */
+ function _pop_cacheable_state($type, $name) {
+ $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+ if ($_cacheable
+ || --$this->_cacheable_state>0) return '';
+ return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
+ . $this->_cache_serial . '#' . ($this->_nocache_count++)
+ . '}\'; endif;';
+ }
+
+
+ /**
+ * push opening tag-name, file-name and line-number on the tag-stack
+ * @param string the opening tag's name
+ */
+ function _push_tag($open_tag)
+ {
+ array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
+ }
+
+ /**
+ * pop closing tag-name
+ * raise an error if this stack-top doesn't match with the closing tag
+ * @param string the closing tag's name
+ * @return string the opening tag's name
+ */
+ function _pop_tag($close_tag)
+ {
+ $message = '';
+ if (count($this->_tag_stack)>0) {
+ list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
+ if ($close_tag == $_open_tag) {
+ return $_open_tag;
+ }
+ if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
+ return $this->_pop_tag($close_tag);
+ }
+ if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
+ $this->_pop_tag($close_tag);
+ return $_open_tag;
+ }
+ if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
+ $this->_pop_tag($close_tag);
+ return $_open_tag;
+ }
+ if ($_open_tag == 'else' || $_open_tag == 'elseif') {
+ $_open_tag = 'if';
+ } elseif ($_open_tag == 'sectionelse') {
+ $_open_tag = 'section';
+ } elseif ($_open_tag == 'foreachelse') {
+ $_open_tag = 'foreach';
+ }
+ $message = " expected {/$_open_tag} (opened line $_line_no).";
+ }
+ $this->_syntax_error("mismatched tag {/$close_tag}.$message",
+ E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+}
+
+/**
+ * compare to values by their string length
+ *
+ * @access private
+ * @param string $a
+ * @param string $b
+ * @return 0|-1|1
+ */
+function _smarty_sort_length($a, $b)
+{
+ if($a == $b)
+ return 0;
+
+ if(strlen($a) == strlen($b))
+ return ($a > $b) ? -1 : 1;
+
+ return (strlen($a) > strlen($b)) ? -1 : 1;
+}
+
+
+/* vim: set et: */
+
+?>
--- /dev/null
+{* Smarty *}
+{* debug.tpl, last updated version 2.1.0 *}
+{assign_debug_info}
+{capture assign=debug_output}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+ <title>Smarty Debug Console</title>
+{literal}
+<style type="text/css">
+/* <![CDATA[ */
+body, h1, h2, td, th, p {
+ font-family: sans-serif;
+ font-weight: normal;
+ font-size: 0.9em;
+ margin: 1px;
+ padding: 0;
+}
+
+h1 {
+ margin: 0;
+ text-align: left;
+ padding: 2px;
+ background-color: #f0c040;
+ color: black;
+ font-weight: bold;
+ font-size: 1.2em;
+ }
+
+h2 {
+ background-color: #9B410E;
+ color: white;
+ text-align: left;
+ font-weight: bold;
+ padding: 2px;
+ border-top: 1px solid black;
+}
+
+body {
+ background: black;
+}
+
+p, table, div {
+ background: #f0ead8;
+}
+
+p {
+ margin: 0;
+ font-style: italic;
+ text-align: center;
+}
+
+table {
+ width: 100%;
+}
+
+th, td {
+ font-family: monospace;
+ vertical-align: top;
+ text-align: left;
+ width: 50%;
+}
+
+td {
+ color: green;
+}
+
+.odd {
+ background-color: #eeeeee;
+}
+
+.even {
+ background-color: #fafafa;
+}
+
+.exectime {
+ font-size: 0.8em;
+ font-style: italic;
+}
+
+#table_assigned_vars th {
+ color: blue;
+}
+
+#table_config_vars th {
+ color: maroon;
+}
+/* ]]> */
+</style>
+{/literal}
+</head>
+<body>
+
+<h1>Smarty Debug Console</h1>
+
+<h2>included templates & config files (load time in seconds)</h2>
+
+<div>
+{section name=templates loop=$_debug_tpls}
+ {section name=indent loop=$_debug_tpls[templates].depth} {/section}
+ <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
+ {$_debug_tpls[templates].filename|escape:html}</font>
+ {if isset($_debug_tpls[templates].exec_time)}
+ <span class="exectime">
+ ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
+ {if %templates.index% eq 0}(total){/if}
+ </span>
+ {/if}
+ <br />
+{sectionelse}
+ <p>no templates included</p>
+{/section}
+</div>
+
+<h2>assigned template variables</h2>
+
+<table id="table_assigned_vars">
+ {section name=vars loop=$_debug_keys}
+ <tr class="{cycle values="odd,even"}">
+ <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
+ <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
+ {sectionelse}
+ <tr><td><p>no template variables assigned</p></td></tr>
+ {/section}
+</table>
+
+<h2>assigned config file variables (outer template scope)</h2>
+
+<table id="table_config_vars">
+ {section name=config_vars loop=$_debug_config_keys}
+ <tr class="{cycle values="odd,even"}">
+ <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
+ <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
+ {sectionelse}
+ <tr><td><p>no config vars assigned</p></td></tr>
+ {/section}
+</table>
+</body>
+</html>
+{/capture}
+{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
+ {$debug_output}
+{else}
+<script type="text/javascript">
+// <![CDATA[
+ if ( self.name == '' ) {ldelim}
+ var title = 'Console';
+ {rdelim}
+ else {ldelim}
+ var title = 'Console_' + self.name;
+ {rdelim}
+ _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
+ _smarty_console.document.write('{$debug_output|escape:'javascript'}');
+ _smarty_console.document.close();
+// ]]>
+</script>
+{/if}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * assemble filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+function smarty_core_assemble_plugin_filepath($params, &$smarty)
+{
+ static $_filepaths_cache = array();
+
+ $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
+ if (isset($_filepaths_cache[$_plugin_filename])) {
+ return $_filepaths_cache[$_plugin_filename];
+ }
+ $_return = false;
+
+ foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
+
+ $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+ // see if path is relative
+ if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
+ $_relative_paths[] = $_plugin_dir;
+ // relative path, see if it is in the SMARTY_DIR
+ if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
+ $_return = SMARTY_DIR . $_plugin_filepath;
+ break;
+ }
+ }
+ // try relative to cwd (or absolute)
+ if (@is_readable($_plugin_filepath)) {
+ $_return = $_plugin_filepath;
+ break;
+ }
+ }
+
+ if($_return === false) {
+ // still not found, try PHP include_path
+ if(isset($_relative_paths)) {
+ foreach ((array)$_relative_paths as $_plugin_dir) {
+
+ $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+ $_params = array('file_path' => $_plugin_filepath);
+ require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+ if(smarty_core_get_include_path($_params, $smarty)) {
+ $_return = $_params['new_file_path'];
+ break;
+ }
+ }
+ }
+ }
+ $_filepaths_cache[$_plugin_filename] = $_return;
+ return $_return;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty assign_smarty_interface core plugin
+ *
+ * Type: core<br>
+ * Name: assign_smarty_interface<br>
+ * Purpose: assign the $smarty interface variable
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_assign_smarty_interface($params, &$smarty)
+{
+ if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
+ return;
+ }
+
+ $_globals_map = array('g' => 'HTTP_GET_VARS',
+ 'p' => 'HTTP_POST_VARS',
+ 'c' => 'HTTP_COOKIE_VARS',
+ 's' => 'HTTP_SERVER_VARS',
+ 'e' => 'HTTP_ENV_VARS');
+
+ $_smarty_vars_request = array();
+
+ foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
+ if (isset($_globals_map[$_c])) {
+ $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
+ }
+ }
+ $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
+
+ $smarty->_smarty_vars['request'] = $_smarty_vars_request;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * create full directory structure
+ *
+ * @param string $dir
+ */
+
+// $dir
+
+function smarty_core_create_dir_structure($params, &$smarty)
+{
+ if (!file_exists($params['dir'])) {
+ $_open_basedir_ini = ini_get('open_basedir');
+
+ if (DIRECTORY_SEPARATOR=='/') {
+ /* unix-style paths */
+ $_dir = $params['dir'];
+ $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+ $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
+ if($_use_open_basedir = !empty($_open_basedir_ini)) {
+ $_open_basedirs = explode(':', $_open_basedir_ini);
+ }
+
+ } else {
+ /* other-style paths */
+ $_dir = str_replace('\\','/', $params['dir']);
+ $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+ if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
+ /* leading "//" for network volume, or "[letter]:/" for full path */
+ $_new_dir = $_root_dir[1];
+ /* remove drive-letter from _dir_parts */
+ if (isset($_root_dir[3])) array_shift($_dir_parts);
+
+ } else {
+ $_new_dir = str_replace('\\', '/', getcwd()).'/';
+
+ }
+
+ if($_use_open_basedir = !empty($_open_basedir_ini)) {
+ $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
+ }
+
+ }
+
+ /* all paths use "/" only from here */
+ foreach ($_dir_parts as $_dir_part) {
+ $_new_dir .= $_dir_part;
+
+ if ($_use_open_basedir) {
+ // do not attempt to test or make directories outside of open_basedir
+ $_make_new_dir = false;
+ foreach ($_open_basedirs as $_open_basedir) {
+ if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
+ $_make_new_dir = true;
+ break;
+ }
+ }
+ } else {
+ $_make_new_dir = true;
+ }
+
+ if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
+ $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
+ return false;
+ }
+ $_new_dir .= '/';
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty debug_console function plugin
+ *
+ * Type: core<br>
+ * Name: display_debug_console<br>
+ * Purpose: display the javascript debug console window
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_display_debug_console($params, &$smarty)
+{
+ // we must force compile the debug template in case the environment
+ // changed between separate applications.
+
+ if(empty($smarty->debug_tpl)) {
+ // set path to debug template from SMARTY_DIR
+ $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
+ if($smarty->security && is_file($smarty->debug_tpl)) {
+ $smarty->secure_dir[] = realpath($smarty->debug_tpl);
+ }
+ $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
+ }
+
+ $_ldelim_orig = $smarty->left_delimiter;
+ $_rdelim_orig = $smarty->right_delimiter;
+
+ $smarty->left_delimiter = '{';
+ $smarty->right_delimiter = '}';
+
+ $_compile_id_orig = $smarty->_compile_id;
+ $smarty->_compile_id = null;
+
+ $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
+ if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
+ {
+ ob_start();
+ $smarty->_include($_compile_path);
+ $_results = ob_get_contents();
+ ob_end_clean();
+ } else {
+ $_results = '';
+ }
+
+ $smarty->_compile_id = $_compile_id_orig;
+
+ $smarty->left_delimiter = $_ldelim_orig;
+ $smarty->right_delimiter = $_rdelim_orig;
+
+ return $_results;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get path to file from include_path
+ *
+ * @param string $file_path
+ * @param string $new_file_path
+ * @return boolean
+ * @staticvar array|null
+ */
+
+// $file_path, &$new_file_path
+
+function smarty_core_get_include_path(&$params, &$smarty)
+{
+ static $_path_array = null;
+
+ if(!isset($_path_array)) {
+ $_ini_include_path = ini_get('include_path');
+
+ if(strstr($_ini_include_path,';')) {
+ // windows pathnames
+ $_path_array = explode(';',$_ini_include_path);
+ } else {
+ $_path_array = explode(':',$_ini_include_path);
+ }
+ }
+ foreach ($_path_array as $_include_path) {
+ if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
+ $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
+ return true;
+ }
+ }
+ return false;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get seconds and microseconds
+ * @return double
+ */
+function smarty_core_get_microtime($params, &$smarty)
+{
+ $mtime = microtime();
+ $mtime = explode(" ", $mtime);
+ $mtime = (double)($mtime[1]) + (double)($mtime[0]);
+ return ($mtime);
+}
+
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Retrieves PHP script resource
+ *
+ * sets $php_resource to the returned resource
+ * @param string $resource
+ * @param string $resource_type
+ * @param $php_resource
+ * @return boolean
+ */
+
+function smarty_core_get_php_resource(&$params, &$smarty)
+{
+
+ $params['resource_base_path'] = $smarty->trusted_dir;
+ $smarty->_parse_resource_name($params, $smarty);
+
+ /*
+ * Find out if the resource exists.
+ */
+
+ if ($params['resource_type'] == 'file') {
+ $_readable = false;
+ if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
+ $_readable = true;
+ } else {
+ // test for file in include_path
+ $_params = array('file_path' => $params['resource_name']);
+ require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+ if(smarty_core_get_include_path($_params, $smarty)) {
+ $_include_path = $_params['new_file_path'];
+ $_readable = true;
+ }
+ }
+ } else if ($params['resource_type'] != 'file') {
+ $_template_source = null;
+ $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
+ && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
+ array($params['resource_name'], &$_template_source, &$smarty));
+ }
+
+ /*
+ * Set the error function, depending on which class calls us.
+ */
+ if (method_exists($smarty, '_syntax_error')) {
+ $_error_funcc = '_syntax_error';
+ } else {
+ $_error_funcc = 'trigger_error';
+ }
+
+ if ($_readable) {
+ if ($smarty->security) {
+ require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
+ if (!smarty_core_is_trusted($params, $smarty)) {
+ $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
+ return false;
+ }
+ }
+ } else {
+ $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
+ return false;
+ }
+
+ if ($params['resource_type'] == 'file') {
+ $params['php_resource'] = $params['resource_name'];
+ } else {
+ $params['php_resource'] = $_template_source;
+ }
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is secure or not.
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+// $resource_type, $resource_name
+
+function smarty_core_is_secure($params, &$smarty)
+{
+ if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
+ return true;
+ }
+
+ if ($params['resource_type'] == 'file') {
+ $_rp = realpath($params['resource_name']);
+ if (isset($params['resource_base_path'])) {
+ foreach ((array)$params['resource_base_path'] as $curr_dir) {
+ if ( ($_cd = realpath($curr_dir)) !== false &&
+ strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+ substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+ return true;
+ }
+ }
+ }
+ if (!empty($smarty->secure_dir)) {
+ foreach ((array)$smarty->secure_dir as $curr_dir) {
+ if ( ($_cd = realpath($curr_dir)) !== false) {
+ if($_cd == $_rp) {
+ return true;
+ } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+ substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
+ return true;
+ }
+ }
+ }
+ }
+ } else {
+ // resource is not on local file system
+ return call_user_func_array(
+ $smarty->_plugins['resource'][$params['resource_type']][0][2],
+ array($params['resource_name'], &$smarty));
+ }
+
+ return false;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is trusted or not
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ // $resource_type, $resource_name
+
+function smarty_core_is_trusted($params, &$smarty)
+{
+ $_smarty_trusted = false;
+ if ($params['resource_type'] == 'file') {
+ if (!empty($smarty->trusted_dir)) {
+ $_rp = realpath($params['resource_name']);
+ foreach ((array)$smarty->trusted_dir as $curr_dir) {
+ if (!empty($curr_dir) && is_readable ($curr_dir)) {
+ $_cd = realpath($curr_dir);
+ if (strncmp($_rp, $_cd, strlen($_cd)) == 0
+ && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+ $_smarty_trusted = true;
+ break;
+ }
+ }
+ }
+ }
+
+ } else {
+ // resource is not on local file system
+ $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
+ array($params['resource_name'], $smarty));
+ }
+
+ return $_smarty_trusted;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Load requested plugins
+ *
+ * @param array $plugins
+ */
+
+// $plugins
+
+function smarty_core_load_plugins($params, &$smarty)
+{
+
+ foreach ($params['plugins'] as $_plugin_info) {
+ list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
+ $_plugin = &$smarty->_plugins[$_type][$_name];
+
+ /*
+ * We do not load plugin more than once for each instance of Smarty.
+ * The following code checks for that. The plugin can also be
+ * registered dynamically at runtime, in which case template file
+ * and line number will be unknown, so we fill them in.
+ *
+ * The final element of the info array is a flag that indicates
+ * whether the dynamically registered plugin function has been
+ * checked for existence yet or not.
+ */
+ if (isset($_plugin)) {
+ if (empty($_plugin[3])) {
+ if (!is_callable($_plugin[0])) {
+ $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+ } else {
+ $_plugin[1] = $_tpl_file;
+ $_plugin[2] = $_tpl_line;
+ $_plugin[3] = true;
+ if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
+ }
+ }
+ continue;
+ } else if ($_type == 'insert') {
+ /*
+ * For backwards compatibility, we check for insert functions in
+ * the symbol table before trying to load them as a plugin.
+ */
+ $_plugin_func = 'insert_' . $_name;
+ if (function_exists($_plugin_func)) {
+ $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
+ continue;
+ }
+ }
+
+ $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
+
+ if (! $_found = ($_plugin_file != false)) {
+ $_message = "could not load plugin file '$_type.$_name.php'\n";
+ }
+
+ /*
+ * If plugin file is found, it -must- provide the properly named
+ * plugin function. In case it doesn't, simply output the error and
+ * do not fall back on any other method.
+ */
+ if ($_found) {
+ include_once $_plugin_file;
+
+ $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+ if (!function_exists($_plugin_func)) {
+ $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+ continue;
+ }
+ }
+ /*
+ * In case of insert plugins, their code may be loaded later via
+ * 'script' attribute.
+ */
+ else if ($_type == 'insert' && $_delayed_loading) {
+ $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+ $_found = true;
+ }
+
+ /*
+ * Plugin specific processing and error checking.
+ */
+ if (!$_found) {
+ if ($_type == 'modifier') {
+ /*
+ * In case modifier falls back on using PHP functions
+ * directly, we only allow those specified in the security
+ * context.
+ */
+ if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
+ $_message = "(secure mode) modifier '$_name' is not allowed";
+ } else {
+ if (!function_exists($_name)) {
+ $_message = "modifier '$_name' is not implemented";
+ } else {
+ $_plugin_func = $_name;
+ $_found = true;
+ }
+ }
+ } else if ($_type == 'function') {
+ /*
+ * This is a catch-all situation.
+ */
+ $_message = "unknown tag - '$_name'";
+ }
+ }
+
+ if ($_found) {
+ $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
+ } else {
+ // output error
+ $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * load a resource plugin
+ *
+ * @param string $type
+ */
+
+// $type
+
+function smarty_core_load_resource_plugin($params, &$smarty)
+{
+ /*
+ * Resource plugins are not quite like the other ones, so they are
+ * handled differently. The first element of plugin info is the array of
+ * functions provided by the plugin, the second one indicates whether
+ * all of them exist or not.
+ */
+
+ $_plugin = &$smarty->_plugins['resource'][$params['type']];
+ if (isset($_plugin)) {
+ if (!$_plugin[1] && count($_plugin[0])) {
+ $_plugin[1] = true;
+ foreach ($_plugin[0] as $_plugin_func) {
+ if (!is_callable($_plugin_func)) {
+ $_plugin[1] = false;
+ break;
+ }
+ }
+ }
+
+ if (!$_plugin[1]) {
+ $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
+ }
+
+ return;
+ }
+
+ $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
+ $_found = ($_plugin_file != false);
+
+ if ($_found) { /*
+ * If the plugin file is found, it -must- provide the properly named
+ * plugin functions.
+ */
+ include_once($_plugin_file);
+
+ /*
+ * Locate functions that we require the plugin to provide.
+ */
+ $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
+ $_resource_funcs = array();
+ foreach ($_resource_ops as $_op) {
+ $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
+ if (!function_exists($_plugin_func)) {
+ $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
+ return;
+ } else {
+ $_resource_funcs[] = $_plugin_func;
+ }
+ }
+
+ $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace cached inserts with the actual results
+ *
+ * @param string $results
+ * @return string
+ */
+function smarty_core_process_cached_inserts($params, &$smarty)
+{
+ preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
+ $params['results'], $match);
+ list($cached_inserts, $insert_args) = $match;
+
+ for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $debug_start_time = smarty_core_get_microtime($_params, $smarty);
+ }
+
+ $args = unserialize($insert_args[$i]);
+ $name = $args['name'];
+
+ if (isset($args['script'])) {
+ $_params = array('resource_name' => $smarty->_dequote($args['script']));
+ require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+ if(!smarty_core_get_php_resource($_params, $smarty)) {
+ return false;
+ }
+ $resource_type = $_params['resource_type'];
+ $php_resource = $_params['php_resource'];
+
+
+ if ($resource_type == 'file') {
+ $smarty->_include($php_resource, true);
+ } else {
+ $smarty->_eval($php_resource);
+ }
+ }
+
+ $function_name = $smarty->_plugins['insert'][$name][0];
+ if (empty($args['assign'])) {
+ $replace = $function_name($args, $smarty);
+ } else {
+ $smarty->assign($args['assign'], $function_name($args, $smarty));
+ $replace = '';
+ }
+
+ $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $smarty->_smarty_debug_info[] = array('type' => 'insert',
+ 'filename' => 'insert_'.$name,
+ 'depth' => $smarty->_inclusion_depth,
+ 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
+ }
+ }
+
+ return $params['results'];
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace nocache-tags by results of the corresponding non-cacheable
+ * functions and return it
+ *
+ * @param string $compiled_tpl
+ * @param string $cached_source
+ * @return string
+ */
+
+function smarty_core_process_compiled_include($params, &$smarty)
+{
+ $_cache_including = $smarty->_cache_including;
+ $smarty->_cache_including = true;
+
+ $_return = $params['results'];
+
+ foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
+ $smarty->_include($_include_file_path, true);
+ }
+
+ foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
+ $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
+ array(&$smarty, '_process_compiled_include_callback'),
+ $_return);
+ }
+ $smarty->_cache_including = $_cache_including;
+ return $_return;
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * read a cache file, determine if it needs to be
+ * regenerated or not
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return boolean
+ */
+
+// $tpl_file, $cache_id, $compile_id, &$results
+
+function smarty_core_read_cache_file(&$params, &$smarty)
+{
+ static $content_cache = array();
+
+ if ($smarty->force_compile) {
+ // force compile enabled, always regenerate
+ return false;
+ }
+
+ if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
+ list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
+ return true;
+ }
+
+ if (!empty($smarty->cache_handler_func)) {
+ // use cache_handler function
+ call_user_func_array($smarty->cache_handler_func,
+ array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+ } else {
+ // use local cache file
+ $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+ $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+ $params['results'] = $smarty->_read_file($_cache_file);
+ }
+
+ if (empty($params['results'])) {
+ // nothing to parse (error?), regenerate cache
+ return false;
+ }
+
+ $_contents = $params['results'];
+ $_info_start = strpos($_contents, "\n") + 1;
+ $_info_len = (int)substr($_contents, 0, $_info_start - 1);
+ $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
+ $params['results'] = substr($_contents, $_info_start + $_info_len);
+
+ if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
+ // caching by expiration time
+ if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
+ // cache expired, regenerate
+ return false;
+ }
+ } else {
+ // caching by lifetime
+ if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
+ // cache expired, regenerate
+ return false;
+ }
+ }
+
+ if ($smarty->compile_check) {
+ $_params = array('get_source' => false, 'quiet'=>true);
+ foreach (array_keys($_cache_info['template']) as $_template_dep) {
+ $_params['resource_name'] = $_template_dep;
+ if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+ // template file has changed, regenerate cache
+ return false;
+ }
+ }
+
+ if (isset($_cache_info['config'])) {
+ $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
+ foreach (array_keys($_cache_info['config']) as $_config_dep) {
+ $_params['resource_name'] = $_config_dep;
+ if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+ // config file has changed, regenerate cache
+ return false;
+ }
+ }
+ }
+ }
+
+ $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
+
+ $smarty->_cache_info = $_cache_info;
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete an automagically created file by name and id
+ *
+ * @param string $auto_base
+ * @param string $auto_source
+ * @param string $auto_id
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
+
+function smarty_core_rm_auto($params, &$smarty)
+{
+ if (!@is_dir($params['auto_base']))
+ return false;
+
+ if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
+ $_params = array(
+ 'dirname' => $params['auto_base'],
+ 'level' => 0,
+ 'exp_time' => $params['exp_time']
+ );
+ require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+ $_res = smarty_core_rmdir($_params, $smarty);
+ } else {
+ $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
+
+ if(isset($params['auto_source'])) {
+ if (isset($params['extensions'])) {
+ $_res = false;
+ foreach ((array)$params['extensions'] as $_extension)
+ $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
+ } else {
+ $_res = $smarty->_unlink($_tname, $params['exp_time']);
+ }
+ } elseif ($smarty->use_sub_dirs) {
+ $_params = array(
+ 'dirname' => $_tname,
+ 'level' => 1,
+ 'exp_time' => $params['exp_time']
+ );
+ require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+ $_res = smarty_core_rmdir($_params, $smarty);
+ } else {
+ // remove matching file names
+ $_handle = opendir($params['auto_base']);
+ $_res = true;
+ while (false !== ($_filename = readdir($_handle))) {
+ if($_filename == '.' || $_filename == '..') {
+ continue;
+ } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
+ $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
+ }
+ }
+ }
+ }
+
+ return $_res;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete a dir recursively (level=0 -> keep root)
+ * WARNING: no tests, it will try to remove what you tell it!
+ *
+ * @param string $dirname
+ * @param integer $level
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+// $dirname, $level = 1, $exp_time = null
+
+function smarty_core_rmdir($params, &$smarty)
+{
+ if(!isset($params['level'])) { $params['level'] = 1; }
+ if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
+
+ if($_handle = @opendir($params['dirname'])) {
+
+ while (false !== ($_entry = readdir($_handle))) {
+ if ($_entry != '.' && $_entry != '..') {
+ if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
+ $_params = array(
+ 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
+ 'level' => $params['level'] + 1,
+ 'exp_time' => $params['exp_time']
+ );
+ smarty_core_rmdir($_params, $smarty);
+ }
+ else {
+ $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
+ }
+ }
+ }
+ closedir($_handle);
+ }
+
+ if ($params['level']) {
+ return @rmdir($params['dirname']);
+ }
+ return (bool)$_handle;
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Handle insert tags
+ *
+ * @param array $args
+ * @return string
+ */
+function smarty_core_run_insert_handler($params, &$smarty)
+{
+
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ if ($smarty->debugging) {
+ $_params = array();
+ $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+ }
+
+ if ($smarty->caching) {
+ $_arg_string = serialize($params['args']);
+ $_name = $params['args']['name'];
+ if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
+ $smarty->_cache_info['insert_tags'][$_name] = array('insert',
+ $_name,
+ $smarty->_plugins['insert'][$_name][1],
+ $smarty->_plugins['insert'][$_name][2],
+ !empty($params['args']['script']) ? true : false);
+ }
+ return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
+ } else {
+ if (isset($params['args']['script'])) {
+ $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
+ require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+ if(!smarty_core_get_php_resource($_params, $smarty)) {
+ return false;
+ }
+
+ if ($_params['resource_type'] == 'file') {
+ $smarty->_include($_params['php_resource'], true);
+ } else {
+ $smarty->_eval($_params['php_resource']);
+ }
+ unset($params['args']['script']);
+ }
+
+ $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
+ $_content = $_funcname($params['args'], $smarty);
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $smarty->_smarty_debug_info[] = array('type' => 'insert',
+ 'filename' => 'insert_'.$params['args']['name'],
+ 'depth' => $smarty->_inclusion_depth,
+ 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+ }
+
+ if (!empty($params['args']["assign"])) {
+ $smarty->assign($params['args']["assign"], $_content);
+ } else {
+ return $_content;
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * called for included php files within templates
+ *
+ * @param string $smarty_file
+ * @param string $smarty_assign variable to assign the included template's
+ * output into
+ * @param boolean $smarty_once uses include_once if this is true
+ * @param array $smarty_include_vars associative array of vars from
+ * {include file="blah" var=$var}
+ */
+
+// $file, $assign, $once, $_smarty_include_vars
+
+function smarty_core_smarty_include_php($params, &$smarty)
+{
+ $_params = array('resource_name' => $params['smarty_file']);
+ require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+ smarty_core_get_php_resource($_params, $smarty);
+ $_smarty_resource_type = $_params['resource_type'];
+ $_smarty_php_resource = $_params['php_resource'];
+
+ if (!empty($params['smarty_assign'])) {
+ ob_start();
+ if ($_smarty_resource_type == 'file') {
+ $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+ } else {
+ $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+ }
+ $smarty->assign($params['smarty_assign'], ob_get_contents());
+ ob_end_clean();
+ } else {
+ if ($_smarty_resource_type == 'file') {
+ $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+ } else {
+ $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+ }
+ }
+}
+
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Prepend the cache information to the cache file
+ * and write it
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return true|null
+ */
+
+ // $tpl_file, $cache_id, $compile_id, $results
+
+function smarty_core_write_cache_file($params, &$smarty)
+{
+
+ // put timestamp in cache header
+ $smarty->_cache_info['timestamp'] = time();
+ if ($smarty->cache_lifetime > -1){
+ // expiration set
+ $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
+ } else {
+ // cache will never expire
+ $smarty->_cache_info['expires'] = -1;
+ }
+
+ // collapse nocache.../nocache-tags
+ if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
+ // remove everything between every pair of outermost noache.../nocache-tags
+ // and replace it by a single nocache-tag
+ // this new nocache-tag will be replaced by dynamic contents in
+ // smarty_core_process_compiled_includes() on a cache-read
+
+ $match_count = count($match[0]);
+ $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
+
+ $level = 0;
+ $j = 0;
+ for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
+ if ($results[$i] == $match[0][$j]) {
+ // nocache tag
+ if ($match[1][$j]) { // closing tag
+ $level--;
+ unset($results[$i]);
+ } else { // opening tag
+ if ($level++ > 0) unset($results[$i]);
+ }
+ $j++;
+ } elseif ($level > 0) {
+ unset($results[$i]);
+ }
+ }
+ $params['results'] = implode('', $results);
+ }
+ $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
+
+ // prepend the cache header info into cache file
+ $_cache_info = serialize($smarty->_cache_info);
+ $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
+
+ if (!empty($smarty->cache_handler_func)) {
+ // use cache_handler function
+ call_user_func_array($smarty->cache_handler_func,
+ array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
+ } else {
+ // use local cache file
+
+ if(!@is_writable($smarty->cache_dir)) {
+ // cache_dir not writable, see if it exists
+ if(!@is_dir($smarty->cache_dir)) {
+ $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+ return false;
+ }
+ $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
+ return false;
+ }
+
+ $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+ $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+ $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
+ require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+ smarty_core_write_file($_params, $smarty);
+ return true;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Extract non-cacheable parts out of compiled template and write it
+ *
+ * @param string $compile_path
+ * @param string $template_compiled
+ * @return boolean
+ */
+
+function smarty_core_write_compiled_include($params, &$smarty)
+{
+ $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
+ $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
+
+ preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
+ $params['compiled_content'], $_match_source, PREG_SET_ORDER);
+
+ // no nocache-parts found: done
+ if (count($_match_source)==0) return;
+
+ // convert the matched php-code to functions
+ $_include_compiled = "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+ $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
+
+ $_compile_path = $params['include_file_path'];
+
+ $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
+ $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
+
+ $_include_compiled .= $params['plugins_code'];
+ $_include_compiled .= "<?php";
+
+ $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
+ for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
+ $_match =& $_match_source[$_i];
+ $source = $_match[4];
+ if ($this_varname == '_smarty') {
+ /* rename $this to $_smarty in the sourcecode */
+ $tokens = token_get_all('<?php ' . $_match[4]);
+
+ /* remove trailing <?php */
+ $open_tag = '';
+ while ($tokens) {
+ $token = array_shift($tokens);
+ if (is_array($token)) {
+ $open_tag .= $token[1];
+ } else {
+ $open_tag .= $token;
+ }
+ if ($open_tag == '<?php ') break;
+ }
+
+ for ($i=0, $count = count($tokens); $i < $count; $i++) {
+ if (is_array($tokens[$i])) {
+ if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
+ $tokens[$i] = '$' . $this_varname;
+ } else {
+ $tokens[$i] = $tokens[$i][1];
+ }
+ }
+ }
+ $source = implode('', $tokens);
+ }
+
+ /* add function to compiled include */
+ $_include_compiled .= "
+function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
+{
+$source
+}
+
+";
+ }
+ $_include_compiled .= "\n\n?>\n";
+
+ $_params = array('filename' => $_compile_path,
+ 'contents' => $_include_compiled, 'create_dirs' => true);
+
+ require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+ smarty_core_write_file($_params, $smarty);
+ return true;
+}
+
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write the compiled resource
+ *
+ * @param string $compile_path
+ * @param string $compiled_content
+ * @return true
+ */
+function smarty_core_write_compiled_resource($params, &$smarty)
+{
+ if(!@is_writable($smarty->compile_dir)) {
+ // compile_dir not writable, see if it exists
+ if(!@is_dir($smarty->compile_dir)) {
+ $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+ return false;
+ }
+ $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
+ return false;
+ }
+
+ $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
+ require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+ smarty_core_write_file($_params, $smarty);
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write out a file to disk
+ *
+ * @param string $filename
+ * @param string $contents
+ * @param boolean $create_dirs
+ * @return boolean
+ */
+function smarty_core_write_file($params, &$smarty)
+{
+ $_dirname = dirname($params['filename']);
+
+ if ($params['create_dirs']) {
+ $_params = array('dir' => $_dirname);
+ require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
+ smarty_core_create_dir_structure($_params, $smarty);
+ }
+
+ // write to tmp file, then rename it to avoid file locking race condition
+ $_tmp_file = tempnam($_dirname, 'wrt');
+
+ if (!($fd = @fopen($_tmp_file, 'wb'))) {
+ $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
+ if (!($fd = @fopen($_tmp_file, 'wb'))) {
+ $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
+ return false;
+ }
+ }
+
+ fwrite($fd, $params['contents']);
+ fclose($fd);
+
+ if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
+ // On platforms and filesystems that cannot overwrite with rename()
+ // delete the file before renaming it -- because windows always suffers
+ // this, it is short-circuited to avoid the initial rename() attempt
+ @unlink($params['filename']);
+ @rename($_tmp_file, $params['filename']);
+ }
+ @chmod($params['filename'], $smarty->_file_perms);
+
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {textformat}{/textformat} block plugin
+ *
+ * Type: block function<br>
+ * Name: textformat<br>
+ * Purpose: format text a certain way with preset styles
+ * or custom wrap/indent settings<br>
+ * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
+ * (Smarty online manual)
+ * @param array
+ * <pre>
+ * Params: style: string (email)
+ * indent: integer (0)
+ * wrap: integer (80)
+ * wrap_char string ("\n")
+ * indent_char: string (" ")
+ * wrap_boundary: boolean (true)
+ * </pre>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string contents of the block
+ * @param Smarty clever simulation of a method
+ * @return string string $content re-formatted
+ */
+function smarty_block_textformat($params, $content, &$smarty)
+{
+ if (is_null($content)) {
+ return;
+ }
+
+ $style = null;
+ $indent = 0;
+ $indent_first = 0;
+ $indent_char = ' ';
+ $wrap = 80;
+ $wrap_char = "\n";
+ $wrap_cut = false;
+ $assign = null;
+
+ foreach ($params as $_key => $_val) {
+ switch ($_key) {
+ case 'style':
+ case 'indent_char':
+ case 'wrap_char':
+ case 'assign':
+ $$_key = (string)$_val;
+ break;
+
+ case 'indent':
+ case 'indent_first':
+ case 'wrap':
+ $$_key = (int)$_val;
+ break;
+
+ case 'wrap_cut':
+ $$_key = (bool)$_val;
+ break;
+
+ default:
+ $smarty->trigger_error("textformat: unknown attribute '$_key'");
+ }
+ }
+
+ if ($style == 'email') {
+ $wrap = 72;
+ }
+
+ // split into paragraphs
+ $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
+ $_output = '';
+
+ for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
+ if ($_paragraphs[$_x] == '') {
+ continue;
+ }
+ // convert mult. spaces & special chars to single space
+ $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
+ // indent first line
+ if($indent_first > 0) {
+ $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
+ }
+ // wordwrap sentences
+ $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
+ // indent lines
+ if($indent > 0) {
+ $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
+ }
+ }
+ $_output = implode($wrap_char . $wrap_char, $_paragraphs);
+
+ return $assign ? $smarty->assign($assign, $_output) : $_output;
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign} compiler function plugin
+ *
+ * Type: compiler function<br>
+ * Name: assign<br>
+ * Purpose: assign a value to a template variable
+ * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> (initial author)
+ * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
+ * @param string containing var-attribute and value-attribute
+ * @param Smarty_Compiler
+ */
+function smarty_compiler_assign($tag_attrs, &$compiler)
+{
+ $_params = $compiler->_parse_attrs($tag_attrs);
+
+ if (!isset($_params['var'])) {
+ $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
+ return;
+ }
+
+ if (!isset($_params['value'])) {
+ $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
+ return;
+ }
+
+ return "\$this->assign({$_params['var']}, {$_params['value']});";
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign_debug_info} function plugin
+ *
+ * Type: function<br>
+ * Name: assign_debug_info<br>
+ * Purpose: assign debug info to the template<br>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
+ * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
+ * @param Smarty
+ */
+function smarty_function_assign_debug_info($params, &$smarty)
+{
+ $assigned_vars = $smarty->_tpl_vars;
+ ksort($assigned_vars);
+ if (@is_array($smarty->_config[0])) {
+ $config_vars = $smarty->_config[0];
+ ksort($config_vars);
+ $smarty->assign("_debug_config_keys", array_keys($config_vars));
+ $smarty->assign("_debug_config_vals", array_values($config_vars));
+ }
+
+ $included_templates = $smarty->_smarty_debug_info;
+
+ $smarty->assign("_debug_keys", array_keys($assigned_vars));
+ $smarty->assign("_debug_vals", array_values($assigned_vars));
+
+ $smarty->assign("_debug_tpls", $included_templates);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {config_load} function plugin
+ *
+ * Type: function<br>
+ * Name: config_load<br>
+ * Purpose: load config file vars
+ * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
+ * @param array Format:
+ * <pre>
+ * array('file' => required config file name,
+ * 'section' => optional config file section to load
+ * 'scope' => local/parent/global
+ * 'global' => overrides scope, setting to parent if true)
+ * </pre>
+ * @param Smarty
+ */
+function smarty_function_config_load($params, &$smarty)
+{
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+ }
+
+ $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
+ $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
+ $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
+ $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
+
+ if (!isset($_file) || strlen($_file) == 0) {
+ $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ if (isset($_scope)) {
+ if ($_scope != 'local' &&
+ $_scope != 'parent' &&
+ $_scope != 'global') {
+ $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ } else {
+ if ($_global) {
+ $_scope = 'parent';
+ } else {
+ $_scope = 'local';
+ }
+ }
+
+ $_params = array('resource_name' => $_file,
+ 'resource_base_path' => $smarty->config_dir,
+ 'get_source' => false);
+ $smarty->_parse_resource_name($_params);
+ $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
+ if (isset($_section))
+ $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
+ else
+ $_compile_file = $smarty->_get_compile_path($_file_path);
+
+ if($smarty->force_compile || !file_exists($_compile_file)) {
+ $_compile = true;
+ } elseif ($smarty->compile_check) {
+ $_params = array('resource_name' => $_file,
+ 'resource_base_path' => $smarty->config_dir,
+ 'get_source' => false);
+ $_compile = $smarty->_fetch_resource_info($_params) &&
+ $_params['resource_timestamp'] > filemtime($_compile_file);
+ } else {
+ $_compile = false;
+ }
+
+ if($_compile) {
+ // compile config file
+ if(!is_object($smarty->_conf_obj)) {
+ require_once SMARTY_DIR . $smarty->config_class . '.class.php';
+ $smarty->_conf_obj = new $smarty->config_class();
+ $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
+ $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
+ $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
+ $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
+ }
+
+ $_params = array('resource_name' => $_file,
+ 'resource_base_path' => $smarty->config_dir,
+ $_params['get_source'] = true);
+ if (!$smarty->_fetch_resource_info($_params)) {
+ return;
+ }
+ $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
+ $_config_vars = array_merge($smarty->_conf_obj->get($_file),
+ $smarty->_conf_obj->get($_file, $_section));
+ if(function_exists('var_export')) {
+ $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
+ } else {
+ $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
+ }
+ $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
+ require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+ smarty_core_write_compiled_resource($_params, $smarty);
+ } else {
+ include($_compile_file);
+ }
+
+ if ($smarty->caching) {
+ $smarty->_cache_info['config'][$_file] = true;
+ }
+
+ $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
+ $smarty->_config[0]['files'][$_file] = true;
+
+ if ($_scope == 'parent') {
+ $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
+ $smarty->_config[1]['files'][$_file] = true;
+ } else if ($_scope == 'global') {
+ for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
+ $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
+ $smarty->_config[$i]['files'][$_file] = true;
+ }
+ }
+
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+ $smarty->_smarty_debug_info[] = array('type' => 'config',
+ 'filename' => $_file.' ['.$_section.'] '.$_scope,
+ 'depth' => $smarty->_inclusion_depth,
+ 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+ }
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {counter} function plugin
+ *
+ * Type: function<br>
+ * Name: counter<br>
+ * Purpose: print out a counter value
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
+ * (Smarty online manual)
+ * @param array parameters
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_counter($params, &$smarty)
+{
+ static $counters = array();
+
+ $name = (isset($params['name'])) ? $params['name'] : 'default';
+ if (!isset($counters[$name])) {
+ $counters[$name] = array(
+ 'start'=>1,
+ 'skip'=>1,
+ 'direction'=>'up',
+ 'count'=>1
+ );
+ }
+ $counter =& $counters[$name];
+
+ if (isset($params['start'])) {
+ $counter['start'] = $counter['count'] = (int)$params['start'];
+ }
+
+ if (!empty($params['assign'])) {
+ $counter['assign'] = $params['assign'];
+ }
+
+ if (isset($counter['assign'])) {
+ $smarty->assign($counter['assign'], $counter['count']);
+ }
+
+ if (isset($params['print'])) {
+ $print = (bool)$params['print'];
+ } else {
+ $print = empty($counter['assign']);
+ }
+
+ if ($print) {
+ $retval = $counter['count'];
+ } else {
+ $retval = null;
+ }
+
+ if (isset($params['skip'])) {
+ $counter['skip'] = $params['skip'];
+ }
+
+ if (isset($params['direction'])) {
+ $counter['direction'] = $params['direction'];
+ }
+
+ if ($counter['direction'] == "down")
+ $counter['count'] -= $counter['skip'];
+ else
+ $counter['count'] += $counter['skip'];
+
+ return $retval;
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {cycle} function plugin
+ *
+ * Type: function<br>
+ * Name: cycle<br>
+ * Date: May 3, 2002<br>
+ * Purpose: cycle through given values<br>
+ * Input:
+ * - name = name of cycle (optional)
+ * - values = comma separated list of values to cycle,
+ * or an array of values to cycle
+ * (this can be left out for subsequent calls)
+ * - reset = boolean - resets given var to true
+ * - print = boolean - print var or not. default is true
+ * - advance = boolean - whether or not to advance the cycle
+ * - delimiter = the value delimiter, default is ","
+ * - assign = boolean, assigns to template var instead of
+ * printed.
+ *
+ * Examples:<br>
+ * <pre>
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Mark Priatel <mpriatel@rogers.com>
+ * @author credit to Gerard <gerard@interfold.com>
+ * @author credit to Jason Sweat <jsweat_php@yahoo.com>
+ * @version 1.3
+ * @param array
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_cycle($params, &$smarty)
+{
+ static $cycle_vars;
+
+ $name = (empty($params['name'])) ? 'default' : $params['name'];
+ $print = (isset($params['print'])) ? (bool)$params['print'] : true;
+ $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
+ $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
+
+ if (!in_array('values', array_keys($params))) {
+ if(!isset($cycle_vars[$name]['values'])) {
+ $smarty->trigger_error("cycle: missing 'values' parameter");
+ return;
+ }
+ } else {
+ if(isset($cycle_vars[$name]['values'])
+ && $cycle_vars[$name]['values'] != $params['values'] ) {
+ $cycle_vars[$name]['index'] = 0;
+ }
+ $cycle_vars[$name]['values'] = $params['values'];
+ }
+
+ $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
+
+ if(is_array($cycle_vars[$name]['values'])) {
+ $cycle_array = $cycle_vars[$name]['values'];
+ } else {
+ $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
+ }
+
+ if(!isset($cycle_vars[$name]['index']) || $reset ) {
+ $cycle_vars[$name]['index'] = 0;
+ }
+
+ if (isset($params['assign'])) {
+ $print = false;
+ $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
+ }
+
+ if($print) {
+ $retval = $cycle_array[$cycle_vars[$name]['index']];
+ } else {
+ $retval = null;
+ }
+
+ if($advance) {
+ if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
+ $cycle_vars[$name]['index'] = 0;
+ } else {
+ $cycle_vars[$name]['index']++;
+ }
+ }
+
+ return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {debug} function plugin
+ *
+ * Type: function<br>
+ * Name: debug<br>
+ * Date: July 1, 2002<br>
+ * Purpose: popup debug window
+ * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string output from {@link Smarty::_generate_debug_output()}
+ */
+function smarty_function_debug($params, &$smarty)
+{
+ if (isset($params['output'])) {
+ $smarty->assign('_smarty_debug_output', $params['output']);
+ }
+ require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+ return smarty_core_display_debug_console(null, $smarty);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {eval} function plugin
+ *
+ * Type: function<br>
+ * Name: eval<br>
+ * Purpose: evaluate a template variable as a template<br>
+ * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ */
+function smarty_function_eval($params, &$smarty)
+{
+
+ if (!isset($params['var'])) {
+ $smarty->trigger_error("eval: missing 'var' parameter");
+ return;
+ }
+
+ if($params['var'] == '') {
+ return;
+ }
+
+ $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
+
+ ob_start();
+ $smarty->_eval('?>' . $_var_compiled);
+ $_contents = ob_get_contents();
+ ob_end_clean();
+
+ if (!empty($params['assign'])) {
+ $smarty->assign($params['assign'], $_contents);
+ } else {
+ return $_contents;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {fetch} plugin
+ *
+ * Type: function<br>
+ * Name: fetch<br>
+ * Purpose: fetch file, web or ftp data and display results
+ * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string|null if the assign parameter is passed, Smarty assigns the
+ * result to a template variable
+ */
+function smarty_function_fetch($params, &$smarty)
+{
+ if (empty($params['file'])) {
+ $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
+ return;
+ }
+
+ $content = '';
+ if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
+ $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
+ require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+ if(!smarty_core_is_secure($_params, $smarty)) {
+ $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
+ return;
+ }
+
+ // fetch the file
+ if($fp = @fopen($params['file'],'r')) {
+ while(!feof($fp)) {
+ $content .= fgets ($fp,4096);
+ }
+ fclose($fp);
+ } else {
+ $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
+ return;
+ }
+ } else {
+ // not a local file
+ if(preg_match('!^http://!i',$params['file'])) {
+ // http fetch
+ if($uri_parts = parse_url($params['file'])) {
+ // set defaults
+ $host = $server_name = $uri_parts['host'];
+ $timeout = 30;
+ $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
+ $agent = "Smarty Template Engine ".$smarty->_version;
+ $referer = "";
+ $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
+ $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
+ $_is_proxy = false;
+ if(empty($uri_parts['port'])) {
+ $port = 80;
+ } else {
+ $port = $uri_parts['port'];
+ }
+ if(!empty($uri_parts['user'])) {
+ $user = $uri_parts['user'];
+ }
+ if(!empty($uri_parts['pass'])) {
+ $pass = $uri_parts['pass'];
+ }
+ // loop through parameters, setup headers
+ foreach($params as $param_key => $param_value) {
+ switch($param_key) {
+ case "file":
+ case "assign":
+ case "assign_headers":
+ break;
+ case "user":
+ if(!empty($param_value)) {
+ $user = $param_value;
+ }
+ break;
+ case "pass":
+ if(!empty($param_value)) {
+ $pass = $param_value;
+ }
+ break;
+ case "accept":
+ if(!empty($param_value)) {
+ $accept = $param_value;
+ }
+ break;
+ case "header":
+ if(!empty($param_value)) {
+ if(!preg_match('![\w\d-]+: .+!',$param_value)) {
+ $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
+ return;
+ } else {
+ $extra_headers[] = $param_value;
+ }
+ }
+ break;
+ case "proxy_host":
+ if(!empty($param_value)) {
+ $proxy_host = $param_value;
+ }
+ break;
+ case "proxy_port":
+ if(!preg_match('!\D!', $param_value)) {
+ $proxy_port = (int) $param_value;
+ } else {
+ $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+ return;
+ }
+ break;
+ case "agent":
+ if(!empty($param_value)) {
+ $agent = $param_value;
+ }
+ break;
+ case "referer":
+ if(!empty($param_value)) {
+ $referer = $param_value;
+ }
+ break;
+ case "timeout":
+ if(!preg_match('!\D!', $param_value)) {
+ $timeout = (int) $param_value;
+ } else {
+ $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+ return;
+ }
+ break;
+ default:
+ $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
+ return;
+ }
+ }
+ if(!empty($proxy_host) && !empty($proxy_port)) {
+ $_is_proxy = true;
+ $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
+ } else {
+ $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
+ }
+
+ if(!$fp) {
+ $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
+ return;
+ } else {
+ if($_is_proxy) {
+ fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
+ } else {
+ fputs($fp, "GET $uri HTTP/1.0\r\n");
+ }
+ if(!empty($host)) {
+ fputs($fp, "Host: $host\r\n");
+ }
+ if(!empty($accept)) {
+ fputs($fp, "Accept: $accept\r\n");
+ }
+ if(!empty($agent)) {
+ fputs($fp, "User-Agent: $agent\r\n");
+ }
+ if(!empty($referer)) {
+ fputs($fp, "Referer: $referer\r\n");
+ }
+ if(isset($extra_headers) && is_array($extra_headers)) {
+ foreach($extra_headers as $curr_header) {
+ fputs($fp, $curr_header."\r\n");
+ }
+ }
+ if(!empty($user) && !empty($pass)) {
+ fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
+ }
+
+ fputs($fp, "\r\n");
+ while(!feof($fp)) {
+ $content .= fgets($fp,4096);
+ }
+ fclose($fp);
+ $csplit = split("\r\n\r\n",$content,2);
+
+ $content = $csplit[1];
+
+ if(!empty($params['assign_headers'])) {
+ $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
+ }
+ }
+ } else {
+ $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
+ return;
+ }
+ } else {
+ // ftp fetch
+ if($fp = @fopen($params['file'],'r')) {
+ while(!feof($fp)) {
+ $content .= fgets ($fp,4096);
+ }
+ fclose($fp);
+ } else {
+ $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
+ return;
+ }
+ }
+
+ }
+
+
+ if (!empty($params['assign'])) {
+ $smarty->assign($params['assign'],$content);
+ } else {
+ return $content;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_checkboxes} function plugin
+ *
+ * File: function.html_checkboxes.php<br>
+ * Type: function<br>
+ * Name: html_checkboxes<br>
+ * Date: 24.Feb.2003<br>
+ * Purpose: Prints out a list of checkbox input types<br>
+ * Input:<br>
+ * - name (optional) - string default "checkbox"
+ * - values (required) - array
+ * - options (optional) - associative array
+ * - checked (optional) - array default not set
+ * - separator (optional) - ie <br> or
+ * - output (optional) - the output next to each checkbox
+ * - assign (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
+ * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ * (Smarty online manual)
+ * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_checkboxes($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $name = 'checkbox';
+ $values = null;
+ $options = null;
+ $selected = null;
+ $separator = '';
+ $labels = true;
+ $output = null;
+
+ $extra = '';
+
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'name':
+ case 'separator':
+ $$_key = $_val;
+ break;
+
+ case 'labels':
+ $$_key = (bool)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'checked':
+ case 'selected':
+ $selected = array_map('strval', array_values((array)$_val));
+ break;
+
+ case 'checkboxes':
+ $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+ $options = (array)$_val;
+ break;
+
+ case 'assign':
+ break;
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values))
+ return ''; /* raise error here? */
+
+ settype($selected, 'array');
+ $_html_result = array();
+
+ if (isset($options)) {
+
+ foreach ($options as $_key=>$_val)
+ $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+
+
+ } else {
+ foreach ($values as $_i=>$_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+ }
+
+ }
+
+ if(!empty($params['assign'])) {
+ $smarty->assign($params['assign'], $_html_result);
+ } else {
+ return implode("\n",$_html_result);
+ }
+
+}
+
+function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
+ $_output = '';
+ if ($labels) $_output .= '<label>';
+ $_output .= '<input type="checkbox" name="'
+ . smarty_function_escape_special_chars($name) . '[]" value="'
+ . smarty_function_escape_special_chars($value) . '"';
+
+ if (in_array((string)$value, $selected)) {
+ $_output .= ' checked="checked"';
+ }
+ $_output .= $extra . ' />' . $output;
+ if ($labels) $_output .= '</label>';
+ $_output .= $separator;
+
+ return $_output;
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_image} function plugin
+ *
+ * Type: function<br>
+ * Name: html_image<br>
+ * Date: Feb 24, 2003<br>
+ * Purpose: format HTML tags for the image<br>
+ * Input:<br>
+ * - file = file (and path) of image (required)
+ * - height = image height (optional, default actual height)
+ * - width = image width (optional, default actual width)
+ * - basedir = base directory for absolute paths, default
+ * is environment variable DOCUMENT_ROOT
+ * - path_prefix = prefix for path output (optional, default empty)
+ *
+ * Examples: {html_image file="/images/masthead.gif"}
+ * Output: <img src="/images/masthead.gif" width=400 height=23>
+ * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Duda <duda@big.hu> - wrote first image function
+ * in repository, helped with lots of functionality
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_image($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $alt = '';
+ $file = '';
+ $height = '';
+ $width = '';
+ $extra = '';
+ $prefix = '';
+ $suffix = '';
+ $path_prefix = '';
+ $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+ $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'file':
+ case 'height':
+ case 'width':
+ case 'dpi':
+ case 'path_prefix':
+ case 'basedir':
+ $$_key = $_val;
+ break;
+
+ case 'alt':
+ if(!is_array($_val)) {
+ $$_key = smarty_function_escape_special_chars($_val);
+ } else {
+ $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+
+ case 'link':
+ case 'href':
+ $prefix = '<a href="' . $_val . '">';
+ $suffix = '</a>';
+ break;
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (empty($file)) {
+ $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
+ return;
+ }
+
+ if (substr($file,0,1) == '/') {
+ $_image_path = $basedir . $file;
+ } else {
+ $_image_path = $file;
+ }
+
+ if(!isset($params['width']) || !isset($params['height'])) {
+ if(!$_image_data = @getimagesize($_image_path)) {
+ if(!file_exists($_image_path)) {
+ $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
+ return;
+ } else if(!is_readable($_image_path)) {
+ $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
+ return;
+ } else {
+ $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
+ return;
+ }
+ }
+ if ($smarty->security &&
+ ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
+ (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
+ (!smarty_core_is_secure($_params, $smarty)) ) {
+ $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
+ }
+
+ if(!isset($params['width'])) {
+ $width = $_image_data[0];
+ }
+ if(!isset($params['height'])) {
+ $height = $_image_data[1];
+ }
+
+ }
+
+ if(isset($params['dpi'])) {
+ if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
+ $dpi_default = 72;
+ } else {
+ $dpi_default = 96;
+ }
+ $_resize = $dpi_default/$params['dpi'];
+ $width = round($width * $_resize);
+ $height = round($height * $_resize);
+ }
+
+ return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_options} function plugin
+ *
+ * Type: function<br>
+ * Name: html_options<br>
+ * Input:<br>
+ * - name (optional) - string default "select"
+ * - values (required if no options supplied) - array
+ * - options (required if no values supplied) - associative array
+ * - selected (optional) - string default not set
+ * - output (required if not options supplied) - array
+ * Purpose: Prints the list of <option> tags generated from
+ * the passed parameters
+ * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_options($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $name = null;
+ $values = null;
+ $options = null;
+ $selected = array();
+ $output = null;
+
+ $extra = '';
+
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'name':
+ $$_key = (string)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'selected':
+ $$_key = array_map('strval', array_values((array)$_val));
+ break;
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values))
+ return ''; /* raise error here? */
+
+ $_html_result = '';
+
+ if (isset($options)) {
+
+ foreach ($options as $_key=>$_val)
+ $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+
+ } else {
+
+ foreach ($values as $_i=>$_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+ }
+
+ }
+
+ if(!empty($name)) {
+ $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
+ }
+
+ return $_html_result;
+
+}
+
+function smarty_function_html_options_optoutput($key, $value, $selected) {
+ if(!is_array($value)) {
+ $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
+ smarty_function_escape_special_chars($key) . '"';
+ if (in_array((string)$key, $selected))
+ $_html_result .= ' selected="selected"';
+ $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
+ } else {
+ $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
+ }
+ return $_html_result;
+}
+
+function smarty_function_html_options_optgroup($key, $values, $selected) {
+ $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
+ foreach ($values as $key => $value) {
+ $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
+ }
+ $optgroup_html .= "</optgroup>\n";
+ return $optgroup_html;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_radios} function plugin
+ *
+ * File: function.html_radios.php<br>
+ * Type: function<br>
+ * Name: html_radios<br>
+ * Date: 24.Feb.2003<br>
+ * Purpose: Prints out a list of radio input types<br>
+ * Input:<br>
+ * - name (optional) - string default "radio"
+ * - values (required) - array
+ * - options (optional) - associative array
+ * - checked (optional) - array default not set
+ * - separator (optional) - ie <br> or
+ * - output (optional) - the output next to each radio button
+ * - assign (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_radios values=$ids output=$names}
+ * {html_radios values=$ids name='box' separator='<br>' output=$names}
+ * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ * (Smarty online manual)
+ * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_radios($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $name = 'radio';
+ $values = null;
+ $options = null;
+ $selected = null;
+ $separator = '';
+ $labels = true;
+ $label_ids = false;
+ $output = null;
+ $extra = '';
+
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'name':
+ case 'separator':
+ $$_key = (string)$_val;
+ break;
+
+ case 'checked':
+ case 'selected':
+ if(is_array($_val)) {
+ $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+ } else {
+ $selected = (string)$_val;
+ }
+ break;
+
+ case 'labels':
+ case 'label_ids':
+ $$_key = (bool)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'radios':
+ $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+ $options = (array)$_val;
+ break;
+
+ case 'assign':
+ break;
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values))
+ return ''; /* raise error here? */
+
+ $_html_result = array();
+
+ if (isset($options)) {
+
+ foreach ($options as $_key=>$_val)
+ $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+
+ } else {
+
+ foreach ($values as $_i=>$_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+ }
+
+ }
+
+ if(!empty($params['assign'])) {
+ $smarty->assign($params['assign'], $_html_result);
+ } else {
+ return implode("\n",$_html_result);
+ }
+
+}
+
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
+ $_output = '';
+ if ($labels) {
+ if($label_ids) {
+ $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
+ $_output .= '<label for="' . $_id . '">';
+ } else {
+ $_output .= '<label>';
+ }
+ }
+ $_output .= '<input type="radio" name="'
+ . smarty_function_escape_special_chars($name) . '" value="'
+ . smarty_function_escape_special_chars($value) . '"';
+
+ if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
+
+ if ((string)$value==$selected) {
+ $_output .= ' checked="checked"';
+ }
+ $_output .= $extra . ' />' . $output;
+ if ($labels) $_output .= '</label>';
+ $_output .= $separator;
+
+ return $_output;
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {html_select_date} plugin
+ *
+ * Type: function<br>
+ * Name: html_select_date<br>
+ * Purpose: Prints the dropdowns for date selection.
+ *
+ * ChangeLog:<br>
+ * - 1.0 initial release
+ * - 1.1 added support for +/- N syntax for begin
+ * and end year values. (Monte)
+ * - 1.2 added support for yyyy-mm-dd syntax for
+ * time value. (Jan Rosier)
+ * - 1.3 added support for choosing format for
+ * month values (Gary Loescher)
+ * - 1.3.1 added support for choosing format for
+ * day values (Marcus Bointon)
+ * - 1.3.2 support negative timestamps, force year
+ * dropdown to include given date unless explicitly set (Monte)
+ * - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
+ * of 0000-00-00 dates (cybot, boots)
+ * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
+ * (Smarty online manual)
+ * @version 1.3.4
+ * @author Andrei Zmievski
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_select_date($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+ require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+ require_once $smarty->_get_plugin_filepath('function','html_options');
+ /* Default values. */
+ $prefix = "Date_";
+ $start_year = strftime("%Y");
+ $end_year = $start_year;
+ $display_days = true;
+ $display_months = true;
+ $display_years = true;
+ $month_format = "%B";
+ /* Write months as numbers by default GL */
+ $month_value_format = "%m";
+ $day_format = "%02d";
+ /* Write day values using this format MB */
+ $day_value_format = "%d";
+ $year_as_text = false;
+ /* Display years in reverse order? Ie. 2000,1999,.... */
+ $reverse_years = false;
+ /* Should the select boxes be part of an array when returned from PHP?
+ e.g. setting it to "birthday", would create "birthday[Day]",
+ "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
+ $field_array = null;
+ /* <select size>'s of the different <select> tags.
+ If not set, uses default dropdown. */
+ $day_size = null;
+ $month_size = null;
+ $year_size = null;
+ /* Unparsed attributes common to *ALL* the <select>/<input> tags.
+ An example might be in the template: all_extra ='class ="foo"'. */
+ $all_extra = null;
+ /* Separate attributes for the tags. */
+ $day_extra = null;
+ $month_extra = null;
+ $year_extra = null;
+ /* Order in which to display the fields.
+ "D" -> day, "M" -> month, "Y" -> year. */
+ $field_order = 'MDY';
+ /* String printed between the different fields. */
+ $field_separator = "\n";
+ $time = time();
+ $all_empty = null;
+ $day_empty = null;
+ $month_empty = null;
+ $year_empty = null;
+ $extra_attrs = '';
+
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'prefix':
+ case 'time':
+ case 'start_year':
+ case 'end_year':
+ case 'month_format':
+ case 'day_format':
+ case 'day_value_format':
+ case 'field_array':
+ case 'day_size':
+ case 'month_size':
+ case 'year_size':
+ case 'all_extra':
+ case 'day_extra':
+ case 'month_extra':
+ case 'year_extra':
+ case 'field_order':
+ case 'field_separator':
+ case 'month_value_format':
+ case 'month_empty':
+ case 'day_empty':
+ case 'year_empty':
+ $$_key = (string)$_value;
+ break;
+
+ case 'all_empty':
+ $$_key = (string)$_value;
+ $day_empty = $month_empty = $year_empty = $all_empty;
+ break;
+
+ case 'display_days':
+ case 'display_months':
+ case 'display_years':
+ case 'year_as_text':
+ case 'reverse_years':
+ $$_key = (bool)$_value;
+ break;
+
+ default:
+ if(!is_array($_value)) {
+ $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
+ } else {
+ $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (preg_match('!^-\d+$!', $time)) {
+ // negative timestamp, use date()
+ $time = date('Y-m-d', $time);
+ }
+ // If $time is not in format yyyy-mm-dd
+ if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
+ $time = $found[1];
+ } else {
+ // use smarty_make_timestamp to get an unix timestamp and
+ // strftime to make yyyy-mm-dd
+ $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
+ }
+ // Now split this in pieces, which later can be used to set the select
+ $time = explode("-", $time);
+
+ // make syntax "+N" or "-N" work with start_year and end_year
+ if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
+ if ($match[1] == '+') {
+ $end_year = strftime('%Y') + $match[2];
+ } else {
+ $end_year = strftime('%Y') - $match[2];
+ }
+ }
+ if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
+ if ($match[1] == '+') {
+ $start_year = strftime('%Y') + $match[2];
+ } else {
+ $start_year = strftime('%Y') - $match[2];
+ }
+ }
+ if (strlen($time[0]) > 0) {
+ if ($start_year > $time[0] && !isset($params['start_year'])) {
+ // force start year to include given date if not explicitly set
+ $start_year = $time[0];
+ }
+ if($end_year < $time[0] && !isset($params['end_year'])) {
+ // force end year to include given date if not explicitly set
+ $end_year = $time[0];
+ }
+ }
+
+ $field_order = strtoupper($field_order);
+
+ $html_result = $month_result = $day_result = $year_result = "";
+
+ $field_separator_count = -1;
+ if ($display_months) {
+ $field_separator_count++;
+ $month_names = array();
+ $month_values = array();
+ if(isset($month_empty)) {
+ $month_names[''] = $month_empty;
+ $month_values[''] = '';
+ }
+ for ($i = 1; $i <= 12; $i++) {
+ $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
+ $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
+ }
+
+ $month_result .= '<select name=';
+ if (null !== $field_array){
+ $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
+ } else {
+ $month_result .= '"' . $prefix . 'Month"';
+ }
+ if (null !== $month_size){
+ $month_result .= ' size="' . $month_size . '"';
+ }
+ if (null !== $month_extra){
+ $month_result .= ' ' . $month_extra;
+ }
+ if (null !== $all_extra){
+ $month_result .= ' ' . $all_extra;
+ }
+ $month_result .= $extra_attrs . '>'."\n";
+
+ $month_result .= smarty_function_html_options(array('output' => $month_names,
+ 'values' => $month_values,
+ 'selected' => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
+ 'print_result' => false),
+ $smarty);
+ $month_result .= '</select>';
+ }
+
+ if ($display_days) {
+ $field_separator_count++;
+ $days = array();
+ if (isset($day_empty)) {
+ $days[''] = $day_empty;
+ $day_values[''] = '';
+ }
+ for ($i = 1; $i <= 31; $i++) {
+ $days[] = sprintf($day_format, $i);
+ $day_values[] = sprintf($day_value_format, $i);
+ }
+
+ $day_result .= '<select name=';
+ if (null !== $field_array){
+ $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
+ } else {
+ $day_result .= '"' . $prefix . 'Day"';
+ }
+ if (null !== $day_size){
+ $day_result .= ' size="' . $day_size . '"';
+ }
+ if (null !== $all_extra){
+ $day_result .= ' ' . $all_extra;
+ }
+ if (null !== $day_extra){
+ $day_result .= ' ' . $day_extra;
+ }
+ $day_result .= $extra_attrs . '>'."\n";
+ $day_result .= smarty_function_html_options(array('output' => $days,
+ 'values' => $day_values,
+ 'selected' => $time[2],
+ 'print_result' => false),
+ $smarty);
+ $day_result .= '</select>';
+ }
+
+ if ($display_years) {
+ $field_separator_count++;
+ if (null !== $field_array){
+ $year_name = $field_array . '[' . $prefix . 'Year]';
+ } else {
+ $year_name = $prefix . 'Year';
+ }
+ if ($year_as_text) {
+ $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
+ if (null !== $all_extra){
+ $year_result .= ' ' . $all_extra;
+ }
+ if (null !== $year_extra){
+ $year_result .= ' ' . $year_extra;
+ }
+ $year_result .= ' />';
+ } else {
+ $years = range((int)$start_year, (int)$end_year);
+ if ($reverse_years) {
+ rsort($years, SORT_NUMERIC);
+ } else {
+ sort($years, SORT_NUMERIC);
+ }
+ $yearvals = $years;
+ if(isset($year_empty)) {
+ array_unshift($years, $year_empty);
+ array_unshift($yearvals, '');
+ }
+ $year_result .= '<select name="' . $year_name . '"';
+ if (null !== $year_size){
+ $year_result .= ' size="' . $year_size . '"';
+ }
+ if (null !== $all_extra){
+ $year_result .= ' ' . $all_extra;
+ }
+ if (null !== $year_extra){
+ $year_result .= ' ' . $year_extra;
+ }
+ $year_result .= $extra_attrs . '>'."\n";
+ $year_result .= smarty_function_html_options(array('output' => $years,
+ 'values' => $yearvals,
+ 'selected' => $time[0],
+ 'print_result' => false),
+ $smarty);
+ $year_result .= '</select>';
+ }
+ }
+
+ // Loop thru the field_order field
+ for ($i = 0; $i <= 2; $i++){
+ $c = substr($field_order, $i, 1);
+ switch ($c){
+ case 'D':
+ $html_result .= $day_result;
+ break;
+
+ case 'M':
+ $html_result .= $month_result;
+ break;
+
+ case 'Y':
+ $html_result .= $year_result;
+ break;
+ }
+ // Add the field seperator
+ if($i < $field_separator_count) {
+ $html_result .= $field_separator;
+ }
+ }
+
+ return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_select_time} function plugin
+ *
+ * Type: function<br>
+ * Name: html_select_time<br>
+ * Purpose: Prints the dropdowns for time selection
+ * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
+ * (Smarty online manual)
+ * @author Roberto Berto <roberto@berto.net>
+ * @credits Monte Ohrt <monte AT ohrt DOT com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_make_timestamp()
+ */
+function smarty_function_html_select_time($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+ require_once $smarty->_get_plugin_filepath('function','html_options');
+ /* Default values. */
+ $prefix = "Time_";
+ $time = time();
+ $display_hours = true;
+ $display_minutes = true;
+ $display_seconds = true;
+ $display_meridian = true;
+ $use_24_hours = true;
+ $minute_interval = 1;
+ $second_interval = 1;
+ /* Should the select boxes be part of an array when returned from PHP?
+ e.g. setting it to "birthday", would create "birthday[Hour]",
+ "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
+ Can be combined with prefix. */
+ $field_array = null;
+ $all_extra = null;
+ $hour_extra = null;
+ $minute_extra = null;
+ $second_extra = null;
+ $meridian_extra = null;
+
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'prefix':
+ case 'time':
+ case 'field_array':
+ case 'all_extra':
+ case 'hour_extra':
+ case 'minute_extra':
+ case 'second_extra':
+ case 'meridian_extra':
+ $$_key = (string)$_value;
+ break;
+
+ case 'display_hours':
+ case 'display_minutes':
+ case 'display_seconds':
+ case 'display_meridian':
+ case 'use_24_hours':
+ $$_key = (bool)$_value;
+ break;
+
+ case 'minute_interval':
+ case 'second_interval':
+ $$_key = (int)$_value;
+ break;
+
+ default:
+ $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
+ }
+ }
+
+ $time = smarty_make_timestamp($time);
+
+ $html_result = '';
+
+ if ($display_hours) {
+ $hours = $use_24_hours ? range(0, 23) : range(1, 12);
+ $hour_fmt = $use_24_hours ? '%H' : '%I';
+ for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
+ $hours[$i] = sprintf('%02d', $hours[$i]);
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Hour"';
+ }
+ if (null !== $hour_extra){
+ $html_result .= ' ' . $hour_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+ $html_result .= smarty_function_html_options(array('output' => $hours,
+ 'values' => $hours,
+ 'selected' => strftime($hour_fmt, $time),
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ if ($display_minutes) {
+ $all_minutes = range(0, 59);
+ for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
+ $minutes[] = sprintf('%02d', $all_minutes[$i]);
+ $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Minute"';
+ }
+ if (null !== $minute_extra){
+ $html_result .= ' ' . $minute_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+
+ $html_result .= smarty_function_html_options(array('output' => $minutes,
+ 'values' => $minutes,
+ 'selected' => $selected,
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ if ($display_seconds) {
+ $all_seconds = range(0, 59);
+ for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
+ $seconds[] = sprintf('%02d', $all_seconds[$i]);
+ $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Second"';
+ }
+
+ if (null !== $second_extra){
+ $html_result .= ' ' . $second_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+
+ $html_result .= smarty_function_html_options(array('output' => $seconds,
+ 'values' => $seconds,
+ 'selected' => $selected,
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ if ($display_meridian && !$use_24_hours) {
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Meridian"';
+ }
+
+ if (null !== $meridian_extra){
+ $html_result .= ' ' . $meridian_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+
+ $html_result .= smarty_function_html_options(array('output' => array('AM', 'PM'),
+ 'values' => array('am', 'pm'),
+ 'selected' => strtolower(strftime('%p', $time)),
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_table} function plugin
+ *
+ * Type: function<br>
+ * Name: html_table<br>
+ * Date: Feb 17, 2003<br>
+ * Purpose: make an html table from an array of data<br>
+ * Input:<br>
+ * - loop = array to loop through
+ * - cols = number of columns, comma separated list of column names
+ * or array of column names
+ * - rows = number of rows
+ * - table_attr = table attributes
+ * - th_attr = table heading attributes (arrays are cycled)
+ * - tr_attr = table row attributes (arrays are cycled)
+ * - td_attr = table cell attributes (arrays are cycled)
+ * - trailpad = value to pad trailing cells with
+ * - caption = text for caption element
+ * - vdir = vertical direction (default: "down", means top-to-bottom)
+ * - hdir = horizontal direction (default: "right", means left-to-right)
+ * - inner = inner loop (default "cols": print $loop line by line,
+ * $loop will be printed column by column otherwise)
+ *
+ *
+ * Examples:
+ * <pre>
+ * {table loop=$data}
+ * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
+ * {table loop=$data cols="first,second,third" tr_attr=$colors}
+ * </pre>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
+ * @author credit to boots <boots dot smarty at yahoo dot com>
+ * @version 1.1
+ * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_table($params, &$smarty)
+{
+ $table_attr = 'border="1"';
+ $tr_attr = '';
+ $th_attr = '';
+ $td_attr = '';
+ $cols = $cols_count = 3;
+ $rows = 3;
+ $trailpad = ' ';
+ $vdir = 'down';
+ $hdir = 'right';
+ $inner = 'cols';
+ $caption = '';
+
+ if (!isset($params['loop'])) {
+ $smarty->trigger_error("html_table: missing 'loop' parameter");
+ return;
+ }
+
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'loop':
+ $$_key = (array)$_value;
+ break;
+
+ case 'cols':
+ if (is_array($_value) && !empty($_value)) {
+ $cols = $_value;
+ $cols_count = count($_value);
+ } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
+ $cols = explode(',', $_value);
+ $cols_count = count($cols);
+ } elseif (!empty($_value)) {
+ $cols_count = (int)$_value;
+ } else {
+ $cols_count = $cols;
+ }
+ break;
+
+ case 'rows':
+ $$_key = (int)$_value;
+ break;
+
+ case 'table_attr':
+ case 'trailpad':
+ case 'hdir':
+ case 'vdir':
+ case 'inner':
+ case 'caption':
+ $$_key = (string)$_value;
+ break;
+
+ case 'tr_attr':
+ case 'td_attr':
+ case 'th_attr':
+ $$_key = $_value;
+ break;
+ }
+ }
+
+ $loop_count = count($loop);
+ if (empty($params['rows'])) {
+ /* no rows specified */
+ $rows = ceil($loop_count/$cols_count);
+ } elseif (empty($params['cols'])) {
+ if (!empty($params['rows'])) {
+ /* no cols specified, but rows */
+ $cols_count = ceil($loop_count/$rows);
+ }
+ }
+
+ $output = "<table $table_attr>\n";
+
+ if (!empty($caption)) {
+ $output .= '<caption>' . $caption . "</caption>\n";
+ }
+
+ if (is_array($cols)) {
+ $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
+ $output .= "<thead><tr>\n";
+
+ for ($r=0; $r<$cols_count; $r++) {
+ $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
+ $output .= $cols[$r];
+ $output .= "</th>\n";
+ }
+ $output .= "</tr></thead>\n";
+ }
+
+ $output .= "<tbody>\n";
+ for ($r=0; $r<$rows; $r++) {
+ $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
+ $rx = ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
+
+ for ($c=0; $c<$cols_count; $c++) {
+ $x = ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
+ if ($inner!='cols') {
+ /* shuffle x to loop over rows*/
+ $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
+ }
+
+ if ($x<$loop_count) {
+ $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
+ } else {
+ $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
+ }
+ }
+ $output .= "</tr>\n";
+ }
+ $output .= "</tbody>\n";
+ $output .= "</table>\n";
+
+ return $output;
+}
+
+function smarty_function_html_table_cycle($name, $var, $no) {
+ if(!is_array($var)) {
+ $ret = $var;
+ } else {
+ $ret = $var[$no % count($var)];
+ }
+
+ return ($ret) ? ' '.$ret : '';
+}
+
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {mailto} function plugin
+ *
+ * Type: function<br>
+ * Name: mailto<br>
+ * Date: May 21, 2002
+ * Purpose: automate mailto address link creation, and optionally
+ * encode them.<br>
+ * Input:<br>
+ * - address = e-mail address
+ * - text = (optional) text to display, default is address
+ * - encode = (optional) can be one of:
+ * * none : no encoding (default)
+ * * javascript : encode with javascript
+ * * javascript_charcode : encode with javascript charcode
+ * * hex : encode with hexidecimal (no javascript)
+ * - cc = (optional) address(es) to carbon copy
+ * - bcc = (optional) address(es) to blind carbon copy
+ * - subject = (optional) e-mail subject
+ * - newsgroups = (optional) newsgroup(s) to post to
+ * - followupto = (optional) address(es) to follow up to
+ * - extra = (optional) extra tags for the href link
+ *
+ * Examples:
+ * <pre>
+ * {mailto address="me@domain.com"}
+ * {mailto address="me@domain.com" encode="javascript"}
+ * {mailto address="me@domain.com" encode="hex"}
+ * {mailto address="me@domain.com" subject="Hello to you!"}
+ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
+ * {mailto address="me@domain.com" extra='class="mailto"'}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
+ * (Smarty online manual)
+ * @version 1.2
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Jason Sweat (added cc, bcc and subject functionality)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_mailto($params, &$smarty)
+{
+ $extra = '';
+
+ if (empty($params['address'])) {
+ $smarty->trigger_error("mailto: missing 'address' parameter");
+ return;
+ } else {
+ $address = $params['address'];
+ }
+
+ $text = $address;
+
+ // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+ // so, don't encode it.
+ $search = array('%40', '%2C');
+ $replace = array('@', ',');
+ $mail_parms = array();
+ foreach ($params as $var=>$value) {
+ switch ($var) {
+ case 'cc':
+ case 'bcc':
+ case 'followupto':
+ if (!empty($value))
+ $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
+ break;
+
+ case 'subject':
+ case 'newsgroups':
+ $mail_parms[] = $var.'='.rawurlencode($value);
+ break;
+
+ case 'extra':
+ case 'text':
+ $$var = $value;
+
+ default:
+ }
+ }
+
+ $mail_parm_vals = '';
+ for ($i=0; $i<count($mail_parms); $i++) {
+ $mail_parm_vals .= (0==$i) ? '?' : '&';
+ $mail_parm_vals .= $mail_parms[$i];
+ }
+ $address .= $mail_parm_vals;
+
+ $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
+ if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
+ $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
+ return;
+ }
+
+ if ($encode == 'javascript' ) {
+ $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
+
+ $js_encode = '';
+ for ($x=0; $x < strlen($string); $x++) {
+ $js_encode .= '%' . bin2hex($string[$x]);
+ }
+
+ return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
+
+ } elseif ($encode == 'javascript_charcode' ) {
+ $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+ for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
+ $ord[] = ord($string[$x]);
+ }
+
+ $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
+ $_ret .= "<!--\n";
+ $_ret .= "{document.write(String.fromCharCode(";
+ $_ret .= implode(',',$ord);
+ $_ret .= "))";
+ $_ret .= "}\n";
+ $_ret .= "//-->\n";
+ $_ret .= "</script>\n";
+
+ return $_ret;
+
+
+ } elseif ($encode == 'hex') {
+
+ preg_match('!^(.*)(\?.*)$!',$address,$match);
+ if(!empty($match[2])) {
+ $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
+ return;
+ }
+ $address_encode = '';
+ for ($x=0; $x < strlen($address); $x++) {
+ if(preg_match('!\w!',$address[$x])) {
+ $address_encode .= '%' . bin2hex($address[$x]);
+ } else {
+ $address_encode .= $address[$x];
+ }
+ }
+ $text_encode = '';
+ for ($x=0; $x < strlen($text); $x++) {
+ $text_encode .= '&#x' . bin2hex($text[$x]).';';
+ }
+
+ $mailto = "mailto:";
+ return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
+
+ } else {
+ // no encoding
+ return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+ }
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {math} function plugin
+ *
+ * Type: function<br>
+ * Name: math<br>
+ * Purpose: handle math computations in template<br>
+ * @link http://smarty.php.net/manual/en/language.function.math.php {math}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_math($params, &$smarty)
+{
+ // be sure equation parameter is present
+ if (empty($params['equation'])) {
+ $smarty->trigger_error("math: missing equation parameter");
+ return;
+ }
+
+ // strip out backticks, not necessary for math
+ $equation = str_replace('`','',$params['equation']);
+
+ // make sure parenthesis are balanced
+ if (substr_count($equation,"(") != substr_count($equation,")")) {
+ $smarty->trigger_error("math: unbalanced parenthesis");
+ return;
+ }
+
+ // match all vars in equation, make sure all are passed
+ preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
+ $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
+ 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
+
+ foreach($match[1] as $curr_var) {
+ if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
+ $smarty->trigger_error("math: function call $curr_var not allowed");
+ return;
+ }
+ }
+
+ foreach($params as $key => $val) {
+ if ($key != "equation" && $key != "format" && $key != "assign") {
+ // make sure value is not empty
+ if (strlen($val)==0) {
+ $smarty->trigger_error("math: parameter $key is empty");
+ return;
+ }
+ if (!is_numeric($val)) {
+ $smarty->trigger_error("math: parameter $key: is not numeric");
+ return;
+ }
+ $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
+ }
+ }
+
+ eval("\$smarty_math_result = ".$equation.";");
+
+ if (empty($params['format'])) {
+ if (empty($params['assign'])) {
+ return $smarty_math_result;
+ } else {
+ $smarty->assign($params['assign'],$smarty_math_result);
+ }
+ } else {
+ if (empty($params['assign'])){
+ printf($params['format'],$smarty_math_result);
+ } else {
+ $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup} function plugin
+ *
+ * Type: function<br>
+ * Name: popup<br>
+ * Purpose: make text pop up in windows via overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup($params, &$smarty)
+{
+ $append = '';
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'text':
+ case 'trigger':
+ case 'function':
+ case 'inarray':
+ $$_key = (string)$_value;
+ if ($_key == 'function' || $_key == 'inarray')
+ $append .= ',' . strtoupper($_key) . ",'$_value'";
+ break;
+
+ case 'caption':
+ case 'closetext':
+ case 'status':
+ $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
+ break;
+
+ case 'fgcolor':
+ case 'bgcolor':
+ case 'textcolor':
+ case 'capcolor':
+ case 'closecolor':
+ case 'textfont':
+ case 'captionfont':
+ case 'closefont':
+ case 'fgbackground':
+ case 'bgbackground':
+ case 'caparray':
+ case 'capicon':
+ case 'background':
+ case 'frame':
+ $append .= ',' . strtoupper($_key) . ",'$_value'";
+ break;
+
+ case 'textsize':
+ case 'captionsize':
+ case 'closesize':
+ case 'width':
+ case 'height':
+ case 'border':
+ case 'offsetx':
+ case 'offsety':
+ case 'snapx':
+ case 'snapy':
+ case 'fixx':
+ case 'fixy':
+ case 'padx':
+ case 'pady':
+ case 'timeout':
+ case 'delay':
+ $append .= ',' . strtoupper($_key) . ",$_value";
+ break;
+
+ case 'sticky':
+ case 'left':
+ case 'right':
+ case 'center':
+ case 'above':
+ case 'below':
+ case 'noclose':
+ case 'autostatus':
+ case 'autostatuscap':
+ case 'fullhtml':
+ case 'hauto':
+ case 'vauto':
+ case 'mouseoff':
+ case 'followmouse':
+ case 'closeclick':
+ if ($_value) $append .= ',' . strtoupper($_key);
+ break;
+
+ default:
+ $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
+ }
+ }
+
+ if (empty($text) && !isset($inarray) && empty($function)) {
+ $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
+ return false;
+ }
+
+ if (empty($trigger)) { $trigger = "onmouseover"; }
+
+ $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
+ $retval .= $append . ');"';
+ if ($trigger == 'onmouseover')
+ $retval .= ' onmouseout="nd();"';
+
+
+ return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup_init} function plugin
+ *
+ * Type: function<br>
+ * Name: popup_init<br>
+ * Purpose: initialize overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup_init($params, &$smarty)
+{
+ $zindex = 1000;
+
+ if (!empty($params['zindex'])) {
+ $zindex = $params['zindex'];
+ }
+
+ if (!empty($params['src'])) {
+ return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
+ . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
+ } else {
+ $smarty->trigger_error("popup_init: missing src parameter");
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty capitalize modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: capitalize<br>
+ * Purpose: capitalize words in the string
+ * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
+ * capitalize (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_capitalize($string, $uc_digits = false)
+{
+ smarty_modifier_capitalize_ucfirst(null, $uc_digits);
+ return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
+}
+
+function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
+{
+ static $_uc_digits = false;
+
+ if(isset($uc_digits)) {
+ $_uc_digits = $uc_digits;
+ return;
+ }
+
+ if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
+ return ucfirst($string[0]);
+ else
+ return $string[0];
+}
+
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty cat modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: cat<br>
+ * Date: Feb 24, 2003
+ * Purpose: catenate a value to a variable
+ * Input: string to catenate
+ * Example: {$var|cat:"foo"}
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_cat($string, $cat)
+{
+ return $string . $cat;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_characters modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_characteres<br>
+ * Purpose: count the number of characters in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
+ * count_characters (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean include whitespace in the character count
+ * @return integer
+ */
+function smarty_modifier_count_characters($string, $include_spaces = false)
+{
+ if ($include_spaces)
+ return(strlen($string));
+
+ return preg_match_all("/[^\s]/",$string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_paragraphs<br>
+ * Purpose: count the number of paragraphs in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ * count_paragraphs (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_paragraphs($string)
+{
+ // count \r or \n characters
+ return count(preg_split('/[\r\n]+/', $string));
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_sentences modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_sentences
+ * Purpose: count the number of sentences in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ * count_sentences (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_sentences($string)
+{
+ // find periods with a word before but not after.
+ return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_words modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_words<br>
+ * Purpose: count the number of words in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
+ * count_words (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_words($string)
+{
+ // split text by ' ',\r,\n,\f,\t
+ $split_array = preg_split('/\s+/',$string);
+ // count matches that contain alphanumerics
+ $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
+
+ return count($word_count);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Include the {@link shared.make_timestamp.php} plugin
+ */
+require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
+/**
+ * Smarty date_format modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: date_format<br>
+ * Purpose: format datestamps via strftime<br>
+ * Input:<br>
+ * - string: input date string
+ * - format: strftime format for output
+ * - default_date: default date if $string is empty
+ * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
+ * date_format (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string|void
+ * @uses smarty_make_timestamp()
+ */
+function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
+{
+ if ($string != '') {
+ $timestamp = smarty_make_timestamp($string);
+ } elseif ($default_date != '') {
+ $timestamp = smarty_make_timestamp($default_date);
+ } else {
+ return;
+ }
+ if (DIRECTORY_SEPARATOR == '\\') {
+ $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
+ $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
+ if (strpos($format, '%e') !== false) {
+ $_win_from[] = '%e';
+ $_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
+ }
+ if (strpos($format, '%l') !== false) {
+ $_win_from[] = '%l';
+ $_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
+ }
+ $format = str_replace($_win_from, $_win_to, $format);
+ }
+ return strftime($format, $timestamp);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty debug_print_var modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: debug_print_var<br>
+ * Purpose: formats variable contents for display in the console
+ * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
+ * debug_print_var (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array|object
+ * @param integer
+ * @param integer
+ * @return string
+ */
+function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
+{
+ $_replace = array(
+ "\n" => '<i>\n</i>',
+ "\r" => '<i>\r</i>',
+ "\t" => '<i>\t</i>'
+ );
+
+ switch (gettype($var)) {
+ case 'array' :
+ $results = '<b>Array (' . count($var) . ')</b>';
+ foreach ($var as $curr_key => $curr_val) {
+ $results .= '<br>' . str_repeat(' ', $depth * 2)
+ . '<b>' . strtr($curr_key, $_replace) . '</b> => '
+ . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+ $depth--;
+ }
+ break;
+ case 'object' :
+ $object_vars = get_object_vars($var);
+ $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
+ foreach ($object_vars as $curr_key => $curr_val) {
+ $results .= '<br>' . str_repeat(' ', $depth * 2)
+ . '<b> ->' . strtr($curr_key, $_replace) . '</b> = '
+ . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+ $depth--;
+ }
+ break;
+ case 'boolean' :
+ case 'NULL' :
+ case 'resource' :
+ if (true === $var) {
+ $results = 'true';
+ } elseif (false === $var) {
+ $results = 'false';
+ } elseif (null === $var) {
+ $results = 'null';
+ } else {
+ $results = htmlspecialchars((string) $var);
+ }
+ $results = '<i>' . $results . '</i>';
+ break;
+ case 'integer' :
+ case 'float' :
+ $results = htmlspecialchars((string) $var);
+ break;
+ case 'string' :
+ $results = strtr($var, $_replace);
+ if (strlen($var) > $length ) {
+ $results = substr($var, 0, $length - 3) . '...';
+ }
+ $results = htmlspecialchars('"' . $results . '"');
+ break;
+ case 'unknown type' :
+ default :
+ $results = strtr((string) $var, $_replace);
+ if (strlen($results) > $length ) {
+ $results = substr($results, 0, $length - 3) . '...';
+ }
+ $results = htmlspecialchars($results);
+ }
+
+ return $results;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty default modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: default<br>
+ * Purpose: designate default value for empty variables
+ * @link http://smarty.php.net/manual/en/language.modifier.default.php
+ * default (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_default($string, $default = '')
+{
+ if (!isset($string) || $string === '')
+ return $default;
+ else
+ return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: escape<br>
+ * Purpose: Escape the string according to escapement type
+ * @link http://smarty.php.net/manual/en/language.modifier.escape.php
+ * escape (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param html|htmlall|url|quotes|hex|hexentity|javascript
+ * @return string
+ */
+function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
+{
+ switch ($esc_type) {
+ case 'html':
+ return htmlspecialchars($string, ENT_QUOTES, $char_set);
+
+ case 'htmlall':
+ return htmlentities($string, ENT_QUOTES, $char_set);
+
+ case 'url':
+ return rawurlencode($string);
+
+ case 'urlpathinfo':
+ return str_replace('%2F','/',rawurlencode($string));
+
+ case 'quotes':
+ // escape unescaped single quotes
+ return preg_replace("%(?<!\\\\)'%", "\\'", $string);
+
+ case 'hex':
+ // escape every character into hex
+ $return = '';
+ for ($x=0; $x < strlen($string); $x++) {
+ $return .= '%' . bin2hex($string[$x]);
+ }
+ return $return;
+
+ case 'hexentity':
+ $return = '';
+ for ($x=0; $x < strlen($string); $x++) {
+ $return .= '&#x' . bin2hex($string[$x]) . ';';
+ }
+ return $return;
+
+ case 'decentity':
+ $return = '';
+ for ($x=0; $x < strlen($string); $x++) {
+ $return .= '&#' . ord($string[$x]) . ';';
+ }
+ return $return;
+
+ case 'javascript':
+ // escape quotes and backslashes, newlines, etc.
+ return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
+
+ case 'mail':
+ // safe way to display e-mail address on a web page
+ return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
+
+ case 'nonstd':
+ // escape non-standard chars, such as ms document quotes
+ $_res = '';
+ for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
+ $_ord = ord(substr($string, $_i, 1));
+ // non-standard char, escape it
+ if($_ord >= 126){
+ $_res .= '&#' . $_ord . ';';
+ }
+ else {
+ $_res .= substr($string, $_i, 1);
+ }
+ }
+ return $_res;
+
+ default:
+ return $string;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty indent modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: indent<br>
+ * Purpose: indent lines of text
+ * @link http://smarty.php.net/manual/en/language.modifier.indent.php
+ * indent (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @return string
+ */
+function smarty_modifier_indent($string,$chars=4,$char=" ")
+{
+ return preg_replace('!^!m',str_repeat($char,$chars),$string);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty lower modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: lower<br>
+ * Purpose: convert string to lowercase
+ * @link http://smarty.php.net/manual/en/language.modifier.lower.php
+ * lower (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_lower($string)
+{
+ return strtolower($string);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty plugin
+ *
+ * Type: modifier<br>
+ * Name: nl2br<br>
+ * Date: Feb 26, 2003
+ * Purpose: convert \r\n, \r or \n to <<br>>
+ * Input:<br>
+ * - contents = contents to replace
+ * - preceed_test = if true, includes preceeding break tags
+ * in replacement
+ * Example: {$text|nl2br}
+ * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
+ * nl2br (Smarty online manual)
+ * @version 1.0
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_nl2br($string)
+{
+ return nl2br($string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty regex_replace modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: regex_replace<br>
+ * Purpose: regular expression search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ * regex_replace (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string|array
+ * @param string|array
+ * @return string
+ */
+function smarty_modifier_regex_replace($string, $search, $replace)
+{
+ if(is_array($search)) {
+ foreach($search as $idx => $s)
+ $search[$idx] = _smarty_regex_replace_check($s);
+ } else {
+ $search = _smarty_regex_replace_check($search);
+ }
+
+ return preg_replace($search, $replace, $string);
+}
+
+function _smarty_regex_replace_check($search)
+{
+ if (($pos = strpos($search,"\0")) !== false)
+ $search = substr($search,0,$pos);
+ if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
+ /* remove eval-modifier from $search */
+ $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
+ }
+ return $search;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty replace modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: replace<br>
+ * Purpose: simple search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.replace.php
+ * replace (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_replace($string, $search, $replace)
+{
+ return str_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty spacify modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: spacify<br>
+ * Purpose: add spaces between characters in a string
+ * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
+ * spacify (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_spacify($string, $spacify_char = ' ')
+{
+ return implode($spacify_char,
+ preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty string_format modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: string_format<br>
+ * Purpose: format strings via sprintf
+ * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
+ * string_format (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_string_format($string, $format)
+{
+ return sprintf($format, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: strip<br>
+ * Purpose: Replace all repeated spaces, newlines, tabs
+ * with a single space or supplied replacement string.<br>
+ * Example: {$var|strip} {$var|strip:" "}
+ * Date: September 25th, 2002
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.php
+ * strip (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_strip($text, $replace = ' ')
+{
+ return preg_replace('!\s+!', $replace, $text);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip_tags modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: strip_tags<br>
+ * Purpose: strip html tags from text
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
+ * strip_tags (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_strip_tags($string, $replace_with_space = true)
+{
+ if ($replace_with_space)
+ return preg_replace('!<[^>]*?>!', ' ', $string);
+ else
+ return strip_tags($string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty truncate modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: truncate<br>
+ * Purpose: Truncate a string to a certain length if necessary,
+ * optionally splitting in the middle of a word, and
+ * appending the $etc string or inserting $etc into the middle.
+ * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
+ * truncate (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_truncate($string, $length = 80, $etc = '...',
+ $break_words = false, $middle = false)
+{
+ if ($length == 0)
+ return '';
+
+ if (strlen($string) > $length) {
+ $length -= min($length, strlen($etc));
+ if (!$break_words && !$middle) {
+ $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
+ }
+ if(!$middle) {
+ return substr($string, 0, $length) . $etc;
+ } else {
+ return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
+ }
+ } else {
+ return $string;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty upper modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: upper<br>
+ * Purpose: convert string to uppercase
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php
+ * upper (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_upper($string)
+{
+ return strtoupper($string);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty wordwrap modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: wordwrap<br>
+ * Purpose: wrap a string of text at a given length
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
+ * wordwrap (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
+{
+ return wordwrap($string,$length,$break,$cut);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty trimwhitespace outputfilter plugin
+ *
+ * File: outputfilter.trimwhitespace.php<br>
+ * Type: outputfilter<br>
+ * Name: trimwhitespace<br>
+ * Date: Jan 25, 2003<br>
+ * Purpose: trim leading white space and blank lines from
+ * template source after it gets interpreted, cleaning
+ * up code and saving bandwidth. Does not affect
+ * <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
+ * Install: Drop into the plugin directory, call
+ * <code>$smarty->load_filter('output','trimwhitespace');</code>
+ * from application.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
+ * @version 1.3
+ * @param string
+ * @param Smarty
+ */
+function smarty_outputfilter_trimwhitespace($source, &$smarty)
+{
+ // Pull out the script blocks
+ preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
+ $_script_blocks = $match[0];
+ $source = preg_replace("!<script[^>]*?>.*?</script>!is",
+ '@@@SMARTY:TRIM:SCRIPT@@@', $source);
+
+ // Pull out the pre blocks
+ preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
+ $_pre_blocks = $match[0];
+ $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
+ '@@@SMARTY:TRIM:PRE@@@', $source);
+
+ // Pull out the textarea blocks
+ preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
+ $_textarea_blocks = $match[0];
+ $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
+ '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
+
+ // remove all leading spaces, tabs and carriage returns NOT
+ // preceeded by a php close tag.
+ $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
+
+ // replace textarea blocks
+ smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
+
+ // replace pre blocks
+ smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
+
+ // replace script blocks
+ smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
+
+ return $source;
+}
+
+function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
+ $_len = strlen($search_str);
+ $_pos = 0;
+ for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
+ if (($_pos=strpos($subject, $search_str, $_pos))!==false)
+ $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
+ else
+ break;
+
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * escape_special_chars common function
+ *
+ * Function: smarty_function_escape_special_chars<br>
+ * Purpose: used by other smarty functions to escape
+ * special chars except for already escaped ones
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_function_escape_special_chars($string)
+{
+ if(!is_array($string)) {
+ $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+ $string = htmlspecialchars($string);
+ $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
+ }
+ return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Function: smarty_make_timestamp<br>
+ * Purpose: used by other smarty functions to make a timestamp
+ * from a string.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_make_timestamp($string)
+{
+ if(empty($string)) {
+ // use "now":
+ $time = time();
+
+ } elseif (preg_match('/^\d{14}$/', $string)) {
+ // it is mysql timestamp format of YYYYMMDDHHMMSS?
+ $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
+ substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
+
+ } elseif (is_numeric($string)) {
+ // it is a numeric string, we handle it as timestamp
+ $time = (int)$string;
+
+ } else {
+ // strtotime should handle it
+ $time = strtotime($string);
+ if ($time == -1 || $time === false) {
+ // strtotime() was not able to parse $string, use "now":
+ $time = time();
+ }
+ }
+ return $time;
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
--- /dev/null
+2004-03-01 Sagi Bashari <sagi@boom.org.il>
+
+ * tsmarty2c.php:
+ - added support for directories (originally by Uros Gruber <uros.gruber@vizija.si>)
+ - fixed bug that prevented more than 1 block per line (reported by Eneko Lacunza <enlar@euskal.org>)
+ - convert new line to \n in output string
+
+ * smarty_gettext.php:
+ - run nl2br() when escaping html
--- /dev/null
+Gettext support for Smarty
+--------------------------
+
+Author: Sagi Bashari <sagi@boom.org.il>
+URL: http://www.boom.org.il/smarty/gettext/
+Support URL: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=84
+
+This file assumes that you already know what is gettext and how to use it with PHP.
+If you don't, please visit the following websites before trying to use this package:
+ - http://www.php.net/gettext
+ - http://www.onlamp.com/pub/a/php/2002/06/13/php.html
+
+This package has two parts:
+ 1. smarty_gettext.php - The smarty plugin
+ 2. tsmarty2c.php - command line utility that rips gettext strings from smarty source files and converts them to C format
+
+The Smarty plugin
+-----------------
+
+Installation:
+
+1. Copy the smarty_gettext.php file to your include directory.
+2. After initializing the smarty object in your script, register the plugin as a block function.
+
+Example:
+$smarty = new Smarty [...];
+require('smarty_gettext.php');
+$smarty->register_block('t', 'smarty_translate');
+
+This example will register the function as a block function named 't'.
+
+Usage:
+
+The content of the block function is the string that you want to translate. For example, for translating 'Hello World', use: {t}Hello World{/t}.
+
+If you have dynamic parameters that should be set inside the string, pass them to the block function, and they will be replaced with %n, where n is 1 for the 1st parameter and so on. For example, {t name="sagi"}my name is %1{/t} will replace %1 with name.
+
+The parameter name is ignored, unless it is one of the reserved names (see below). Only the parameters order matters.
+
+Example for using multiple parameters:
+{t 1='one' 2='two' 3='three'}The 1st parameter is %1, the 2nd is %2 and the 3nd %3.{/t}
+
+NOTE: I decided to use numeric arguments instead of sprintf(), because it offers greater control over the parameter placement in the translated text. You can also use this in your PHP code, by using the strarg() function, like this: strarg(_('hi %1'), $name [,..]).
+
+By default all the translated strings will be automatically HTML escaped. You may control this by setting the 'escape' parameter. Possible values:
+ - 'html' for HTML escaping, this is the default.
+ - 'js' for javascript escaping.
+ - 'no'/'off'/0 - turns off escaping
+
+ Example: {t escape=no url="http://www.php.net/" name="PHP website"}<a href="%1">%2</a>{/t}
+
+Plural support:
+
+The package also provides support for plural forms (see ngettext).
+
+To provide a plural form:
+ 1. Set a parameter named 'plural' with the plural version of the string.
+ 2. Set a parameter named 'count' with the variable count.
+
+Example:
+{t count=$files|@count plural="%1 files"}%1 file{/t}
+
+
+tsmarty2c.php - the command line utility
+----------------------------------------
+
+This utility will rip the translation strings from the smarty files, and convert them to gettext calls in C, that can later be used with the standard gettext tools.
+
+Usage:
+./tsmarty2c.php <filename or directory> <file2> <..> > smarty.c
+
+If a parameter is a directory, the template files within will be parsed.
+
+Copyright
+---------
+
+Copyright (c) 2004 Sagi Bashari
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--- /dev/null
+<?php
+/**
+ * smarty_gettext.php - Gettext support for smarty
+ *
+ * ------------------------------------------------------------------------- *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ * ------------------------------------------------------------------------- *
+ *
+ * To register as a smarty block function named 't', use:
+ * $smarty->register_block('t', 'smarty_translate');
+ *
+ * @package smarty_gettext
+ * @version 0.9
+ * @link http://www.boom.org.il/smarty/gettext/
+ * @author Sagi Bashari <sagi@boom.org.il>
+ * @copyright 2004 Sagi Bashari
+ */
+
+/**
+ * Replace arguments in a string with their values. Arguments are represented by % followed by their number.
+ *
+ * @param string Source string
+ * @param mixed Arguments, can be passed in an array or through single variables.
+ * @returns string Modified string
+ */
+function strarg($str)
+{
+ $tr = array();
+ $p = 0;
+
+ for ($i=1; $i < func_num_args(); $i++) {
+ $arg = func_get_arg($i);
+
+ if (is_array($arg)) {
+ foreach ($arg as $aarg) {
+ $tr['%'.++$p] = $aarg;
+ }
+ } else {
+ $tr['%'.++$p] = $arg;
+ }
+ }
+
+ return strtr($str, $tr);
+}
+
+/**
+ * Smarty block function, provides gettext support for smarty.
+ *
+ * The block content is the text that should be translated.
+ *
+ * Any parameter that is sent to the function will be represented as %n in the translation text,
+ * where n is 1 for the first parameter. The following parameters are reserved:
+ * - escape - sets escape mode:
+ * - 'html' for HTML escaping, this is the default.
+ * - 'js' for javascript escaping.
+ * - 'no'/'off'/0 - turns off escaping
+ * - plural - The plural version of the text (2nd parameter of ngettext())
+ * - count - The item count for plural mode (3rd parameter of ngettext())
+ */
+function smarty_translate($params, $text, &$smarty)
+{
+ $text = stripslashes($text);
+
+ // set escape mode
+ if (isset($params['escape'])) {
+ $escape = $params['escape'];
+ unset($params['escape']);
+ }
+
+ // set plural version
+ if (isset($params['plural'])) {
+ $plural = $params['plural'];
+ unset($params['plural']);
+
+ // set count
+ if (isset($params['count'])) {
+ $count = $params['count'];
+ unset($params['count']);
+ }
+ }
+
+ // use plural if required parameters are set
+ if (isset($count) && isset($plural)) {
+ $text = ngettext($text, $plural, $count);
+ } else { // use normal
+ $text = gettext($text);
+ }
+
+ // run strarg if there are parameters
+ if (count($params)) {
+ $text = strarg($text, $params);
+ }
+
+ if (!isset($escape) || $escape == 'html') { // html escape, default
+ $text = nl2br(htmlspecialchars($text));
+ } elseif (isset($escape) && ($escape == 'javascript' || $escape == 'js')) { // javascript escape
+ $text = str_replace('\'','\\\'',stripslashes($text));
+ }
+
+ return $text;
+}
+
+?>
--- /dev/null
+#!/usr/local/bin/php -qn
+<?php
+/**
+ * tsmarty2c.php - rips gettext strings from smarty template
+ *
+ * ------------------------------------------------------------------------- *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ * ------------------------------------------------------------------------- *
+ *
+ * This command line script rips gettext strings from smarty file, and prints them to stdout in C format,
+ * that can later be used with the standard gettext tools.
+ *
+ * Usage:
+ * ./tsmarty2c.php <filename or directory> <file2> <..> > smarty.c
+ *
+ * If a parameter is a directory, the template files within will be parsed.
+ *
+ * @package smarty_gettext
+ * @version 0.9
+ * @link http://www.boom.org.il/smarty/gettext/
+ * @author Sagi Bashari <sagi@boom.org.il>
+ * @copyright 2004 Sagi Bashari
+ */
+
+// smarty open tag
+$ldq = preg_quote('{');
+
+// smarty close tag
+$rdq = preg_quote('}');
+
+// smarty command
+$cmd = preg_quote('t');
+
+// extensions of smarty files, used when going through a directory
+$extensions = array('tpl');
+
+// "fix" string - strip slashes, escape and convert new lines to \n
+function fs($str)
+{
+ $str = stripslashes($str);
+ $str = str_replace('"', '\"', $str);
+ $str = str_replace("\n", '\n', $str);
+ return $str;
+}
+
+// rips gettext strings from $file and prints them in C format
+function do_file($file)
+{
+ $content = @file_get_contents($file);
+
+ if (empty($content)) {
+ return;
+ }
+
+ global $ldq, $rdq, $cmd;
+
+ preg_match_all("/{$ldq}\s*({$cmd})\s*([^{$rdq}]*){$rdq}([^{$ldq}]*){$ldq}\/\\1{$rdq}/", $content, $matches);
+
+ for ($i=0; $i < count($matches[0]); $i++) {
+ if (preg_match('/plural\s*=\s*["\']?\s*(.[^\"\']*)\s*["\']?/', $matches[2][$i], $match)) {
+ print 'ngettext("'.fs($matches[3][$i]).'","'.fs($match[1]).'",x);'."\n";
+ } else {
+ print 'gettext("'.fs($matches[3][$i]).'");'."\n";
+ }
+ }
+}
+
+// go through a directory
+function do_dir($dir)
+{
+ $d = dir($dir);
+
+ while (false !== ($entry = $d->read())) {
+ if ($entry == '.' || $entry == '..') {
+ continue;
+ }
+
+ $entry = $dir.'/'.$entry;
+
+ if (is_dir($entry)) { // if a directory, go through it
+ do_dir($entry);
+ } else { // if file, parse only if extension is matched
+ $pi = pathinfo($entry);
+
+ if (in_array($pi['extension'], $GLOBALS['extensions'])) {
+ do_file($entry);
+ }
+ }
+ }
+
+ $d->close();
+}
+
+for ($ac=1; $ac < $_SERVER['argc']; $ac++) {
+ if (is_dir($_SERVER['argv'][$ac])) { // go through directory
+ do_dir($_SERVER['argv'][$ac]);
+ } else { // do file
+ do_file($_SERVER['argv'][$ac]);
+ }
+}
+
+?>
--- /dev/null
+<?php
+
+class BGraph{
+ private $title;
+
+ private $data;
+ private $data_type;
+ private $type;
+
+ private $colors;
+ private $shading;
+
+ private $width;
+ private $height;
+ private $output_file;
+ private $plot;
+
+ function __construct( $filename = "graph.png" )
+ {
+ $this->output_file = 'templates_c/' . $filename;
+ }
+
+ public function SetData( $data_in, $type, $data_type, $shading = 5 )
+ {
+ $this->data = $data_in;
+ $this->type = $type;
+ $this->data_type = $data_type;
+ $this->shadding = $shading;
+ }
+
+ public function SetGraphSize( $width, $height )
+ {
+ $this->width = $width;
+ $this->height = $height;
+ }
+
+ public function SetTitle( $title )
+ {
+ if( !empty($title) )
+ $this->title = $title;
+ else
+ die( "Please provide a non empty title for the graph" );
+ }
+
+ public function SetColors( $colors )
+ {
+ if( is_array( $colors ) )
+ $this->colors = $colors;
+ else
+ die( "Please provide a array in BGraph->SetColors()" );
+ }
+
+ public function Get_Image_file()
+ {
+ return $this->output_file;
+ }
+
+ public function Render()
+ {
+ // Setting the size
+ $this->plot = new PHPlot( $this->width, $this->height );
+
+ // Render to file instead of screen
+ $this->plot->SetOutputFile( $this->output_file );
+ $this->plot->SetFileFormat("png");
+ $this->plot->SetIsInline( true );
+
+
+ $this->plot->SetImageBorderType('plain');
+
+ // Data, type and data type
+ $this->plot->SetPlotType( $this->type );
+ $this->plot->SetDataType( $this->data_type );
+ $this->plot->SetDataValues( $this->data );
+
+ // Plot colors
+ $this->plot->SetDataColors( $this->colors );
+
+ // Plot shading
+ $this->plot->SetShading( $this->shading );
+
+ // Image border
+ $this->plot->SetImageBorderType( 'none' );
+
+ // Plot area (calculated regarding the width and height of the graph)
+ if( $this->type == 'pie' )
+ $this->plot->SetPlotAreaPixels( 10, 10, ($this->width / 2), $this->height-10 );
+
+ // Legend position (calculated regarding the width and height of the graph)
+ $this->plot->SetLegendPixels( ($this->width / 2) + 10, 25 );
+
+ // Labels scale position
+ if( $this->type == 'pie' )
+ $this->plot->SetLabelScalePosition( 0.2 );
+
+ // Graph title
+ $this->plot->SetTitle( $this->title );
+
+ // Setting up legends
+ if( $this->type != 'bars' ) {
+ $legends = array();
+ foreach( $this->data as $key => $legend ) {
+ $this->plot->SetLegend( implode(': ',$legend) );
+ }
+ }
+
+ # Turn off X tick labels and ticks because they don't apply here:
+ $this->plot->SetXTickLabelPos('none');
+ $this->plot->SetXTickPos('none');
+ $this->plot->SetPlotAreaWorld(NULL, 0, NULL, NULL);
+
+
+ $this->plot->DrawGraph();
+ } // end function Render()
+} // end BGraph classe
+
+?>