Location: PHPKode > projects > Tv.2 CMS > tv2engine/ctlUrlMapper.class.php
<?php
/** 
 * @constant int MAP_FULL 
 * @package pyramid-framework
 */
define('MAP_FULL', 1);
/** 
 * @constant int MAP_PARTIAL 
 * @package pyramid-framework
 */
define('MAP_PART', 2);
/** 
 * @constant int MAP_DEFAULT 
 * @package pyramid-framework
 */
define('MAP_DEFAULT', 3);

/**
 * This class analyzes URL and calls the appropriate module.
 *
 * @package pyramid-framework
 * @author Emilis Dambauskas (hide@address.com)
 * @copyright 2002–2003 Emilis Dambauskas under {@link http://opensource.org/licenses/artistic-license.php Artistic license}
 * @version $Id: ctlUrlMapper.class.php,v 1.2 2003/07/21 15:42:44 lunaticlt Exp $
 * @class ctlUrlMapper
 */
class ctlUrlMapper
{
	/** 
	 * Relative url from {@link SITE_BURL}
	 * @attribute private string $url
	 */
	var $url;
	
	/**
	 * Array containing "addresses" of modules
	 * @attribute private array $map
	 */
	var $map;
	
	/**
	 * Constructor. Gets URL into $url attribute, creates other attributes.
	 *
	 * @constructor ctlUrlMapper
	 * @return object Returns ctlControl object.
	 */
	function ctlUrlMapper()
	{
		// 1. Lets fill other attributes with default values:
		$this->url = '';
		$this->map = array(); // filename relative to your script
	}
	
	/**
	 * Fills $this->map with values from an array or file
	 *
	 * @method public loadMap
	 * @return boolean TRUE on success, FALSE onfailure
	 * @param mixed $mymap Name of file containing map or map array itself
	 */
	function loadMap($mymap)
	{
		// 1. Either our map is a filename containing $map array
		if (is_string($mymap))
		{
			include($mymap);
			return ($this->map = $map);
		}
		// 2. Or it is the array itself
		else if (is_array($mymap))
			return ($this->map = $mymap);
		// 3. And maybe there's an error:
		else
			return FALSE;
	}
	
	/**
	 * Returns partial or full URL. Partial URLs are relative to {@link SITE_URL}.
	 *
	 * @method public getUrl
	 * @return string URL
	 * @param optional boolean $full Should the URL returned be full or partial? (Default: partial).
	 * @use $protocol
	 * @use SITE_URL
	 * @todo It still needs to be tested if HTTP/HTTPS matching can be used conveniently.
	 */
	function getUrl($full = FALSE)
	{
		// 1. Partial URL is returned:
		if (!$full)
			return $this->url;
		// 2. Else URL is full:
		else
		{
			global $protocol;
			
			// 3. Lets find out if the protocol used is HTTP or HTTPS:
			$prot = $protocol->getServerVar('SERVER_PROTOCOL');
			if (($prot === 'HTTP/1.1' || $prot === 'HTTP/1.0') && $protocol->getServerVar('SERVER_PORT') == 80)
				$prot = 'http://';
			else if ($protocol->getServerVar('SERVER_PORT') == 43)
				$prot = 'https://';
			
			// 4. We add an ending to the URL, so that you don't have to worry about 
			// ? or & when adding GET parameters to the URL in your string
			if (strstr(SITE_URL, '?'))
				return $prot.SITE_URL.$this->url.'&';
			else
				return $prot.SITE_URL.$this->url.'?';
		}
	}
	
	/**
	 * Creates and returns full URL made of partial URL $url and optional 
	 * additional GET parameters.
	 * 
	 * @method public buildUrl
	 * @return string URL
	 * @param string $url partial URL
	 * @param optional string $par Parameter part of the URL (e.g. var1=val1&var2=val2)
	 * @use $protocol
	 * @use SITE_URL
	 * @todo It still needs to be tested if HTTP/HTTPS matching can be used conveniently.
	 */
	function buildUrl($url, $par = '')
	{
		global $protocol;
			
		// 1. Lets find out if the protocol used is HTTP or HTTPS:
		$prot = $protocol->getServerVar('SERVER_PROTOCOL');
		if (($prot === 'HTTP/1.1' || $prot === 'HTTP/1.0') && $protocol->getServerVar('SERVER_PORT') == 80)
			$prot = 'http://';
		else if ($protocol->getServerVar('SERVER_PORT') == 43)
			$prot = 'https://';
		
		// 2. If SITE_URL contains '?' (e.g. you have server.com/index.php?url=) 
		// then we should use '&' to separate parameters
		if (strstr(SITE_URL, '?'))
			return $prot.SITE_URL.$url.'&'.$par;
		else
			return $prot.SITE_URL.$url.'?'.$par;
	}
	
	/**
	 * Maps partial URL to the appropriate module.
	 * Calls {@link $site->showIndex()} or $this->runModule, 
	 * or {@link $site->showError(404)}
	 * 
	 * @method public doMapping
	 * @return string HTML of the page
	 * @param string $url URL from request
	 * @use $protocol
	 * @use $site
	 * @use MAP_FULL
	 * @use MAP_PARTIAL
	 */
	function doMapping($url)
	{
		global $site;
		
		// 1. We can't procede without map loaded:
		if (!sizeof($this->map))
			return FALSE;
		
		// 2. Lets get rid of begining and ending slashes in URL:
		$url = trim($url, '/');
		$this->url = $url;
		
		// 3. If url is empty it means we've got index page:
		if (!$url)
			return $site->showIndex();
		
		// 4. If $url can be found between full urls:
		if (isset($this->map[MAP_FULL][$url]))
			return $this->runModule($this->map[MAP_FULL][$url]);
		
		// 5. Else we check partial urls in our map.
		$urls = explode('/', $url);
		$nurls = array();
		$turl = $this->url;
		
		while (sizeof($urls))
		{
			$url = implode('/', $urls);
			$this->url = $url;
			
			if (isset($this->map[MAP_PART][$url]))
				return $this->runModule($this->map[MAP_PART][$url],$nurls);
			
			array_unshift($nurls, array_pop($urls));
		}
		
		// 6. If we haven't found the url in our map we return an error:
		if (isset($this->map[MAP_DEFAULT]))
		    return $this->runModule($this->map[MAP_DEFAULT], $this->url);
		else
		{
		    $this->url = $turl;
		    return $site->showError(404);
		}
	}

	/**
	 * This method loads a module and returns result from the module's method.
	 * 
	 * @method private runModule
	 * @return string output from module
	 * @param array $addr module "address" from map
	 * @param optional array $nurls remaining part of the URL split by '/'
	 * @use CLASS_DIR
	 * @use $site
	 */
	function runModule($addr,$nurls = NULL)
	{
		$fname = $addr[0]; // module file name
			
		// 1. we check if the filename is absolute or relative:
		if ($fname{0} == '/' || $fname{1} == ':' || $fname{0} == '\\')
			include_once($fname);
		else
			include_once(CLASS_DIR.$fname);
			
		// 2. Let's set up $site object:
		global $site;
		if (@$addr[3]) // site method name
			$site->setMethod($addr[3]);
			
		// 3. We create the module and call it's method:
		$module = &new $addr[1](); // module class
		return $module->$addr[2]($nurls); // module method
	}
	
}
?>
Return current item: Tv.2 CMS