<?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 20022003 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
}
}
?>