Archive

Archive for the ‘PHP’ Category

Protect class’s properties

March 28, 2010 Comments off

The following class can be used to extend your existent class(es) when you want them to disallow run-time properties instantiation.

class SafeObject


<?php
/**
* base class SafeObject
*
* @description: This base class protects other classes from having properties instantiated at run-time
* @author: Costin Trifan
* @date: 28.03.2010
* @version: 1.0
* @status: release
*/
class SafeObject
{
	/**
	* The list of public properties that can be set to this class
	* @type array
	* @access private
	* @see __get(), __set(), AllowedProperties()
	*/
	private $properties = array();

	/**
	* Whether or not to restrict access to class's properties.
	* @type bool
	* @access private
	* @see RestrictedAccess()
	*/
	private $restricted = true;

/**
*  PRIVATE METHODS
*-------------------------------------------
*/
	private function __clone()
	{
		exit('<br/>Error: You are not allowed to use method [__clone] in class: '.get_class($this));
	}
	private function __sleep()
	{
		exit('<br/>Error: You are not allowed to use method [__sleep] in class: '.get_class($this));
	}
	private function __wakeup()
	{
		exit('<br/>Error: You are not allowed to use method [__wakeup] in class: '.get_class($this));
	}

/**
*  PUBLIC METHODS
*-------------------------------------------
*/
	public function __construct(){}
	public function __destruct(){}

	public function __unset( $var )
	{
		if ($this->restricted)
		{
			exit('<br/>Error: You are not allowed to use method [__unset] in class: '.get_class($this));
	        } 
		unset($var);
       }

	public function __isset( $name )
	{
		return isset($this->properties[$name]);
	}

	public function __toString()
	{
		$str = '';
		foreach($this->properties as $key=>$value)
		{
			$str .= $key . ' = '. $value. '<br/>';
		}
		return $str;
	}
	
	final public function __get( $name )
	{
		if ($this->restricted)
		{
			if (array_key_exists($name, $this->properties)) {
				return $this->properties[$name];
			}
		}
		else {
			if ($this->__isset($name)) {
				return $this->name;
			}
		}
		exit("<br/>Error: Property: [{$name}] was not found!");
	}

	final public function __set( $name, $value )
	{
		if ($this->restricted)
		{
			if (array_key_exists($name, $this->properties)) {
				$this->properties[$name] = $value;
			}
			else { exit("<br/>Error: Property: [{$name}] cannot be set!"); }
		}
		else { $this->name = $value; }
	}

	/**
	* Restrict access to class's properties to only the allowed properties.
	* @return $this
	*/
	final public function AllowedProperties( array $properties )
	{
		if ($this->restricted)
		{
			foreach( $properties as $prop )
			{
				$this->properties[$prop] = null;
			}
		}
		return $this;
	}


	/**
	* Whether or not to restrict access to class's properties.
	* @return $this
	*/
	final public function RestrictedAccess( $value )
	{
		$this->restricted = $value;
		return $this;
	}

}

Tests


/*
*    TESTS
*/

class Test extends SafeObject
{
	public function DoSomething() { echo 'Doing something...'; }
	public function DoSomethingElse() { echo 'Doing something else...'; }
}

$o = new Test();

$o->RestrictedAccess(true)
	->AllowedProperties(array('server','username')); /* << class Test can only have these two public properties */


// ok
$o->server = 'localhost';
echo '<br/>server: ' , $o->server;

// ok
$o->username = 'costin';
echo '<br/>username: ' , $o->username;

// NOT ok
unset($o->username);

// NOT ok
$o->test = 'test';
echo '<br/>test: ' , $o->test;

// __toString()
echo '<br/>' , $o;
?>

Note:

When the RestrictedAccess function’s argument is set to FALSE then that class allows the instantiation of public properties at run-time.

Categories: PHP Tags: ,

Protect your pages against sql injections

March 9, 2010 1 comment

The following function inspects the URL and looks for the (‘) apostrophe; if the apostrophe is found the url will be cut and the page reloaded using the cleaned url.

function CleanRequest


/**
* Remove ' (apostrophe) from URL and cut the url at the first occurrence of the apostrophe
* Prevent sql injections.
*
* @author: Costin Trifan
* @date: 06.05.2009
* @status: release
*/
function CleanRequest( $use = 'http' )
{
	$url = $_SERVER['REQUEST_URI'];
	$url = utf8_decode($url);
	if (($pos = strpos($url, '%27')) !== false)
	{
		$url = substr($url, 0, $pos);
		$url = $use.'://'.$_SERVER['HTTP_HOST'].$url;
		header("Location: ".$url); /*[ reload page using the cleaned url ]*/
		exit;
	}
}

This function can be called on individual pages but I find it to be more useful when called in a config.php file so it can be executed on all pages of a website.

Edit: March, 28 The $use argument has been removed.


/**
* Remove ' (apostrophe) from URL and cut the url at the first occurence of the apostrophe
* Prevent sql injections.
*
* @author: Costin Trifan
* @date: 06.05.2009
* @status: release
* @revision: March 28, 2010;
*	The $use argument has been removed.
*/
function CleanRequest()
{
	$use = 'http';
	if (isset($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] == "on")) {$use .= 's';}

	$url = $_SERVER['REQUEST_URI'];
	$url = utf8_decode($_SERVER['REQUEST_URI']);
	if (($pos = strpos($url, '%27')) !== false)
	{
		$url = substr($url, 0, $pos);
		$url = $use.'://'.$_SERVER['HTTP_HOST'].utf8_encode($url);
		header("Location: ".$url); /*[ reload page using the cleaned url ]*/
		exit;
	}
}
Categories: PHP Tags:

Compress output

January 18, 2010 Comments off

Remove new lines && multiple consecutive whitespaces from content


/**
 * Remove new lines && multiple consecutive whitespaces from content
 */
function compress( $content )
{
	$content = trim(ereg_replace("\n|\r|\r\n|\n\r", '', preg_replace('/\s+/', ' ', $content)));
	return $content;
}

class Syndication

December 19, 2009 Comments off

Notice: This class is subject to change.

interface ISyndication:

<?php

interface ISyndication
{
	function GetBaseTags();
	function GetTitles( $maxLimit );
	function GetEntries( $maxLimit );
}

?>

class FeedReaderBase:

The base class for parsing xml feeds.


<?php

	require_once __DIR__.DIRECTORY_SEPARATOR.'interface.isyndication.php';
/**
 * class FeedReaderBase
 *
 * The base class for parsing xml feeds.
 *
 * @author     	Costin Trifan 
 * @copyright  	2009 Costin Trifan
 * @licence    	MIT License:	http://en.wikipedia.org/wiki/MIT_License
 * @last update	Dec. 2009
 * @version    	1.0
 */
class FeedReaderBase implements ISyndication
{
	private function __clone(){}
	private function __sleep(){}
	private function __wakeup(){}

	final public function __get( $name ) { throw new Exception('Method: "__get" is not allowed in class: '.__CLASS__); }
	final public function __set( $name, $value ) { throw new Exception('Method: "__set" is not allowed in class: '.__CLASS__); }

	/*[[ MUST OVERRIDE ]]*/
	public function GetBaseTags(){}
	public function GetTitles( $maxLimit ){}
	public function GetEntries( $maxLimit ){}
}
/*[ end class ]*/

?>

Read more…

Categories: PHP Tags: ,

XLog – php logging class

December 17, 2009 1 comment

Notice: This class is subject to change.


<?php
/**
* class XLog
*
* The XLog is a PHP 5 oriented object class to log messages into one or multiple files.
* 
* @category   Log
* @author     Costin Trifan 
* @copyright  2009 Costin Trifan
* @licence    MIT License http://en.wikipedia.org/wiki/MIT_License
* @version    1.0
* 
* Copyright (c) 2009 Costin Trifan 
* 
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
* 
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
class XLog
{
	private function __clone() {}
	private function __wakeup() {}

	protected
		$log_file 	= '',	# The absolute path to the log file.
		$message 	= '',	# The message to write into the log file
		$line		= '',	# The line where the error has occurred [ ie: __LINE__ ]
		$file 		= '';	# The file where the error has occurred [ ie: __FILE__ ]

	# Error messages
	protected
		$error_file_not_found 	= "Error: Although you have enabled error logging, the log file could not be found!",
		$error_file_open 	= "Error: Couldn't open the log file. Check for permissions!",
		$error_no_message       = "Error: The content to write into the log file is missing...";



	/**
	* Constructor
	*
	* @param string $log_file The absolute path to the log file.
	*/
	public function __construct( $log_file='' )
	{
		$this->SetLogFile($log_file);
	}


	/**
	* Set the active log file.
	*
	* @access private
	* @return void
	*/
	private function SetLogFile( $log_file='' )
	{
		if ($log_file)
			$this->log_file = $log_file;
	}


	/**
	* Check to see whether or not the log file exists.
	*
	* @access private
	* @return boolean
	*/
	private function FileExists( $log_file )
	{
		return file_exists($log_file);
	}


	/**
	* Clear the log file
	*/
	public function Clear( $log_file='' )
	{
		if (!$log_file)
			$log_file = $this->log_file;

		if (!$this->FileExists($log_file))
			$this->ExitWithError($this->error_file_not_found);
	
		if (($h = fopen($log_file, "w")) !== FALSE)
			fclose($h);
		else
			$this->ExitWithError($this->error_file_open);
	}


	/**
	* Show the content from the log file
	*
	* @param string $log_file The absolute path to the log file.
	* @return string
	*/
	public function GetContent( $log_file='' )
	{
		if (!$log_file)
			$log_file = $this->log_file;

		if (!$this->FileExists($log_file))
			$this->ExitWithError($this->error_file_not_found);

		# Check if the file is php; if it is, remove php's tags and comments
		$info = pathinfo($log_file);
		$file_extension  = strtoupper($info['extension']);


		if (($h = @fopen($log_file, "r")) !== FALSE)
		{
			# Get content
			$content = file_get_contents($log_file);
			@fclose($h);

			if ($file_extension == 'PHP')
			{
				$begin_file = '';

				$content_length 	= strlen($content);
				$begin_file_length 	= strlen($begin_file);
				$end_file_length 	= strlen($end_file);
				# Strip php's tags and comments
				$content 			= substr($content, $begin_file_length, -$end_file_length);
			}
		}
		return html_entity_decode($content, ENT_QUOTES, "UTF-8");
	}


	/**
	* Write into the log file
	*
	* @param string $message The message to write into the log file.
	* @param string $file  The file where the error has occurred [ ie: __FILE__ ].
	* @param number $line The line where the error has occurred [ ie: __LINE__ ].
	* @param boolean $clear_before Whether or not to delete the existent content from the log file before writting the new one.
	* @param string $log_file The absolute path to the log file.
	*
	* @return void
	*/
	public function Write($message='', $file=NULL, $line=NULL, $clear_before=FALSE, $log_file='')
	{
		if (!$message) $this->ExitWithError($this->error_no_message);
	
		# Setup arguments
		$this->message  = htmlentities($message, ENT_QUOTES, "UTF-8");
		$this->file		= $file;
		$this->line		= $line;
	
		if ($log_file)
			$this->log_file = $log_file;

		if (!$this->FileExists($this->log_file))
			$this->ExitWithError($this->error_file_not_found);

		if ($clear_before)
			$this->Clear($this->log_file);

		# Detect the file's extension so the appropriate function can be called
		$info = pathinfo($this->log_file);
		$file_extension  = strtoupper($info['extension']);

		switch ($file_extension)
		{
			case 'INI' 	: $this->WriteIni(); break;
			case 'PHP' 	: $this->WritePhp(); break;
			default 	: $this->WriteAny(); break;
		}
	}


	/**
	* Write log into an ini file
	*
	* @access protected
	*/
	protected function WriteIni()
	{
		if (($h = fopen($this->log_file, "r+")) !== FALSE)
		{
			$initial_content = file_get_contents($this->log_file);
		
			$br = "\r\n";
			$content  = $br.";---------------------------------------------------------------------------------------".$br;
			$content .= "Date \t= ".date("M d Y H:i:s", time()).$br;
			$content .= "IP \t= ".$_SERVER['REMOTE_ADDR'].$br;
			$content .= "Page \t= ".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$br;
			$content .= "File \t= ".$this->file.$br;
			$content .= "Line \t= ".$this->line.$br;
			$content .= "Error \t= ".$this->message.$br;
			$content .= ";---------------------------------------------------------------------------------------".$br;
			$content .= $br.$initial_content;

			$content = trim($content);
			@fwrite($h, $content, strlen($content));
			@fclose($h);
		}
		else $this->ExitWithError($this->error_file_open);
	}


	/**
	* Write log into a php file
	*
	* @access protected
	*/
	protected function WritePhp()
	{
		if (($h = fopen($this->log_file, "r+")) !== FALSE)
		{
			$br 		= "\r\n";
			$begin_file = '';

			$initial_content = trim(file_get_contents($this->log_file));

			$content_length 	= strlen($initial_content);
			$begin_file_length 	= strlen($begin_file);
			$end_file_length 	= strlen($end_file);
			# Strip php's tags and comments
			$initial_content 	= substr($initial_content, $begin_file_length, -$end_file_length);


			$content  = "[".date("M d Y H:i:s", time())."]".$br;
			$content .= "---------------------------------------------------------------------------------------".$br;
			$content .= "IP: \t".$_SERVER['REMOTE_ADDR'].$br;
			$content .= "Page: \t".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$br;
			$content .= "File: \t".$this->file.$br;
			$content .= "Line: \t".$this->line.$br;
			$content .= "Error: \t".$this->message.$br;
			$content .= "---------------------------------------------------------------------------------------".$br;
			$content .= $initial_content;

			$content = trim($content);
			$content = $begin_file.$br.$content.$br.$end_file;
			@fwrite($h, $content, strlen($content));
			@fclose($h);
		}
		else $this->ExitWithError($this->error_file_open);
	}


	/**
	* Write log into any other file type
	*
	* @access protected
	*/
	protected function WriteAny()
	{
		if (($h = fopen($this->log_file, "r+")) !== FALSE)
		{
			$initial_content = file_get_contents($this->log_file);
		
			$br = "\r\n";
			$content  = "[".date("M d Y H:i:s", time())."]".$br;
			$content .= "---------------------------------------------------------------------------------------".$br;
			$content .= "IP: \t".$_SERVER['REMOTE_ADDR'].$br;
			$content .= "Page: \t".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$br;
			$content .= "File: \t".$this->file.$br;
			$content .= "Line: \t".$this->line.$br;
			$content .= "Error: \t".$this->message.$br;
			$content .= "---------------------------------------------------------------------------------------".$br;
			$content .= $br.$initial_content;

			$content = trim($content);
			@fwrite($h, $content, strlen($content));
			@fclose($h);
		}
		else $this->ExitWithError($this->error_file_open);
	}


	/**
	* Get the size of the log file.
	* Original source code: http://www.php.net/manual/en/function.filesize.php#84034
	*
	* @return string
	*/
	public function GetFileSize( $log_file='', $round=0 , $add_space=TRUE)
	{
		if (!$log_file)
			$log_file = $this->log_file;

		$size 	= filesize($log_file);
		$sizes 	= array('B', 'KB', 'MB', 'GB');
		$total 	= count($sizes);

		for ($i=0; $size > 1024 && $i < $total; $i++)
			$size /= 1024;

		if ($add_space)
			return round($size,$round).' '.$sizes[$i];
		else
			return round($size,$round).$sizes[$i];
	}


	/**
	* Display the error message
	*
	* @param string $error_message The message to be displayed in case of an error.
	* @access protected
	* @return void
	*/
	protected function ExitWithError( $error_message='' )
	{
		exit("".$error_message."");
	}

}
/*[ end class ]*/
?>

Usage:


<?php
include "class.XLog.php";

$log = new XLog();

# SET THE PATH TO THE LOG FILE
$log_file_php 	= $_SERVER['DOCUMENT_ROOT'].'/xlog/logs/log.php';

# The message
$msg_php 	= "A log entry into a php file";

# Log messages in a php file
$log->Write($msg_php, __FILE__, __LINE__, FALSE, $log_file_php);
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>Using the XLog class</title>
</head>
<body>

<h4 style="font-weight: normal;">The content of the log file <strong><?php echo $log_file_php;?></strong> is displayed below:</h4>

<p>The size of the log file is: <strong><?php echo $log->GetFileSize($log_file_php);?></strong></p>

<div style="margin: 25px; border: solid 1px #ccc; padding: 5px;">
	<pre><?php echo $log->GetContent($log_file_php);?></pre>
</div>

</body>
</html>
Categories: PHP Tags: ,

Class Cache

December 17, 2009 1 comment

Notice: This class is not for public usage and is subject to change.


<?php
/**
 * Class Cache. A caching class. Requires PHP 5+
 *
 * @package    		Cache
 * @category   		Caching
 * @author     		Costin Trifan 
 * @copyright  		2009 Costin Trifan
 * @licence    		Attribution-NonCommercial-NoDerivs 2.5	http://creativecommons.org/licenses/by-nc-nd/2.5/legalcode
 * @version    		1.0
 * @last-update		dec.2009
 *
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE").
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS
 * LICENSE OR COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE.
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 
 *
 *	http://creativecommons.org/licenses/by-nc-nd/2.5/legalcode
 */
class Cache
{

	private function __clone(){}
	private function __sleep(){}
	private function __wakeup(){}

	public function __get( $name ) { return null; }
	public function __set( $name, $value ) { }


# PROTECTED PROPERTIES
#======================

	protected
		 $_cacheDir = "cache/"
		,$_cacheLifetime = 3600
		;

	private $_cacheFileExt = '.php';



# PUBLIC METHODS
#======================

	public function __construct( $cacheDir, $createCacheDir = false, $cacheLifetime = 3600 )
	{
		if ( ! is_dir($cacheDir) )
		{
			if ($createCacheDir) {
				mkdir($cacheDir, 0775);
			}
			else exit('The cache directory was not found!');
		}
		if ( is_writable($cacheDir) ) {
			$this->SetCacheDir($cacheDir);
		}
		else { exit("The cache directory '$cacheDir' is not writable! Check permissions."); }

		$this->SetCacheLifetime($cacheLifetime);
	}


	public function Cache( $file )
	{
		$savefilepath = $this->_setFilePath($file);

		if ( ! file_exists($file)) { return $this; }

/*
 *	TODO:
 *
 * :: execute php code inside templates
---------------------------------------
		$data = '';
		ob_start();
			include_once $file;
			$data = ob_get_contents();
		ob_end_clean();


*/
		$data = file_get_contents($file, false);
		$data = htmlentities($data, ENT_QUOTES);
		file_put_contents($savefilepath, $data);
		return $this;
	}


	public function CacheBlock( $file, $content )
	{
		$savefilepath = $this->_setFilePath($file);

		if ( ! file_exists($file)) { return $this; }

		$data = htmlentities($content, ENT_QUOTES);
		file_put_contents($savefilepath, $data);

		return $this;
	}


	public function Get( $file )
	{
		$fpath = $this->_setFilePath($file);

		$data = '';

		if ( $this->_isCached($fpath) )
		{
			$data = file_get_contents($fpath);
			$data = html_entity_decode($data, ENT_QUOTES);
		}
		return $data;
	}


	/**
	 * Att! Not to be used internally!
	 * Use the private _IsCached($file) instead!!
	 */
	public function IsCached( $file )
	{
		return $this->_IsCached($this->_setFilePath($file));
	}


	/**
	* Delete all files from the cache directory.
	*
	* return $this
	*/
	public function EmptyDirectory()
	{
		$files = $this->_getCachedFiles();
		if (count($files) > 0) {
			foreach ($files as $file)
				unlink($file);
		}
		return $this;
	}

	/**
	* Delete a cached template.
	*
	* param string $fileNames  The name(s) of the file(s) to delete.
	* return $this
	*/
	public function Delete(/* [ $fileName, $fileName,...] */)
	{
		$files = func_get_args();
		if (count($files) > 1) {
			foreach ($files as $file) {
				$_file = $this->_setFilePath($file);
				if (file_exists($_file)) {
					unlink($_file);
				}
			}
		}
		return $this;
	}



	public function SetCacheDir( $dir )
	{
		$this->_cacheDir = $dir;
                return $this;
	}

	public function GetCacheDir()
	{
		return $this->_cacheDir;
	}

	public function SetCacheLifetime( $seconds )
	{
		if (is_numeric($seconds)) {
			$this->_cacheLifetime = $seconds;
		}
		return $this;
	}

	public function GetCacheLifetime()
	{
		return $this->_cacheLifetime;
	}






# PRIVATE METHODS
#======================

	private function _encodeName( $file )
	{
		return md5(basename($file));
	}


	private function _setFilePath( $file )
	{
		$file = $this->_cacheDir.$this->_encodeName($file).$this->_cacheFileExt;
		return $file;
	}


	private function _isCached( $file )
	{
		$_cached = false;

		if (file_exists($file)) /*[ requires $file to be encoded !! ]*/
		{
			clearstatcache();

			if (filemtime($file) > (time() - $this->_cacheLifetime)) {
				$_cached = true;
			}
		}
		return $_cached;
	}


	/**
	* Get all files from the cache directory.
	* access protected
	* return array
	*/
	private function _getCachedFiles()
	{
		$fileList = array();
		$fileCount = 0;

		if ($dir = opendir($this->_cacheDir))
		{
			while ($file = readdir($dir))
			{
				if ($file != '.' && $file != '..')
				{
					$finfo = pathinfo($file);
					$fext = '.' . $finfo['extension'];

					if (strcasecmp($fext, $this->_cacheFileExt) == 0)
					{
						array_push($fileList, $file);
						$fileCount++;
					}
				}
			}
			closedir($dir);
		}
		return $fileList;
	}


}
/*[ end class ]*/
?>
Categories: PHP Tags: ,

Template Engine class

December 16, 2009 Comments off

Notice: This class is not for public usage and is subject to change.


<?php
/**
 * Class Template. A template engine class. Requires PHP 5+
 *
 * @package    		Template
 * @category   		Template
 * @author     		Costin Trifan 
 * @copyright  		2009 Costin Trifan
 * @licence    		Attribution-NonCommercial-NoDerivs 2.5	http://creativecommons.org/licenses/by-nc-nd/2.5/legalcode
 * @version    		1.0
 * @last-update		dec.2009
 *
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE").
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS
 * LICENSE OR COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE.
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 
 *
 *	http://creativecommons.org/licenses/by-nc-nd/2.5/legalcode
 */
class Template
{

	private function __clone(){}
	private function __sleep(){}
	private function __wakeup(){}

	/**
	 * RESTRICT ACCESS TO CLASS'S GLOBAL VARIABLES
	 (=============================================)
	 */

	public function __get( $name )
	{
		if (isset($this->_vars[$name]) and !empty($this->_vars[$name]))
		{
			return $this->_vars[ $name ];
		}
		else return null;
	}

	public function __set( $name, $value )
	{
		$this->_vars[$name] = $value;
	}



	private
		 $_tplDir = 'tpl/'		# The name of the folder where the template files are supposed to be stored.
		,$_vars = array()		# The class's variables array.
		,$_leftDel = '{'		# The left delimiter to use in the templates files to mark a template variable.
		,$_rightDel = '}'		# The right delimiter to use in the templates files to mark a template variable.
		,$_cacheObj = null		# Holds the instance of the ClibCache class
			;


	/**
	 * .ctor
	 */
	public function __construct( $tplDir = '', $cacheObj = null, $leftDelimiter = '{', $rightDelimiter = '}' )
	{
		if (isset($tplDir) and trim($tplDir) != '') {
			$this->_tplDir = $tplDir;
		}
		if (isset($cacheObj) and (! is_null($cacheObj)) ) {
			$this->_cacheObj = $cacheObj;
		}
		if (isset($leftDelimiter) and trim($leftDelimiter) != '{') {
			$this->_leftDel = $leftDelimiter;
		}
		if (isset($rightDelimiter) and trim($rightDelimiter) != '}') {
			$this->_rightDel = $rightDelimiter;
		}
	}



	/**
	* Add a variable to the vars array. This variable will be replaced in a template.
	*
	* param string $name  The name of the variable to store in the vars array.
	* param mixed $value  The value of the variable.
	* return $this
	*/
	public function SetVar( $name, $value )
	{
		$this->__set( $name, $value );
		return $this;
	}


	/**
	* Get a variable from the vars array.
	*
	* param string $name  The name of the variable to retrieve from the vars array.
	* return mixed
	*/
	public function GetVar( $name )
	{
		return $this->__get( $name );
	}


	/**
	* Delete all variables from the vars array.
	*
	* return $this
	*/
	public function ClearVars()
	{
		$this->_vars = array();
		return $this;
	}


	/**
	* Get all variables from the vars array.
	*
	* return array
	*/
	public function GetAllVars()
	{
		return $this->_vars;
	}



	/**
	* Retrieve the content of a template.
	*
	* param string $template  	The name of the template file to load.
	* param bool $getCached  	Whether or not to load the chached version of the $template
	* return string  The template's html content.
	*/
	function GetFile( $fileName, $getCached = false )
	{
		$data = '';

		$dir = ( $getCached ) ? $this->_cacheObj->GetCacheDir() : $this->_tplDir;

		if ($getCached) { $data = $this->_cacheObj->Get($dir.$fileName); }
		else {
			$file = $dir.$fileName;
			if ( file_exists($file) ) {
				$data = $this->Parse( $file );
			}
		}
		return $data;
	}


	/**
	* Outputs the template's html content.
	*
	* param string $fileName  The name of the template file to load.
	* param bool $getCached  	Whether or not to load the chached version of the $fileName
	* return $this
	*/
	function Display( $fileName, $getCached = false )
	{
		echo $this->GetFile( $fileName, $getCached );
		return $this;
	}




	/**
	* Replaces the variables from the specified template file.
	*
	* access protected
	* param string $file  The name of the template file to load.
	* return string  The template's parsed content.
	*/
	protected function Parse ( $file )
	{
		$content = '';

		ob_start();
			include_once $file;
			$content = ob_get_contents();
		ob_end_clean();

		if ($content == '') { return $content; }

		// make sure there is something to parse
		if ( ($pos = strpos($content, $this->_leftDel)) === FALSE ) { return $content; }

		if (count($this->_vars) > 0)
		{
			foreach($this->_vars as $name => $value)
			{
				if (is_string($value))
				{
					$var = $this->_leftDel. $name .$this->_rightDel;
					$content = str_ireplace($var, $value, $content);
				}
			}
		}
		return $content;
	}



	/**
	* Replaces the variables from the specified content block.
	*
	* access protected
	* param string $block  The content to be parsed.
	* return string  The parsed content.
	*/
	private function _parseBlock ( $data )
	{
		$content = '';

		if ($data == '') { return $content; }

		// make sure there is something to parse
		if ( ($pos = strpos($content, $this->_leftDel)) === FALSE ) { return $content; }

		if (count($this->_vars) > 0)
		{
			foreach($this->_vars as $name => $value)
			{
				if (is_string($value))
				{
					$var = $this->_leftDel. $name .$this->_rightDel;
					$content = str_ireplace($var, $value, $content);
				}
			}
		}
		return $content;
	}

}
/*[ end class ]*/
?>
Categories: PHP Tags: ,