<?
/*
	$pos=strripos ( $_SERVER['SERVER_NAME'] , '.' , 0 ) - strlen($_SERVER['SERVER_NAME']) - 1;
	$pos=strripos ( $_SERVER['SERVER_NAME'] , '.' , $pos );
	ini_set('session.cookie_domain', $pos ? substr($_SERVER['SERVER_NAME'],$pos) : '.'.$_SERVER['SERVER_NAME']);
 */
	if(isset($_GET[session_name()]) && $_GET[session_name()]!='') //Чтоб ID сессии переданная гетом был главней а не создавался заново
		session_id($_GET[session_name()]);
	@session_start();
	if(isset($_SESSION['REMOTE_ADDR']) && $_SESSION['REMOTE_ADDR'] != $_SERVER['REMOTE_ADDR']) unset($_SESSION["USER_ID"]); //Делаемся не авторизованным если зашли с другого ip адреса

	//sleep(1); //Тестирование с задержкой

	//require_once("../../config.php"); Должно быть обьявлено во внешнем файле
	require_once("tools.php");

	/**
	 * Отправить клиенту информацию о ошибке
	 * @param String $e - Наименование ошибки
	 */
	function sendError($e)
	{
		header('Content-type: text/xml');
		header("Cache-Control: no-cache, must-revalidate");
		echo '<?xml version="1.0" encoding="utf-8"?><metadata fn="0"><![CDATA['.$e.']]></metadata>';
		Exit();
	}

	/**
	 * Взять данные из базы данных в результсет
	 * @param Node $treeNode - DOM узел переданной клиентом
	 * @param Node $currNode - DOM узел из файла tree.xml параметрам фильтра которого будут присвоенны значения из treeNode (недостающие фильтры возтмуться из nodeMetadata)
	 * @return PDOStatement|NULL Результ-сет
	 */
	function fnGetData($treeNode,$currNode)
	{
		$sql=getSQL($treeNode,$currNode);

		if(gettype($_SESSION['USER_ID'])=='string')
			$sql=str_replace('${_user_id}',$_SESSION['USER_ID']=='' ? 'null' : '\''.$_SESSION['USER_ID'].'\'',$sql);
		else
			$sql=str_replace('${_user_id}',$_SESSION['USER_ID']=='' ? 'null' : $_SESSION['USER_ID'],$sql);

		global $db;
		try
		{	return $db->query($sql);
		} catch (Exception $e)
		{	sendError($e->getMessage()."\n\n".$sql);
		}
		return null;
	} //end of function fnGetData

	if (!isset($_SESSION['USER_ID'])) $_SESSION['USER_ID']=''; //По умолчанию анонимный пользователь
	//sendError("Вы не авторизованы!");

	//Открываем XML структуры дерева
	$objXMLDocument = new DOMDocument();
	try
	{
		$objXMLDocument->load($treexml); //Объявлен в нешнем файле $treexml
	} catch (Exception $e)
	{
		sendError($e->getMessage());
	}
	$mainNode = $objXMLDocument->documentElement;

	// Соединяемся с базой данных
	$db=null;
	try
	{	$db = new PDO($db_connection, $db_login, $db_password);
		$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	} catch (Exception $e)
	{
		sendError('Connect error '.$_SERVER['HTTP_HOST'].': "'.$e->getMessage().'"!');
	}

	//Отправить клиенту заранее построеный файл (чтоб каждый раз не запрашивал данные)
	if(isset($_REQUEST['fn'])) $fn=$_REQUEST['fn']; else $fn='';
	if(isset($_REQUEST['name'])) $name=$_REQUEST['name']; else $name='';
	if(isset($_REQUEST['path'])) $path=$_REQUEST['path']; else $path='';

	if($fn=='0') //Генерить XML фаил дерева
	{
		echo '<html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"></head><body>';
		echo "Начинаем строить дерево<br><br>";
		$xmlstr=getTreeArray(findNode($mainNode,'type'),null,$db,true,$path);	
		if($handle = fopen($name, 'w'))
		{
			echo strtolower(afterLast($name,'.')).'<br>';
			if(strtolower(afterLast($name,'.'))=='js')
			{
				$xmlstr = str_replace("\n","",$xmlstr);
				$xmlstr = str_replace("'","\'",$xmlstr);
				fwrite($handle, 'var '.beforeFirst($name,'.')."='");
				fwrite($handle, $xmlstr);
				fwrite($handle, "';");
			}else 
			{
				fwrite($handle, $xmlstr);
			}
			fclose($handle);
		}
		echo "<br>Построили<br>";
		echo '</body></html>';

		Exit();
	}

	//принимаем XML данные для заполнения фильтра
	$docReq = new DOMDocument();
	try
	{
		$docReq->loadXML(file_get_contents("php://input"));
	} catch (Exception $e)
	{
		sendError($e->getMessage());
	}


	$reqNode=$docReq->documentElement;
	if ($reqNode)
	{
		$fn=$reqNode->getAttribute("fn");
		$treeid=$reqNode->getAttribute("treeid");
		$htmlid=$reqNode->getAttribute("htmlid");
	}else exit();


	if($fn=='1')
	{
		header('Content-type: text/xml');
		//Прочитать подготовленый файл в поток
		readfile('test_tree.xml');
		Exit();
	}else if($fn=='2')
	{


		$xmlstring="";
		$xmlnode="";
		//находим нужный узел в tree.xml для того чтобы выполнить запрос

		$mainNode=findFirstNodeOnAttribute($mainNode,"type","id",$treeid);
		if($mainNode!=null)
		{
			//перебераем все дочерние элементы и для каждого выполняем запрос c фильтрацией
			$currNode = $mainNode->firstChild; //из tree.xml
			while ($currNode != null)
			{
				$tmpNode=$currNode; //если узел goto

				if($tmpNode->nodeName=="goto") //если встретилась "зацикливалка"
				{
					$treeid=$tmpNode->getAttribute("id");
					$tmpNode=findFirstNodeOnAttribute($objXMLDocument->documentElement,"type","id",$treeid);
					if($tmpNode==null) { $currNode = $currNode->nextSibling; continue; }
				}

				if($tmpNode->nodeName=="type") //если выборка из базы
				{
					$treeid=$tmpNode->getAttribute("id");
					$caption=$tmpNode->getAttribute("c");

					//$j=0;
					$res=fnGetData($reqNode,$tmpNode);//currNode из tree.xml
					if($res==null)
					{
						sendError('fnGetData==null!');
					}
					while ($row = $res->fetch(PDO::FETCH_ASSOC))
					{
						if(array_key_exists('id', $row)) $fid=$row['id']; else $fid=''; //Уникальный id записи
						if(array_key_exists('icon_id', $row)) $iid=$row['icon_id']; else $iid=''; //id значка
						if(array_key_exists($caption, $row)) $val=$row[$caption]; else $val=''; //Заголовок

						$visible='';
						if($tmpNode->getAttribute("visible")=="0") $visible=' visible="0" ';
						//Для проверки есть ли дети составляем XML запрос и отправляем в вункцию как будто он пришел от клиента
						//c - Есть ли под узлы по умолчанию есть
						//fid - id записи
						//iid - id иконки
						//treeid - id ветки дерева
						//ObjectID - название поля с уникальным идентификатором записи
						$xmlnode='<?xml version="1.0" encoding="utf-8"?>';
						$xmlnode.='<tree c="1" fid="'.$fid.'" iid="'.$iid.'" treeid="'.$treeid.'" t="'.$tmpNode->getAttribute("n").'" ObjectID="'.$tmpNode->getAttribute("ObjectID").'"'.$visible.'>';
						$xmlnode.='<![CDATA['.$val.']]>';
						//сохраняем параметры фильтра для дочерних элементов с текщем состоянием
						//перебираем фильтры которые должны быть заполненны для каждого узла даные для фильтра беруться из результ сета
						$xmlnode.='<columns>';

						//считываем название поля и находим данные в результсете
						$nodeParam = findFirstNode($tmpNode, 'columns'); //tree.xml
						if($nodeParam!=null) $nodeParam=$nodeParam->firstChild;
						while ($nodeParam != null)
						{
							if($nodeParam->nodeName=="param")
							{
								$fname=$nodeParam->getAttribute("n");
								try
								{
									if(array_key_exists($fname, $row)) $fval=$row[$fname]; else $fval=getCdataValue($nodeParam);
								} catch (Exception $e)
								{
									sendError($e->getMessage());
								}
								$xmlnode.='<param n="'.$fname.'"><![CDATA['.$fval.']]></param>';
							}
							$nodeParam = $nodeParam->nextSibling;
						}

						$xmlnode.='</columns>';
						$xmlnode.='</tree>';

						//парсим созданную ветку дерева в DOMDocument потом посылаем в функцию взятия данных как будто их все открыли
						//если есть данные то у этого узла дерева есть дети c="1" инече нет c="0".
						$child=0;
						$objXMLDocTree = new DOMDocument();
						try
						{	$objXMLDocTree->loadXML($xmlnode);
						} catch (Exception $e)
						{	sendError($e->getMessage());
						}
						$testNodeTree=$objXMLDocTree->documentElement;

						$testNode = $tmpNode->firstChild; //Текущий узел из tree.xml
						while ($testNode != null)
						{
							$tmpNode2=$testNode;
							if($tmpNode2->nodeName=="goto")
							{
								$treeid=$tmpNode2->getAttribute("id");
								$tmpNode2=findFirstNodeOnAttribute($objXMLDocument->documentElement,"type","id",$treeid);
								if($tmpNode2==null) { $testNode = $testNode->nextSibling; continue; }
							}
							if($tmpNode2->nodeName=="type")
							{
								$testrs=fnGetData($testNodeTree,$tmpNode2);
								if(($testrs!=null)&&($testrs->rowCount()>0))
								{
									$child=1;
									break;
								}
							}
							$testNode = $testNode->nextSibling;
						}
						$testNodeTree->setAttribute("c",$child);

						$xmlstring.=$objXMLDocTree->saveXML($objXMLDocTree->documentElement);
						//Закончили проверку на детей

					}
					$res->closeCursor();
				}
				$currNode = $currNode->nextSibling;
			}
		}else
		{
			sendError('Can\'t find "type" node id='.$treeid.' in "'.$treexml.'"!');
		}

		$xmlstring='<?xml version="1.0" encoding="utf-8"?><metadata fn="1" htmlid="'.$htmlid.'">'.$xmlstring.'</metadata>';
		header('Content-type: text/xml');
		echo $xmlstring;
		exit();
	}
