<?php

class RedirectEditorView extends Slot
{
	var $ModuleID = 1;
	var $SectionID = 39;
	var $new_log1;
	var $new_log2;
	var $search = false;
	var $search_string = '';
	var $searchlog = array();

	function __construct($pquery) {
		parent::__construct($pquery);
	}

	function init() {
		global $TOOLS_PATH;
		$this->Scheme = 'default';
		if(!empty($this->Request)) {
			if($this->server_type=='dev') {
				//printArray($this->Request);
				$this->new_log1 = $this->getRequestField('new_log1');
				$this->new_log2 = $this->getRequestField('new_log2');
				if($this->Request['submit'] == "Search") {
					//printArray($this->new_log1);
					$this->search = true;
					$this->search_string = $this->getRequestField('search_string');
					if($this->search_string != '') $this->getSearch();
				}
				elseif(!empty($this->new_log1))
				$this->validateForm($this->new_log1,$this->new_log2)
				and $this->saveFile()
				and $this->Action->processEvent($this->SectionID,'log',array('type' => 2,'entity' => 3,'event' => 12,'value' => 'Edit list of Redirects'),$this)
				and header('Location: '.$this->Home.'/Registar/RedirectEditor');
			}
		}
		$this->setSchemeTemplate($this->Scheme);
	}

	function fillElements() {
		global $ROOT_PATH;
		$this->TempFillEls['addBut'] = $this->server_type=='dev'? 'visible' : 'hidden';
		$this->TempFillEls['pubBut'] = $this->server_type=='pro'? 'hidden' : 'visible';
		$this->TempFillEls['search_string'] = $this->search_string;
		if(count($this->errors) > 0) $this->TempFillEls['path_error'] = $this->printError($this->errors['path']);
		if(count($this->errors) > 0 or $this->search) {
			foreach($this->new_log1 as $url) $this->TempFillEls['log1'][]['url1'] = $url;
			foreach($this->new_log2 as $url) $this->TempFillEls['log2'][]['url2'] = $url;
			if(!empty($this->searchlog)) $this->TempFillEls['searchlog'] = $this->searchlog;
		}
		else $this->fillLog();
	}

	function validateForm($log1 = array(),$log2 = array()) {
		global $REGISTRY;
		foreach($log1 as $k => $link) {
			$link = trim($link);
			if(!preg_match('/^\//',$link)) $link = '/'.$link;
			$path = checkURL(getenv('HTTP_HOST').$link);
			if(empty($path) || preg_match('/^\/admin(\/|$)/i',$link) || is_dir(preg_replace('/^\//','',$link))) {$this->errors['path'] = 'Contains invalid URLs ('.$link.')'; return FALSE;}
			if(preg_match('/^\/+$/',$link)) {unset($log1[$k]); unset($log2[$k]); continue;}
			if(isset($log2[$k])){
				$log2[$k] = trim($log2[$k]);
				if (!preg_match('/^(\/|http:\/\/)/i',$log2[$k])) $log2[$k] = '/'.$log2[$k];
			}
			else $log2[$k] = '/';
			$log1[$k] = $link;
		}
		if(count(array_unique($log1)) != count($log2)) {$this->errors['path'] = 'Includes two or more redirections from one page'; return FALSE;}
		foreach($log2 as $link2) {
			$path = checkURL((!preg_match('/^(http:\/\/)/i',$link2)? getenv('HTTP_HOST'):'').$link2);
			if(empty($path) || preg_match('/^\/admin(\/|$)/i',$link2)) {$this->errors['path'] = 'Contains invalid URLs ('.$link2.')'; return FALSE;}
			if(!preg_match('/^(http:\/\/)/i',$link2)){
				if(!array_key_exists(strtolower(preg_replace("/\?.*/",'',$link2)),$REGISTRY['VirtualSlotTarget']['main'])) {
					$this->errors['path'] = 'Redirection to nonexistent page ('.$link2.')';	return FALSE;
				}
			}
			elseif(preg_match('/^http:\/\/'.getenv('HTTP_HOST').'/i',$link2)){
				$l = preg_replace('/^http:\/\/'.getenv('HTTP_HOST').'/i','',$link2);
				if(!array_key_exists(strtolower(preg_replace("/\?.*/",'',$l)),$REGISTRY['VirtualSlotTarget']['main'])) {
					$this->errors['path'] = 'Redirection to nonexistent page ('.$link2.')';	return FALSE;
				}
			}
			if(in_array($link2,$log1)) {$this->errors['path'] = "Cyclic redirection is forbidden (".$link2.")"; return false;}
		}
		$this->new_log1 = $log1;
		$this->new_log2 = $log2;
		return TRUE;
	}

	function saveFile() {
		global $REGISTRY,$ROOT_PATH;
		$path = $ROOT_PATH.'/.htaccess';
		$log1 = array(); $log2 = array(); $redirect = array();
		$data = ''; $data_arr = array(); $data_arr_new = array();
		$log1 = $this->new_log1;
		$log2 = $this->new_log2;
		foreach($log1 as $k => $link) {
			$linkFrom = preg_replace("/^\/.*/Uis", "", $link);
			$linkTo = (!preg_match('/^(http:\/\/)/i',$log2[$k])?'http://'.getenv('HTTP_HOST'):'').$log2[$k];
			$linkTo = str_replace(".", "\.", $linkTo);
			$redirect[$linkFrom] = "RewriteRule ^".$linkFrom."$ ".$linkTo." [R=301,NC,L]";
		}
		//printArray($redirect);
		if(is_readable($path) && is_writable($path)) {
			$fh = fopen($path, "r");
			$data = fread($fh, filesize($path));
			fclose($fh);
			$data_arr = explode("\n",$data);
			$process = false;
			foreach($data_arr as $key => $row) {
				/**
				 * Если блок редиректов, то добавляем все новые редиректы которые получили из формы
				 */
				if($process == true) {
					foreach ($redirect as $k => $v) {
						$data_arr_new[] = $v;
					}
					$process = false;
				}
				/**
				 * Если строка похожа на редирект, пропускаем ее и не дописываем в файл
				 */
				if(preg_match('/^RewriteRule \^.*\s.*\s\[R=301\,NC\,L\]/i',$row)) {
					continue;
				}
				else {
					/**
					 * Проверяем не похожа ли строка на старый редирект.
					 */
					if(preg_match('/^Redirect\spermanent.*\s.*$/i',$row)) {
						/**
						* Если строка похожа на старый тип правила, конвертируем в новые и дописываем в файл
						*/
						$data_arr_new[] = $this->_formStringRuleFromArray($this->_formArrayFromOldStringRule($row));
					}
					else {
						/**
						* Если же строка не похожа на старый редирект то просто добисываем в файл
						*/
						$data_arr_new[] = $row;
					}
				}
				if($row == '#start_redirect') $process = true;
				if($row == '#end_redirect') $process = false;
			}
			$data_new = implode("\n",$data_arr_new);
			if(strcmp($data,$data_new) != 0) {
				$fr = fopen($path, "w");
				flock($fr,LOCK_EX);
				fwrite($fr, $data_new);
				flock($fr,LOCK_UN);
				fclose($fr);
			}
		}
		else {$this->errors['path'] = "Can't write to .htaccess file"; return;}
		return true;
	}

	function fillLog() {
		global $ROOT_PATH;
		$path = $ROOT_PATH.'/.htaccess';
		$data = ''; $data_arr = array();
		$log1 = ''; $log2 = '';
		if(is_readable($path)) {
			$fh = fopen($path,"r");
			$data = fread($fh, filesize($path));
			fclose($fh);
		}
		else {
			$this->TempFillEls['path_error'] = $this->printError("Can't read .htaccess file");
			return;
		}
		$data_arr = explode("\n",$data);
		$r_start = array_search('#start_redirect',$data_arr);
		$r_end = array_search('#end_redirect',$data_arr);
		if($r_end-$r_start > 1) {
			for($i=$r_start+1;$i<$r_end;$i++) {
				$inLog = $this->_formArrayFromStringRule($data_arr[$i]);
				if($data_arr[$i] == $inLog['from']) {
					//Старый вариант редиректов
					$inLog = $this->_formArrayFromOldStringRule($data_arr[$i]);
				}
				$log1[] = $inLog['from'];
				$log2[] = $inLog['to'];
			}
		}
		foreach($log1 as $k => $url) $this->TempFillEls['log1'][]['url1'] = '/'.$url;
		foreach($log2 as $k => $url) $this->TempFillEls['log2'][]['url2'] = str_replace("\.", ".", $url);
	}

	function getSearch() {
		if(!empty($this->new_log1) && !empty($this->new_log2)) {
			for($i=1; $i<count($this->new_log1); $i++) {
				if(ereg($this->search_string,$this->new_log1[$i]) or ereg($this->search_string,$this->new_log2[$i])) {
					$this->searchlog[] = array('from' => $this->colorIt($this->new_log1[$i]), 'to' => $this->colorIt($this->new_log2[$i]));
				}
			}
		}
		else {
			return false;
		}
		if(empty($this->searchlog)) return false;
		return true;
	}

	function colorIt($str = '') {
		$str = preg_replace("/(.*?)(".preg_quote($this->search_string,'/').")(.*?)/i","\\1<span style='color:Red; font-weight:bold;'>\\2</span>\\3",$str);
		return $str;
	}

	function _formArrayFromStringRule($string) {
		return array(
		"from"=>preg_replace('/RewriteRule\s\^(.*)\$\s(.*)\s\[R=301\,NC\,L\]/Uis','\\1',$string),
		"to"=>preg_replace('/RewriteRule\s\^(.*)\$\s(.*)\s\[R=301\,NC\,L\]/Uis','\\2',$string)
		);
	}

	function _formArrayFromOldStringRule($string) {
		return array(
		"from"=>preg_replace('/^Redirect permanent \/(.*) (.*)$/Uis','\\1',$string),
		"to"=>preg_replace('/^Redirect permanent \/(.*) (.*)$/Uis','\\2',$string)
		);
	}

	function _formStringRuleFromArray($array) {
		return "RewriteRule ^".$array['from']."$ ".$array['to']." [R=301,NC,L]";
	}

}
?>