266 lines
10 KiB
PHP
266 lines
10 KiB
PHP
<?
|
||
/*
|
||
$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(['cookie_lifetime' => 43200,'cookie_secure' => true,'cookie_httponly' => true]);
|
||
if(isset($_SESSION['REMOTE_ADDR']) && $_SESSION['REMOTE_ADDR'] != $_SERVER['REMOTE_ADDR']) unset($_SESSION["USER_ID"]); //Делаемся не авторизованным если зашли с другого ip адреса
|
||
|
||
//sleep(1); //Тестирование с задержкой
|
||
|
||
//require_once("../../config.xyz"); Должно быть обьявлено во внешнем файле
|
||
require_once("treetools.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=getSQLFromP($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();
|
||
}
|