<?php //$Id$
//Copyright (c) 2012-2017 Pierre Pronchery <khorben@defora.org>
//This file is part of DeforaOS Web DaPortal
//
//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, version 3 of the License.
//
//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.
//
//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.



//HTTPFriendlyEngine
class HTTPFriendlyEngine extends HTTPEngine
{
	//public
	//methods
	//essential
	//HTTPFriendlyEngine::match
	public function match()
	{
		if(($score = parent::match()) != 100)
			return $score;
		return $score + 1;
	}


	//accessors
	//HTTPFriendlyEngine::getRequest
	public function getRequest()
	{
		return parent::getRequest();
	}

	protected function _getRequestDo()
	{
		//XXX hack to avoid testing twice for idempotence
		if($this->request !== FALSE)
			return $this->request;
		if(!isset($_SERVER['PATH_INFO']))
			return parent::_getRequestDo();
		$path = explode('/', $_SERVER['PATH_INFO']);
		if(!is_array($path) || count($path) < 2)
			return parent::_getRequestDo();
		//the first element is empty
		array_shift($path);
		//the second element is the module name
		if(($module = array_shift($path)) == '')
			return parent::_getRequestDo();
		$action = FALSE;
		$id = FALSE;
		$title = FALSE;
		$type = FALSE;
		$extension = FALSE;
		$args = FALSE;
		if(count($path) > 0)
		{
			//the third element is the action (or the ID directly)
			$id = array_shift($path);
			if(!is_numeric($id))
			{
				//there is an action before the ID
				$action = $id;
				$id = FALSE;
				if(count($path) > 0 && is_numeric($path[0]))
					$id = array_shift($path);
			}
		}
		if(count($path) > 0)
			$title = implode('/', $path);
		//arguments
		//XXX is there a function to do this directly?
		$query = explode('&', $_SERVER['QUERY_STRING']);
		foreach($query as $q)
		{
			$q = explode('=', $q);
			if(count($q) < 2)
				continue;
			if($args === FALSE)
				$args = array();
			$q0 = urldecode(array_shift($q));
			$q1 = urldecode(implode('=', $q));
			if($title === FALSE && $q0 == '_title')
				$title = $q1;
			else if($q0 == '_type')
				$type = $q1;
			else if(($pos = strpos($q0, '[')) !== FALSE
					&& $pos > 0 && substr($q0, -1) == ']')
			{
				//convert to an array as really expected
				$key = substr($q0, 0, $pos);
				$value = substr($q0, $pos + 1, -1);
				if(!isset($args[$key]))
					$args[$key] = array($value);
				else
					$args[$key][] = $value;
			}
			else
				$args[$q0] = $q1;
		}
		$this->request = new Request($module, $action, $id, $title,
			$args);
		if($type !== FALSE && strlen($type) > 0)
			$this->request->setType($type);
		if($this->getDebug())
			$this->_getRequestDebug();
		return $this->request;
	}


	//HTTPFriendlyEngine::getURL
	public function getURL(Request $request = NULL, $absolute = TRUE)
	{
		global $config;
		$secure = $config->get('engine::http', 'secure');

		//use the kicker if defined
		if(($kicker = $config->get($this->section, 'kicker'))
				!== FALSE && strlen($kicker) > 0)
			$name = dirname($_SERVER['SCRIPT_NAME']).'/'.$kicker;
		else
			$name = $_SERVER['SCRIPT_NAME'];
		$name = ltrim($name, '/');
		if((!$this->isHTTPS() && $secure) || $absolute)
			$url = $this->_getURLAbsolute($name, $secure);
		else
			//prepare a relative address
			$url = basename($name);
		//return if already complete
		if(is_null($request)
				|| ($module = $request->getModule()) === FALSE)
			return $url;
		//handle the main parameters
		$url .= '/'.$module;
		if(($action = $request->getAction()) !== FALSE)
			$url .= '/'.$action;
		if(($id = $request->getID()) !== FALSE)
			$url .= '/'.$id;
		if(($title = $request->getTitle()) !== FALSE)
		{
			if($action === FALSE && $id === FALSE)
				$url .= '/default';
			$title = str_replace(array(' ', '?', '#'),
					array('%20', '%3F', '-'), $title);
			if($config->get($this->section, 'lowercase'))
				$title = strtolower($title);
			$url .= '/'.$title;
		}
		//handle arguments
		if($request->isIdempotent()
				&& ($args = $request->getParameters())
				!== FALSE)
		{
			$sep = '?';
			foreach($args as $key => $value)
				$url .= $this->_getURLParameter($key, $value,
						$sep);
		}
		return $url;
	}


	//private
	//properties
	private $section = 'engine::httpfriendly';
}

?>
