<?php

// установить в 1, чтобы функция debug() вернула истину
define('SIMPLEURL_DEBUG', 0);

// класс для поддержки работы с web-страницами
// (с) Михаил Молочников, mikhail@molochnikov.com
// начало разработки: 10 сентября 2010
// версия 0.2

/*
  Правильный вид URL-ов



  [0,1]. город РФ ИЛИ название страны ИЛИ название страны + город (необязательный)
  /moscow/
  /vladivostok/
  /italy/
  /ukraine/kiev/
  [2]. раздел сайта (обязательный)
  /office/
  /warehouse/
  ...
  /help/
  [2]. раздел справочника (обязательный в основных разделах)
  /catalog/
  /billboard/
  [3]. наименование объекта (необязательный)
  /gulliver/
  [4]. подраздел сайта (необязательный)
  /newbuilding/
  [5]. аренда или продажа или инвестиции (на текущий момент если аренда, то не выдаем, продажа есть всегда)
  /rent/
  /sale/
  /investment/
  [6]. номер страницы и прочие опции (необязательный, если не задан, то page=1)
  /catalog/3/
  [7]. на последнем месте index.aspxpor - для совместимости
  /catalog/index.aspx

  [8]. если встречается debug, то выдаем служебную информацию

  иначе: ошибка 404

  примеры:
  /moscow/office/catalog/under-construction/
  /moscow/office/catalog/under-construction/sale/
  /moscow/office/billboard/rental-requests/
         /office/
         /investments/partners/
         /help/registration/


  ТИПЫ СТРАНИЦ
  1. Главная страница сайта
     Код: homepage
  Ничего не задано в параметрах

  2. Страница региона
     Код: regions
  Если задан раздел сайта, но не задан регион

  3. Страница города
     Код: region
  Если задан город, но не задан раздел

  4. Страница раздела
     Код: rubricator
  Если задан город, задан раздел сайта (только 1 уровень)

  5. Страница каталога-доски объявлений-раздела сайта и проч.
     Код: catalog
  Если задан город, заданы 2 или более разделов сайта

  */

class SimpleUrl {
	var $country; // наименование страны
	var $region;  // наименование города или региона
	var $section = array(); // массив разделы сайта [0] - раздел, [1] - подраздел и т.д.
	var $params = array();  // опции (номер страницы) и т.д.
	var $object_name; // наименование объекта
	var $page_num; // номер страницы (в списках)
	var $doc_id; // ID страницы (объекта WEB_PAGE)
	var $restate_type_id; // ID типа объекта недвижимости

	var $url_input; // адрес страницы (введен пользователем)
	var $url_str; // адрес страницы (обработанный после проверки)
	//protected $db_url_str; // тот же $url_str но без пэйджинга. Инициализируется в checkurl
	var $url;        //адрес страницы - массив

//	var $arr_countries; // справочник стран
//	var $arr_regions; // справочник регионов
	var $arr_sect0; // справочники разделов
	var $arr_sect1; //             подразделов
	var $arr_sect2; //             типов подразделов
	var $arr_sect3; //             типов подразделов

	// конструктор класса
	public function SimpleUrl() {
		// NOT SAFE!
		// okay, now pre-check enabled
		$this->url_input = $_SERVER['REDIRECT_URL'];
		if (empty($this->url_input)) {
			$this->url_input = "/index.php";//REDIRECT_URL не заполняется, если URL совпадает с именем скрипта
		}
		if (SUB_URL != "") {//удаляем "прослойку" между доменом и сайтом при наличии таковой
			$subUrlLen = strlen(SUB_URL);
			if (strlen($this->url_input) > $subUrlLen && SUB_URL == substr($this->url_input, 0, $subUrlLen)) {
				$this->url_input = substr($this->url_input, $subUrlLen);
			}
		}
		
		//print_r($_SERVER['HTTP_HOST']);
		//$this->url_str = preg_replace( '|^'.dirname($_SERVER['PHP_SELF']).'|', '', $this->url_str);
		//echo $_SERVER['REDIRECT_URL'];echo "<br/>";
		//echo $_SERVER['PHP_SELF'];
		//echo dirname($_SERVER['PHP_SELF']);
		//echo preg_replace( '|^'.dirname($_SERVER['PHP_SELF']).'|', '', $this->url_str);
		//echo '<li>'.$this->url_str;
		//echo "<pre>";
		//print_r($_SERVER);
		//echo "</pre>";
		
		$this->params = $_GET;
		$this->url = array();
		$this->url = explode('/', str_replace('/index.php', '', $this->url_input));
		$this->url = array_remove($this->url, 0, 1);
		$this->params["url"] = array();//сюда будут записаны элементы адреса после разделов
		
		// 0 раздел
		$this->arr_sect0 = array('login', 'help', 'login', 'faq', 'search', 'waveEditor', 'cms', 'panel', 'desktop', 'incidents', 'additions', 'forum');
		// 1 подраздел
		$this->arr_sect1 = array('catalog', 'map', 'desktop', 'pages', 'news', 'banners', 'navigate');
		// 2 подраздел 3 уровень + закладки
		$this->arr_sect3     = array();
		// параметры
		$this->arr_params    = array();
		//print_r($this->url);
		$this->checkurl();
		
		//print_a($this->arr_sect0);
		//print_a($this->arr_sect1);
		
		// making url_str
		// sample: /saint-petersburg/apartments/catalog/karavan24/photo/index.php
		$this->url_str = '';
		if (!empty($this->region)) $this->url_str .= '/'.$this->region;
		if (!empty($this->section[0])) $this->url_str .= '/'.$this->section[0];
		if (!empty($this->section[1])) $this->url_str .= '/'.$this->section[1];
		if (!empty($this->object_name)) $this->url_str .= '/'.$this->object_name;
		if (!empty($this->section[2])) $this->url_str .= '/'.$this->section[2];
		if (!empty($this->section[3])) $this->url_str .= '/'.$this->section[3];
		if (empty($this->url_str)) {
			$this->url_str = '/';
		}
		
	}


	public function checkurl() {
		// возвращает 1, если все ОК, иначе 0
		
		// если главная страница, добавляем в URL index.php
//			echo "url_input" . $this->url_input;die;
			
		if ($this->url_input == '/') {
			$this->url_input = '/'.'index.php';
		}

		$ind = 0;
		
		// провряем раздел
		$key = array_search($this->url[$ind],$this->arr_sect0);
		// проверяем через is_int - значение может быть False, а может быть 0!
		if (is_int($key)) {
			// нашли
			
			array_push($this->section, $this->url[$ind]);
			$ind++;
			
			// если ОК - то подраздел 1 уровень
			$key = array_search($this->url[$ind],$this->arr_sect1);
			
			if (is_int($key)) {
				array_push($this->section, $this->url[$ind]);
				$ind++;
				// если ОК - то подраздел 2 уровень (НЕОБЯЗАТЕЛЬНЫЙ)
				$key = array_search($this->url[$ind],$this->arr_sect3);
				
				if (is_int($key)) {
					// нашли
					array_push($this->section, $this->url[$ind]);
					$ind++;
				}
				
			}
		} else {
			// не найден основной раздел (обязательное поле)
			if (($this->url_input != '/index.php') and empty($this->region)) {
				array_push($this->section, 'error');
				array_push($this->section, '404');
				return;
			}
		}
		
		// всё остальное - параметры
		for ($i = $ind; $i<count($this->url); $i++) {
			$this->params["url"][] = $this->url[$i];
		}
	}

	// конструктор класса
	public function get_pagetype()
	{
		
		//  1. Главная страница сайта
		//     Код: homepage
		//  Ничего не задано в параметрах
		if ($this->url_str == '/') {
			return '\\carabi_office\\homepage';
		}
		
		// Обработка ошибки
		if($this->section[0] == 'error') {
			return 'error';
		}

		//  2. Страница региона
		//     Код: regions
		//  Если нажата ссылка на города
		if ($this->url_str == '/cities.php') {
			return 'regions';
		}
		//  Если задан 1 раздел сайта, но не задан регион
		//$this->get_urlinfo();
		if (count($this->section) == 1) {
			switch ($this->section[0]) {
				case 'site-map':
					return 'sitemap';
				case 'search':
					return 'search';
				case 'login':
					return '\\astersik\\login';
				case 'registration':
					return 'registration';
				case 'vocab':
					return 'vocab';
				case 'waveEditor':
					return 'waveEditor';
				case 'panel':
					return 'panel';
				case 'cms':
					return '\\carabi_cms\\homepage';
				case 'desktop':
					return '\\carabi_office\\desktop';
				case 'incidents':
					return '\\carabi_office\\incidents';
				case 'additions':
					return '\\carabi_office\\additions';
				case 'forum':
					return '\\carabi_office\\forum';
				case 'userimg':
					return 'userimg';
				case 'docs':
					return 'docs';
				case 'error':
					return 'error';
			}
		}
		
		//Подразделы CMS
		if ($this->section[0] == "cms") {
			switch ($this->section[1]) {
				case 'articles':
					return '\\carabi_cms\\articles';
				case 'banners':
					return '\\carabi_cms\\banners';
				case 'desktop':
					return '\\carabi_cms\\desktop';
				case 'navigate':
					return '\\carabi_cms\\navigate';
				case 'news':
					return '\\carabi_cms\\news';
				case 'pages':
					return '\\carabi_cms\\pages';
			}
		}
	}

	public function get_urlinfo() {
		// печатает информацию об адресе
		echo "<br><b>URL info</b><br>url_str: ";
		echo $this->url_str;
		echo "<br>url_input: ";
		echo $this->url_input;
		echo "<br><b>Портал:</b><br>";
		echo PROJECT_NAME; // массив разделы сайта [0] - раздел, [1] - подраздел и т.д.
		echo "<br><b>ID страницы:</b><br>doc_id: ";
		echo $this->doc_id; // массив разделы сайта [0] - раздел, [1] - подраздел и т.д.
		echo "<br><b>Тип страницы:</b><br>get_pagetype(): ";
		echo $this->get_pagetype(); // массив разделы сайта [0] - раздел, [1] - подраздел и т.д.
		echo "<br><b>Страна:</b><br>country: ";
		print_r($this->country);
		echo "<br><b>Город:</b><br>region: ";
		print_r($this->region);  // наименование города или региона
		echo "<br><b>Раздел:</b><br>section: ";
		print_r($this->section); // массив разделы сайта [0] - раздел, [1] - подраздел и т.д.
		echo "<br><b>Объект:</b><br>object_name: ";
		echo $this->object_name; // массив разделы сайта [0] - раздел, [1] - подраздел и т.д.
		echo "<br><b>Номер страницы списка:</b><br>page_num: ";
		echo $this->page_num; // массив разделы сайта [0] - раздел, [1] - подраздел и т.д.
		echo "<br><b>Параметры:</b><br>params: ";
		print_r($this->params);  // опции (номер страницы) и т.д.
	}


	/*
	* Функция get_url возвращает сформированную ссылку относительно начала сайта.
	* На вход подаётся:
	*	- Либо хэш-массив с парами название-значение, где название - системное именование пути урла
	*	а значение - его значение.
	* 	- Либо скалярные значения в порядке: country, region, section1, section2, section3, object, page
	* Любые из значений опциональны.
	*
	* @todo Сделать возможность добавлять произволные значеня в урл, например
	* как параметры после "?"
	* 
	*/
	public static function getUrl()
	{
		$args = func_get_args();
		if (is_array($args[0])) {
			extract($args[0]);
		} else {
			list($country, $region, $section1, $section2,
			$section3, $object, $page, $params, $mode) = $args;
		}
		$ulr_parts_order = array('country', 'region', 'section1',
					'section2', 'page', 'object', 'section3', 'mode');
		$url_parts = array();

		// TODO
		if( $section1=='cities' )
			return '/cities.php';

		foreach ($ulr_parts_order as $url_part) {
			$up_val = $$url_part;

			// пропускаем page=0
			if ($url_part=='page'&&$up_val<=1)
				continue;

			if (empty($up_val))
				continue;

			$url_parts[] = $up_val;
		}

		$url_parts[] = 'index.php';

		if (is_array($params)) {
			$query_params = '?';
			foreach ($params as $k=>$v) {
				$query_params .= $k . '=' . $v . '&';
			}
		} else {
			$query_params = '';
		}

		return '/' . join('/', $url_parts) . $query_params;
	}

	public static function getMainUrl()
	{
		$url = explode("?", $_SERVER["REQUEST_URI"]);

		return $url[0];
	}

	public function get_url ()
	{
		//return self::getUrl(func_get_args());
		return call_user_func_array( array(self,'getUrl'), func_get_args());
	}

	public function debug()
	// возвращает 1, если идет отладка данного класса
	// используется для проверок, требуется ли выдавать служебную информацию на страницах
	{
		if (SIMPLEURL_DEBUG == 1) {
			return true;
		} else {
			return false;
		}
	}
	
	

	/*
	* Magic метод __call - позволяет обращаться к полям класса через виртуальный функции.
	* Формат функции: $obj->get_abc( $cnt=null )
	*	где abc название поля объекта
	*	$cnt - в случае если поле массив, возвращается значение массива за индексом $cnt,
	*	если $cnt не указан, поле возвращается целиком
	*/
	public function __call( $name, $args ){
		if( strpos( $name, 'get_') === false )
			return;

		switch( strtolower(substr( $name, 4 )) ){
			case 'country':
				return $this->country;
			break;

			case 'region':
				return $this->region;
			break;

			case 'section':
				return $this->section[(isset($args[0])?$args[0]:0)];
			break;

			case 'sections':
				return $this->section;
			break;

			case 'pagenum':
				return $this->page_num;
			break;

			case 'objectname':
				return $this->object_name;
			break;
			
			case 'params':
				return $this->params;
			break;

			default:
				//return;
				throw new Exception('Method does not exist: "' . $name . '"');
			break;
		}
	}


/*
	public function getPagehandler(){
		$pagetype = $this->get_pagetype();
		$pagehandler = carabi_pagehandler::construct($this);
		return $pagehandler;

	}
*/

}// class simpleurl
?>