<?php
/**
* PHP Text Cache is a simple caching class for for saving/retrieving local copies of url data
* @package php_text_cache

* @copyright (C) 2004 John Heinstein. All rights reserved
* @license  http://www.gnu.org/copyleft/lesser.html LGPL License
* @author John Heinstein <johnkarl@nbnet.nb.ca>
* @link http://www.engageinteractive.com/php_text_cache/ PHP Text Cache Home Page
* PHP Text Cache is Free Software
**/

if (!defined('PHP_TEXT_CACHE_INCLUDE_PATH')) {
	define('PHP_TEXT_CACHE_INCLUDE_PATH',  "include/domit/");
}

require_once(PHP_TEXT_CACHE_INCLUDE_PATH . 'php_http_connector.php');

/**
* A simple caching class for saving/retrieving local copies of url data
*
* @package php_text_cache
* @author John Heinstein <johnkarl@nbnet.nb.ca>
*/
class php_text_cache extends php_http_connector {
	/** @var string The directory in which cached files are stored */
	var $cacheDir;
	/** @var int The amount time of time to wait before a cached file should be updated  */
	var $cacheTime;
	
	/**
	* Constructor
	* @param string Directory in which to store the cache files
	* @param int Expiry time for cache file (-1 signifies no expiry limit)
	*/
	function php_text_cache($cacheDir = './', $cacheTime = -1) {
		$this->cacheDir = $cacheDir;
		$this->cacheTime = $cacheTime;
	} //php_text_cache	
	
	
	/**
	* Gets data from an url, or its cache file
	* 
	* @param string The url of the data
	* @return string The data at the specified url
	*/
	function getData($url) {
		$cacheFile = $this->getCacheFileName($url);

		if (is_file($cacheFile)) {
			$fileStats = stat($cacheFile);
			$lastChangeTime = $fileStats[9]; //mtime
			$currTime = time();

			if (($this->cacheTime != -1) && ($currTime - $lastChangeTime) > $this->cacheTime) { //get data from url	
				return $this->fromURL($url, $cacheFile);
			}
			else { //get data from file	
				return $this->fromCache($cacheFile);				
			}			
		}
		else {
			return $this->fromURL($url, $cacheFile);
		}
	} //getData
	
	/**
	* Given an url, returns the path to the cache file
	* 
	* Uses an md5 hash of the url. This can be 
	* overridden if a different approach is required
	* 
	* @param string The url of the data
	* @return string The cache file name 
	*/
	function getCacheFileName($url) {
		return ($this->cacheDir . md5($url));
	} //getCacheFileName
	
	/**
	* Establishes a connection, given an url
	* @param string The url of the data
	*/
	 function establishConnection($url) { 
                require_once(PHP_TEXT_CACHE_INCLUDE_PATH . 'php_http_client_generic.php'); 
                
//                $host = php_http_connection::formatHost($url); 
//                $host = substr($host, 0, strpos($host, '/')); 
                $host = parse_url($url,PHP_URL_HOST); 
                $port = parse_url($url,PHP_URL_PORT);         
                if (!isset($port)){ 
                        $port=80; 
                } 
                $this->setConnection($host,"/",$port); 
        } //establishConnection
	
	/**
	* Gets data from an url and caches a copy of the data
	* @param string The url for the data
	* @param string The cache file path
	* @return string The contents of the url
	*/
	function fromURL($url, $cacheFile) {
		$fileContents = '';
		$_filename = strtolower($url);
		//if it's not a url or it's not from our cache dir don't let it through
		if(substr($_filename, 0,7) !== 'http://' && substr($_filename, 0,6) !== 'rss://' && substr($_filename, 0,8) !== 'https://' && substr($_filename, 0,strlen($this->cacheDir)) !== strtolower($this->cacheDir)){
			$GLOBALS['log']->debug('RSS - ILLEGAL PATH - ' . $_filename );
			return '';	
		}
		// make sure they don't hop out of our cache dir
		$url = str_replace('..', '', $url);
		if ($this->httpConnection != null) {
			$response = $this->httpConnection->get($url);
			$fileContents = $response->getResponse();
		}
		else {
			$fileContents = $this->fromFile($url);						
		}

		//if file is empty, might need to establish an
		//http connection to get the data
		if ($fileContents == '') {
			$this->establishConnection($url);
			$response = $this->httpConnection->get($url); 
			if ( $response )
			{
				$fileContents = $response->getResponse();
			}
		}
// R. Rangel 3/16/2005
// strip out everything before the "<rss " tag just in case..		
		if (strstr($fileContents, "<rss ")) $fileContents = stristr($fileContents,'<rss ');

		if ($fileContents != '') {
			require_once(PHP_TEXT_CACHE_INCLUDE_PATH . 'php_file_utilities.php');
			php_file_utilities::putDataToFile($cacheFile, $fileContents, 'w');
		}
		return $fileContents;
	} //fromURL
	
	/**
	* Get text from cache file
	* @param string The file path
	* @return string The text contained in the file, or an empty string
	*/
	function fromCache($cacheFile) {
		return $this->fromFile($cacheFile);
	} //fromCache
	
	/**
	* Get text from an url or file
	* @param string The url or file path
	* @return string The text contained in the url or file, or an empty string
	*/
	function fromFile($filename) {
		if (function_exists('file_get_contents')) {
			return @file_get_contents($filename);
		}
		else {
			require_once(PHP_TEXT_CACHE_INCLUDE_PATH . 'php_file_utilities.php');
			$fileContents = php_file_utilities::getDataFromFile($filename, 'r');
			return $fileContents;
		}
		
		return '';
	} //fromFile
} //php_text_cache

?>
