Files
Metadata_PHP/metadata/dbms/records.php

1386 lines
59 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
//sleep(1);
//ini_set('display_errors','Off'); //Чтоб ошибки не отправлялись клиентам
//ini_set("error_log", "php_error.log"); //Чтоб ошибки сохранялись в локальную папку
$host = $_SERVER['HTTP_HOST'];
$host = '.'.cutAfterLast($host,'.',2);
ini_set('session.cookie_domain', $host);
//if(isset($_GET[session_name()]) && $_GET[session_name()]!='') //Чтоб сессия переданная гетом была главней
// session_id($_GET[session_name()]);
startSession(true); //Для ручного определения времени жизни сесии
if(isset($_SESSION['REMOTE_ADDR']) && $_SESSION['REMOTE_ADDR'] != $_SERVER['REMOTE_ADDR']) unset($_SESSION['USER_ID']); //Делаемся не авторизованным если зашли с другого ip адреса
if(!isset($_SESSION['USER_ID'])) { $_SESSION['USER_ID']=null; }
if(!isset($_COOKIE['GUID'])) { $_COOKIE['GUID']=null; }
//include("../include/xmltools.php");
//include("../include/toExcell.php");
//require_once("config.php");
function getCurrentDirectory() {
$path = dirname($_SERVER['PHP_SELF']);
$position = strrpos($path,'/') + 1;
return substr($path,$position);
}
//Полный путь к скрипту включая протокол без названия файла на конце "/"
function getFullPath()
{
$pro="http";
if (isset( $_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') $pro="https";
$path = $pro.'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$position = strrpos($path,'/') + 1;
return substr($path,0,$position);
}
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="-1"><![CDATA['.$e.']]></metadata>';
Exit();
}
function getSQLValue($t,$v)
{
global $db_connection;
if($t=='object' && gettype($v)=='string'){
$t='string'; //Если id шники uuid
}
if($t=='object'){
if ($v=='-1'||$v=='' || $v==null) $v='NULL';
}else
if($t=='i1' || $t=='i2' || $t=='i4' || $t=='integer'){
if($v=='') $v='NULL';
}else
if($t=='f8' || $t=='f4' || $t=='real' || $t=='double'){
if($v=='')$v='NULL';
$v=str_replace(',','.',$v); //Разделитель целой и дробной части точка
}else
if($t=='b'){
if($v=='') $v='NULL'; else
if($v=='1') $v='true'; else
if($v=='0') $v='false';
}else
if($t=='string' || $t=='html' || $t=='text' || $t=='dateTime' || $t=='time' || $t=='date' || $t=='file') {
if ($v == '') {
$v = 'NULL';
} else {
if (strpos($db_connection, 'pgsql') !== false)
$v = str_replace("'", "''", $v); //так как в SQL строку вставляется
else
$v = str_replace('\'', '\\\'', $v); //так как в SQL строку вставляется
$v = '\'' . $v . '\'';
}
}else if($t=="NULL" || $t==null){
if ($v == '') {
$v = 'NULL';
} else {
$v='\''.$v.'\'';
}
}else{
$v='\''.$v.'\'';
}
return $v;
}
function getValue($t,$v)
{
if($t=='object' && gettype($v)=='string'){
$t='string'; //Если id шники uuid
}
if($t=='object'){
if (($v=='-1')||($v=='')) $v=null;
}else
if($t=='i4' || $t=='integer'){
if($v=='') $v=null;
}else
if($t=='f8'){
if($v=='')$v=null;
$v=str_replace(',','.',$v); //Разделитель целой и дробной части точка
}else
if($t=='b'){
if($v=='') $v=null; else
if($v=='1') $v=true; else
if($v=='0') $v=false;
}else
if($t=='string' || $t=='dateTime' || $t=='date'){
if($v=='') $v=null;
}
return $v;
}
function getPDOTypeParam($t)
{
//if($t=='object' && gettype($v)=='string') $t='string'; //Если id шники uuid
if($t=='object')
{ //return PDO::PARAM_INT;
return PDO::PARAM_STR;
}else
if($t=='i4' || $t=='integer')
{ return PDO::PARAM_INT;
}else
if($t=='f8')
{ return PDO::PARAM_STR;
}else
if($t=='b')
{ return PDO::PARAM_BOOL;
}else
if($t=='string' || $t=='dateTime' || $t=='date')
{ return PDO::PARAM_STR;
}else
if($t=='blob')
{ return PDO::PARAM_LOB;
}else
return PDO::PARAM_STR;
}
//Заменить все значения первого фильтра значениями из второго
function setFilter($n1,$n2)
{
if($n1==null || $n2==null) return;
$nc1=$n1->firstChild;
while ($nc1)
{
if ($nc1->nodeName=='column')
{
$nc2=findNodeOnAttribute($n2, 'column', 'n', $nc1->getAttribute("n"));
if($nc2) getCdata($nc1)->nodeValue=getCdata($nc2)->nodeValue;
}
$nc1 = $nc1->nextSibling;
}
}
//Получить узел метаданных из базы данных
function getMetadataNode($name)
{
global $db,$Schema;
$xmls='';
$sql='select xml from '.$Schema.'_metadata where del=false and name=\''.$name.'\';';
$resX = $db->query($sql);
while ($rowX = $resX->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$xmls='<?xml version="1.0" encoding="UTF-8"?><metadata>'.trts($rowX['xml']).'</metadata>';
}
if($xmls!='')
{
//sendError("Metadata node \"".$name."\" not find in database!");
$objXMLDocument = new DOMDocument();
try
{
$objXMLDocument->loadXML($xmls);
} catch (Exception $e)
{ sendError($e->getMessage());
}
$currNode=findNodeOnAttribute($objXMLDocument->documentElement, "type","n",$name);
return $currNode;
}else{
return null;
}
}
function special_handler($exception)
{
sendError($exception->getMessage());
}
set_exception_handler('special_handler'); //чтоб не пойманные исключения посылались в виде XML
//Схема базы по умолчанияю
if(!isset($Schema)) {
$Schema="";
}
//Тип идентификаторов
$idType="object";
if(!isset($idType)) {
$idType="object";
}
try
{
if(strpos($db_connection, 'sqlite')!==false)
{
$db = new PDO($db_connection);
}else
{
$db = new PDO($db_connection, $db_login, $db_password);
$db->exec("SET timezone TO 'UTC';"); //Пользователь должен сам передавать свою зону или она должна быть в настройках
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e)
{ sendError('Connect error '.$_SERVER['HTTP_HOST'].': "'.$e->getMessage().'"!');
}
//Пытаемся автоматически залогинется по GUID из COOKIE
/*if($_SESSION['USER_ID']==null && $_COOKIE['GUID']!=null)
{
$res = $db->query("select * from ".$Schema."p__Login(null,null,null,'".$_COOKIE['GUID']."');");
//$res = $db->query("select * from p__Login_1(null,null,null,'".$_COOKIE['GUID']."');");
if($res->rowCount()>0)
{
$result = $res->fetch(PDO::FETCH_ASSOC);
$_SESSION['USER_ID']=$result['id'];
}
}*/
$fn=filter_input(INPUT_GET, 'fn', FILTER_VALIDATE_INT, array('options'=>array('default'=>-1)));
$HTTP_INPUT=file_get_contents("php://input");
if($HTTP_INPUT)
{
$doc = new DOMDocument();
try
{
$doc->loadXML($HTTP_INPUT);
} catch (Exception $e)
{
sendError($e->getMessage());
}
$reqNode = $doc->documentElement;
if ($reqNode)
{
$fn = $reqNode->getAttribute("fn"); //Номер функции
}
}
//описание
//(fn==0) - отправить метаданные клиенту по запрошенному узлу
//(fn==1) - вставить одну запись в базу данных (результат id записи)
//(fn==2) - обновить запись
//(fn==3) - удалить запись
//(fn==4 || fn==11) - отправить данные клиенту соответствии с значением фильтра
//(fn==5) - взять данные для редактирования 1й записи по id
//(fn==6) - вернуть клиенту данные для заполнения обьекта SELECT выделенно в отдельную функцию для экономии трафика здесь могут также использоваться фильтры
//(fn==7) - залогинеться
//(fn==8) - отчёты почти тоже самое что и функция 4
//(fn==9) - Сохранить двоичные данные в базу
//(fn==10) - Получить двоичные данные из базы
if ($fn==0) //отправить метаданные клиенту по запрошенному узлу
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError('Вы не авторизованы! '.$_SERVER['PHP_SELF']);
$typename=findFirstNode($reqNode, "type")->getAttribute("n");
$currNode=getMetadataNode($typename);
if ($currNode!=null)
{
$objXMLDocument=$currNode->ownerDocument;
//Вернём значение прав доступа для запрошенного объекта
//$allow=true;
$allow=false;
//$sql_query='select a.*,at.name from _Access a, _Actions at where a.del=false and at.id=a.action_id and at.name=\'Insert_'.$typename.'\' and a.role_id in (select group_id from _UsersRoles where user_id='.$_SESSION['USER_ID'].');'
$sql_query='select '.$Schema.'p_getaccess('.getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']).',\'Insert_'.$typename.'\') as allow;';
$res = $db->query($sql_query);
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$allow=$allow || ($row['allow'] == 't');
}
$xmlAttr = $objXMLDocument->createAttribute("ins"); //insert
$xmlAttr->nodeValue = $allow ? "1" : "0";
$currNode->setAttributeNode($xmlAttr);
$allow=false;
//$sql_query='select a.*,at.name from _Access a, _Actions at where a.del=false and at.id=a.action_id and at.name=\'Update_'.$typename.'\' and a.role_id in (select group_id from _UsersRoles where user_id='.$_SESSION['USER_ID'].');';
$sql_query='select '.$Schema.'p_getaccess('.getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']).',\'Update_'.$typename.'\') as allow;';
$res = $db->query($sql_query);
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$allow=$allow || ($row['allow'] == 't');
}
$xmlAttr = $objXMLDocument->createAttribute("upd"); //insert
$xmlAttr->nodeValue = $allow ? "1" : "0";
$currNode->setAttributeNode($xmlAttr);
$allow=false;
//$sql_query='select a.*,at.name from _Access a, _Actions at where a.del=false and at.id=a.action_id and at.name=\'Delete_'.$typename.'\' and a.role_id in (select group_id from _UsersRoles where user_id='.$_SESSION['USER_ID'].');';
$sql_query='select '.$Schema.'p_getaccess('.getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']).',\'Delete_'.$typename.'\') as allow;';
$res = $db->query($sql_query);
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$allow=$allow || ($row['allow'] == 't');
}
$xmlAttr = $objXMLDocument->createAttribute("del"); //delete
$xmlAttr->nodeValue = $allow ? "1" : "0";
$currNode->setAttributeNode($xmlAttr);
$allow=true;
$xmlAttr = $objXMLDocument->createAttribute("sel"); //select
$xmlAttr->nodeValue = $allow ? "1" : "0";
$currNode->setAttributeNode($xmlAttr);
//Удаляем все запросы из узла
for($i=0;$i<5;$i++)
{ $nsql=findFirstNode($currNode, "sql-query");
if($nsql!=NULL) $nsql->parentNode->removeChild($nsql);
}
$xmlstring='<?xml version="1.0" encoding="utf-8"?><metadata fn="0">'.$objXMLDocument->saveXML($currNode).'</metadata>';
header('Content-type: text/xml');
header("Cache-Control: no-cache, must-revalidate");
echo $xmlstring;
Exit();
}else
{
sendError('Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==1) //вставка записи (результат id записи)
{
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError('Вы не авторизованы! '.$_SERVER['PHP_SELF']);
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
$typename=findFirstNode($reqNode,"type")->getAttribute("n");
$currNode=getMetadataNode($typename);
if ($currNode!=null)
{
$objXMLDocument=$currNode->ownerDocument;
$sql_query=getCdataValue(findFirstNodeOnAttribute($currNode, "sql-query", "t", "i"));
$nodeProp=findFirstNode($reqNode,"properties");
//Представляем SQL в виде параметров
$nodePropData=$nodeProp->firstChild;
while($nodePropData != null)
{
if (($nodePropData->nodeName=="prop"))
{
//$vt=findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("vt");
$nPropR = findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"));
if($nPropR!=NULL) { $vt=$nPropR->getAttribute("vt"); } else { $vt=''; }
if($vt=='blob')
{ $sql_query=str_replace('${'.$nodePropData->getAttribute("n").'}',':'.$nodePropData->getAttribute("n"),$sql_query);
//Название файла запишем в указаное поле
$val=getCdataValue($nodePropData);
$cd=findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("cd");
$nd=findFirstNodeOnAttribute($nodeProp,'prop','n',$cd);
if($nd!=null) { getCdata($nd)->nodeValue=$val; }
}else if($vt=='file')
{
$val=getCdataValue($nodePropData);
$valSql=getSQLValue($vt, $val);
$sql_query=str_replace('${'.$nodePropData->getAttribute("n").'}',$valSql,$sql_query);
//Копируем файл из './temp/' в указанную папку относительно корня сайта
$flnm = afterLast($val,'_');
$dir = "./temp/";
if($val!='' && file_exists($dir.$flnm))
{
$path= $_SERVER['DOCUMENT_ROOT'].'/'.findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("path");
@mkdir($path); //Создаём папку если её нет
if(!rename($dir.$flnm, $path.$flnm))
sendError('Can\'t rename to "'.$path.$v.'"!');
}
}else
{ $v=getSQLValue($vt, getCdataValue($nodePropData));
$sql_query=str_replace('${'.$nodePropData->getAttribute("n").'}',$v,$sql_query);
}
}
$nodePropData=$nodePropData->nextSibling;
}
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query); //Потому что PostgreSQL не может хранить id пользователя привязаного к сесии
$stmt = $db->prepare($sql_query);
if($stmt === false) sendError('Error preparing Statement');
//присваеваем параметрам значения (В записи может быть только 1 двоичное поля см bindParam или сделать несколько переменных)
$nodePropData=$nodeProp->firstChild;
while($nodePropData != null)
{
if (($nodePropData->nodeName=="prop"))
{
//$vt=findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("vt");
$nPropR = findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"));
if($nPropR!=NULL) { $vt=$nPropR->getAttribute("vt"); } else { $vt=''; }
//Если тип blob то в качастве параметра приходит название файла переданого на сервер заранее
if($vt=='blob')
{ $v=getCdataValue($nodePropData);
if($v!='' && file_exists('./temp/'.afterLast($v,'_')))
{ $v = fopen('./temp/'.afterLast($v,'_'), 'rb');
} else $v=null;
$stmt->bindParam(':'.$nodePropData->getAttribute("n"), $v, PDO::PARAM_LOB);
}
}
$nodePropData=$nodePropData->nextSibling;
}
try
{
$res = $stmt->execute();
} catch (Exception $e)
{ sendError($e->getMessage());
}
$result = $stmt->fetch(PDO::FETCH_NUM);
if($result[0]=='')
{
if(strpos($db_connection, 'sqlite')!==false) {
$result[0] = $db->lastInsertId(); //Для SQLite
}else{
sendError(trt('Failed_to_insert_record').'!');
}
}
$xmlstring='<?xml version="1.0" encoding="utf-8"?><metadata fn="1"><type n="'.$typename.'" id="'.$result[0].'"></type></metadata>';
header('Content-type: text/xml');
echo $xmlstring;
Exit();
}else
{
sendError('Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==2) //редактирование (результат id записи)
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError('Вы не авторизованы! '.$_SERVER['PHP_SELF']);
$nodeType=findFirstNode($reqNode,"type");
$typename=$nodeType->getAttribute("n");
$obj_id=$nodeType->getAttribute("id");
$node_properties=findFirstNode($nodeType,"properties");
$currNode=getMetadataNode($typename);
if ($currNode!=null)
{
$objXMLDocument=$currNode->ownerDocument;
$sql_query=getCdataValue(findFirstNodeOnAttribute($currNode, "sql-query", "t", "u"));
//Представляем blob поля в SQL запросе в виде параметров
$nodeProps=findFirstNode($reqNode,"properties");
$nodePropData=$nodeProps->firstChild;
while($nodePropData != null)
{
if (($nodePropData->nodeName=="prop"))
{
//$vt=findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("vt");
$nPropR = findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"));
if($nPropR!=NULL) { $vt=$nPropR->getAttribute("vt"); } else { $vt=''; }
if($vt=='blob')
{ $sql_query=str_replace('${'.$nodePropData->getAttribute("n").'}',':'.$nodePropData->getAttribute("n"),$sql_query);
//Название файла запишем в указаное поле
$val=getCdataValue($nodePropData);
$cd=findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("cd"); //Имя поля с которого нужно брать название файла
$nd=findFirstNodeOnAttribute($nodeProps,'prop','n',$cd);
if($nd!=null) getCdata($nd)->nodeValue=$val;
}else if($vt=='file') //Файл который не загружается в базу а храниться в файловой системе
{
$val=getCdataValue($nodePropData);
$valSql=getSQLValue($vt, $val);
$sql_query=str_replace('${'.$nodePropData->getAttribute("n").'}',$valSql,$sql_query);
//Копируем файл в указанную папку относительно корня сайта
$flnm = afterLast($val,'_');
$dir = "./temp/";
if($val!='' && file_exists($dir.$flnm))
{
$path= $_SERVER['DOCUMENT_ROOT'].'/'.findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("path");
@mkdir($path);//Создаём папку если её нет
if(!rename($dir.$flnm, $path.$flnm))
sendError('Can\'t rename to "'.$path.$v.'"!');
}
}else
{
$val=getSQLValue($vt, getCdataValue($nodePropData));
$sql_query=str_replace('${'.$nodePropData->getAttribute("n").'}',$val,$sql_query);
}
}
$nodePropData=$nodePropData->nextSibling;
}
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query); //Потому что PostgreSQL не может хранить id пользователя привязаного к сесии
$sql_query=str_replace('${'.$currNode->getAttribute("ObjectID").'}',getSQLValue(gettype($obj_id),$obj_id),$sql_query); //Так как пока идентификатор базы отдельно передаётся
//sendError($sql_query);
$stmt = $db->prepare($sql_query);
if($stmt === false) sendError('Error preparing Statement');
//Присваеваем параметру двоичную информацию (Внимание! Только 1 параметр может быть в 1 записи (почему?))
$pos_v = 0;
$mas_v[$pos_v]=null; //Чтобы данные не перекрывали друг друга при вставке
$nodePropData=$nodeProps->firstChild;
while($nodePropData != null)
{
if (($nodePropData->nodeName=="prop"))
{
//$vt=findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"))->getAttribute("vt");
$nPropR = findFirstNodeOnAttribute($currNode,"prop","n",$nodePropData->getAttribute("n"));
if($nPropR!=NULL) { $vt=$nPropR->getAttribute("vt"); } else { $vt=''; }
if($vt=='blob')
{
$path_v=getCdataValue($nodePropData);
if($path_v!='' && file_exists('./temp/'.afterLast($path_v,'_')))
{ $v = fopen('./temp/'.afterLast($path_v,'_'), 'rb');
}else
{ $v=null;
}
$mas_v[$pos_v]=$v;
$stmt->bindParam(':'.$nodePropData->getAttribute("n"), $mas_v[$pos_v], PDO::PARAM_LOB);
$pos_v++;
}
}
$nodePropData=$nodePropData->nextSibling;
}
try
{ $res = $stmt->execute();
} catch (Exception $e)
{ sendError($e->getMessage()."\n".$sql_query);
}
$result = $stmt->fetch(PDO::FETCH_NUM); //$obj_id
if($result[0]==''){ $result[0]=$obj_id; }
$xmlstring='<?xml version="1.0" encoding="utf-8"?><metadata fn="2"><type n="'.$typename.'" id="'.$result[0].'"></type></metadata>';
header('Content-type: text/xml');
echo $xmlstring;
Exit();
}else
{
sendError('Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==3) //удаление (результат id записи)
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError('Вы не авторизованы! '.$_SERVER['PHP_SELF']);
$nodeType=findFirstNode($reqNode,"type");
$typename=$nodeType->getAttribute("n");
$obj_id=$nodeType->getAttribute("id");
$currNode=getMetadataNode($typename);
if ($currNode!=null)
{
$objXMLDocument=$currNode->ownerDocument;
$sql_query=getCdataValue(findFirstNodeOnAttribute($currNode, "sql-query", "t", "d"));
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query); //Потому что PostgreSQL не может хранить id пользователя привязаного к сесии
$sql_query=str_replace('${'.$currNode->getAttribute("ObjectID").'}',getSQLValue(gettype($obj_id),$obj_id),$sql_query);
//Выполняем
try
{ $res = $db->query($sql_query);
}catch (Exception $e)
{ sendError($e->getMessage());
}
//записываем id удалённой записи для удаления без перезагрузки страницы через javascript
$xmlstring="";
$xmlstring.="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$xmlstring.='<metadata fn="3">';
$xmlstring.=" <type n=\"".$typename."\" id=\"".$obj_id."\"></type>\n";
$xmlstring.="</metadata>\n";
header('Content-type: text/xml');
echo $xmlstring;
Exit();
}else
{
sendError('Не найден запрошенный узел: "'.$typename.'"!');
}
}else
if ($fn==4 || $fn==11) //взять данные из базы по переданным значениям фильтра ($fn==11 для обновления записи у клиента после вставки или редактировании)
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError('Вы не авторизованы! 4'.$_SERVER['PHP_SELF']);
$rowspagecount = 100; //записей на страницу
$nTypeR=findFirstNode($reqNode,'type');
$typename=$nTypeR->getAttribute("n");
$pagepos=$nTypeR->getAttribute("pp"); //текущяя страница page pos
$currNode=getMetadataNode($typename);
if ($currNode!=null)
{
$objXMLDocument=$currNode->ownerDocument;
$objListR = findFirstNode($nTypeR,'objects-list');
//В переданном запросе может быть не полный фильтр заполняем серверный значениями из переданного
$f1=findNodeOnPath($currNode,'objects-list/filter');
$f2=findNodeOnPath($nTypeR,'objects-list/filter');
setFilter($f1,$f2);//заменить все значения первого фильтра значениями из второго
$sql_query=getCdataValue(findNodeOnPath($currNode, "objects-list/sql-query"));
if($f1!=null)
{
$nextnode=$f1->firstChild;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{ $vt=$nextnode->getAttribute("vt");
$val=getCdataValue($nextnode);
$val=getSQLValue($vt,$val);
$sql_query=str_replace('${'.$nextnode->getAttribute("n").'}',$val,$sql_query);
}
$nextnode = $nextnode->nextSibling;
}
}
$vType=gettype($_SESSION['USER_ID']);
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query);
if($objListR!=null && $objListR->getAttribute('order')!='' && $objListR->getAttribute('order')!=null && $objListR->getAttribute('order')!='null')
{
$sql_query=str_replace('${_order}',findNodeOnAttribute(findFirstNode($currNode,'objects-list'), "column","n",$objListR->getAttribute("order"))->getAttribute("order"),$sql_query);
}else $sql_query=str_replace('${_order}','1',$sql_query);
//sendError($sql_query);
//Выполняем запрос
try
{ $res = $db->query($sql_query);
} catch (Exception $e)
{ sendError($e->getMessage().' '.$sql_query);
}
//Формируем ответ
$pagecount=ceil($res->rowCount()/$rowspagecount); //Кол-во страниц
//В месте с фильтром может прити и название полей которые нужно выбрать если есть хоть 1 поле то выберать только его
$columns = array();
$nextnode=findNode($nTypeR,'objects-list');
if($nextnode)
{ $nextnode=$nextnode->firstChild;//Пытаемся заполнить из запроса
$i=0;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{ $columns[$i]=$nextnode->getAttribute("n");
$i++;
}
$nextnode = $nextnode->nextSibling;
}
}
if(count($columns)==0)//Если нет ни одного столбца заполняем массив из серверного XML
{
$nextnode=findNode($currNode,'objects-list');
if($nextnode)
{ $nextnode=$nextnode->firstChild;//Пытаемся заполнить из запроса
$i=0;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{ $columns[$i]=$nextnode->getAttribute("n");
$i++;
}
$nextnode = $nextnode->nextSibling;
}
}
}
//перебираем RS и строим XML только из тех столбцов которые записанны в секци objects-list поля column в не зависимости от их видимости
$xmlstring='';
$xmlstring.='<?xml version="1.0" encoding="utf-8"?>'."\n";
$xmlstring.='<metadata fn="'.$fn.'"><type n="'.$typename.'" pc="'.$pagecount.'" pp="'.$pagepos.'">'."\n";
//Перечисляю название выбираемых столбцов через запятую
$xmlstring.='<objects-list>';
$nextnode=findNode($currNode,'objects-list')->firstChild;
while ($nextnode)
{
if ($nextnode->nodeName=='column')
{
$xmlstring.='<column n="'.$nextnode->getAttribute("n").'"/>';
}
$nextnode = $nextnode->nextSibling;
}
$xmlstring.='</objects-list>';
$node=findFirstNode($reqNode,'objects-list');
$pos=-1;
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$pos++;
if (($pagepos!=-1)&&(($pos<($pagepos*$rowspagecount))||($pos>=$pagepos*$rowspagecount+$rowspagecount))) { continue; }
//разрешать или запрещять редактировать запись надо проверять в хранимке а также запрещять либо разрешать редактировать колонку
//для каждой записи формируеться строка настроек со значениями что нужно запретить в таком виде "iuds"
//$access=$row["access"];
$access=''; //u = enable update field, d = enable delete field
if(!array_key_exists("_u",$row)) { $access.="u"; } else { $access.=$row["_u"]; }
if(!array_key_exists("_d",$row)) { $access.="d"; } else { $access.=$row["_d"]; }
if(array_key_exists($currNode->getAttribute("ObjectID"),$row))
$xmlstring.=' <record id="'.$row[$currNode->getAttribute("ObjectID")].'" a="'.$access.'">';
else
$xmlstring.=' <record id="" a="'.$access.'">';
$nextnode=findNode($currNode,'objects-list')->firstChild;
while ($nextnode)
{
if ($nextnode->nodeName=='column')
{
if(array_key_exists($nextnode->getAttribute("n"),$row))
{
$xmlstring.='<![CDATA['.$row[$nextnode->getAttribute("n")].']]>';
}else
{
sendError("Column \"".$nextnode->getAttribute("n")."\" not exists in \"$typename\" for select!");
}
}
$nextnode = $nextnode->nextSibling;
}
$xmlstring.='</record>'."\n";
}
$res->closeCursor();
$xmlstring.='</type></metadata>'."\n";
//sendError('pos1='.$xmlstring);
header('Content-type: text/xml');
echo $xmlstring;
}else
{
sendError("Не найден запрошеный узел!");
}
}else
if ($fn==5) //вернуть клиенту данные по id для редактирования одной записи
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError('Вы не авторизованы! '.$_SERVER['PHP_SELF']);
$sql_query='';
$node=findFirstNode($reqNode,'type');
$typename=$node->getAttribute("n");
$idval=$node->getAttribute("id"); //Значение идентификатора
$currNode=getMetadataNode($typename);
if ($currNode!=null)
{
$objXMLDocument=$currNode->ownerDocument;
//Тип поля с ObjectID
$nField=findFirstNodeOnAttribute(findNode($currNode, 'properties'), "prop", "n", $node->getAttribute('ObjectID'));
$csql=findNode(findFirstNodeOnAttribute($currNode, "sql-query", "t", "s"), "#cdata-section");
if($csql!=NULL && $csql->nodeValue!="") //Есть ли SQL запрос
{
$sql_query=$csql->nodeValue;
$sql_query=str_replace('${'.$node->getAttribute("ObjectID").'}',getSQLValue($nField->getAttribute('vt'),$idval),$sql_query);
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query);
}
}
//sendError($sql_query);
try
{
$res = $db->query($sql_query);
} catch (Exception $e)
{ sendError($e->getMessage());
}
if(strpos($db_connection, 'sqlite')===false) //Для SQLite не работает rowCount()
{
if($res->rowCount()!=1) sendError("Количество записей не равно одному!");
}
$xmls='';
$resX = $db->query('select xml from '.$Schema.'_metadata where del=false and name=\''.$typename.'\';');
while ($rowX = $resX->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$xmls='<?xml version="1.0" encoding="UTF-8"?><metadata>'.trts($rowX['xml']).'</metadata>';
}
if($xmls=='')
{
sendError("Metadata node \"".$name."\" is empty!");
}
//загружаем мета данные и смотрим какие поля должны передать клиенту
$mdoc = new DOMDocument();
try
{
$mdoc->loadXML($xmls);
} catch (Exception $e)
{ sendError($e->getMessage());
}
//находим нужный узел
$node=findNodeOnAttribute($mdoc->documentElement, "type","n",$typename);
$node=findFirstNode($node,'properties');
$xmlstring='<?xml version="1.0" encoding="utf-8"?>'."\n";
$xmlstring.='<metadata fn="5">'."\n";
$xmlstring.='<type n="'.$typename.'" id="'.$idval.'">'."\n";
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{ $xmlstring.='<properties>';
$nextnode=$node->firstChild;
while($nextnode)
{
if($nextnode->nodeName=='prop')
{
try
{
if(array_key_exists ( $nextnode->getAttribute("n"), $row) || ($nextnode->getAttribute("vt")=="file" && array_key_exists ( $nextnode->getAttribute("cd"), $row)))
{
if($nextnode->getAttribute("vt")=="b"){ if($row[$nextnode->getAttribute("n")]===false) { $row[$nextnode->getAttribute("n")]="0"; } else if($row[$nextnode->getAttribute("n")]===true) { $row[$nextnode->getAttribute("n")]="1"; } }
if($nextnode->getAttribute("vt")=="blob") { //Только blob не file так как file как обычная текстовая строка (100 символов)
if(array_key_exists($nextnode->getAttribute("cd"), $row)) {
$xmlstring .= '<prop n="' . $nextnode->getAttribute("n") . '"><![CDATA[' . $row[$nextnode->getAttribute("cd")] . ']]></prop>' . "\n";
}else{
sendError('Поле "'.$nextnode->getAttribute("cd").'" не найдено в результирующем наборе!');
}
}
else {
$xmlstring.='<prop n="'.$nextnode->getAttribute("n").'"><![CDATA['.$row[$nextnode->getAttribute("n")].']]></prop>'."\n";
}
}else
{
sendError('Поле "'.$nextnode->getAttribute("n").'" не найдено в результирующем наборе!');
}
} catch (Exception $e) { sendError($e->getMessage()); }
}
$nextnode = $nextnode->nextSibling;
}
$xmlstring.='</properties>';
}
$xmlstring.='</type>';
$xmlstring.='</metadata>';
header('Content-type: text/xml');
echo $xmlstring;
}else
if ($fn==6) //вернуть клиенту данные колонки таблицы для заполнения выпадающего списка SELECT либо выборка названия поля типа object
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError('Вы не авторизованы! '.$_SERVER['PHP_SELF']);
$tNodeR=findFirstNode($reqNode,'type');
$typename=$tNodeR->getAttribute("n"); //Название принятого узла
$columnname=$tNodeR->getAttribute("c"); //Столбец для выбора (через , могут перечислятся)
$columns=explode(",",$columnname);
$propName=$tNodeR->getAttribute("pn"); //Название поля <prop> нигде не используется передаётся обратно в результат
//Теперь а нутри фильтра передаётся поэтому ненужно $propid=$tNodeR->getAttribute("id"); //-1 или '' то много записей иначе 1 должна вернуться
//if($propid==-1 || $propid=='') $propid='NULL';
$currNode=getMetadataNode($typename);
if($currNode==null) sendError("Not find \"".$typename."\"!");
$objXMLDocument=$currNode->ownerDocument;
$objListR = findFirstNode($tNodeR,'objects-list'); //Из запроса
$f1=findNodeOnPath($currNode, 'objects-list/filter');
$f2=findNodeOnPath($tNodeR,'objects-list/filter');
setFilter($f1,$f2);//заменить все значения первого фильтра значениями из второго
$sql_query=getCdataValue(findNodeOnPath($currNode, "objects-list/sql-query"));
if($f1!=NULL)
{
$nextnode=$f1->firstChild;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{ $val=getSQLValue($nextnode->getAttribute("vt"),getCdata($nextnode)->nodeValue);
$sql_query=str_replace('${'.$nextnode->getAttribute("n").'}',$val,$sql_query);
}
$nextnode = $nextnode->nextSibling;
}
}
//$sql_query=str_replace('${'.$currNode->getAttribute("ObjectID").'}',getSQLValue(gettype($propid),$propid),$sql_query); //Чтоб вернулась 1 запись если это не выпадающий
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query);
if($objListR!=null && $objListR->getAttribute('order')!='' && $objListR->getAttribute('order')!=null && $objListR->getAttribute('order')!='null')
{
$sql_query=str_replace('${_order}',findNodeOnAttribute(findFirstNode($currNode,'objects-list'), "column","n",$objListR->getAttribute("order"))->getAttribute("order"),$sql_query);
}else $sql_query=str_replace('${_order}','1',$sql_query);
try
{ $res = $db->query($sql_query);
} catch (Exception $e)
{ sendError($e->getMessage());
}
//выбираем данные из базы и отправляем клиенту
$xmlstring='<?xml version="1.0" encoding="utf-8"?>'."\n";
$xmlstring.='<metadata fn="6">'."\n";
$xmlstring.='<type n="'.$typename.'" pn="'.$propName.'">'."\n";
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$xmlstring.='<record id="'.$row[$currNode->getAttribute("ObjectID")].'">';
$val="";
for($i=0;$i<count($columns);$i++)
{
if ($val!="") $val.=" ";
if(array_key_exists($columns[$i],$row))
{
$val.=$row[$columns[$i]];
}else
{
sendError("Column \"$columns[$i]\" not exists in \"$typename\" for select to drop down list!");
}
}
$xmlstring.='<![CDATA['.$val.']]>';
$xmlstring.='</record>'."\n";
}
$xmlstring.='</type>'."\n";;
$xmlstring.='</metadata>'."\n";;
header('Content-type: text/xml');
echo $xmlstring;
}else
if ($fn==7)//Залогинеться
{
$cmd=getCdataValue(findFirstNode($reqNode,"cmd"));
$login=getCdataValue(findFirstNode($reqNode,"login"));
$password=getCdataValue(findFirstNode($reqNode,"password"));
$guid=getCdataValue(findFirstNode($reqNode,"guid")); //Зачем коментил?
if($cmd==0) //Restore password by email
{
$res = $db->query("select 1 from '.$Schema.'_Users where del=false and email = '$login';");
if($res->rowCount()>0)
{
mail($login,'pal.kz','Not implement',"Content-type: text/html; charset=utf-8\r\nFrom: smartpal Site <info@pal.kz>");
}
}elseif($cmd==1) //Logout
{
$sql='delete from '.$Schema.'_Logins where sessionid='.getSQLValue('string',$_COOKIE['GUID']).' and user_id='.getSQLValue('object',$_SESSION['USER_ID']).';';
try
{ $db->exec($sql);
} catch (Exception $e)
{ sendError($e->getMessage());
}
unset($_SESSION['USER_ID']);
header('Content-type: text/xml');
header("Cache-Control: no-cache, must-revalidate");
$xs='<?xml version="1.0" encoding="utf-8"?>'."\n";
$xs.='<metadata fn="7">'."\n";
$xs.=' <cmd><![CDATA['.$cmd.']]></cmd><login><![CDATA[0]]></login><sesid><![CDATA['.session_id().']]></sesid><sesname><![CDATA['.session_name().']]></sesname>'."\n";
$xs.='</metadata>';
echo $xs;
exit();
}elseif($cmd==2) //Проверить залогинен ли пользователь
{
header('Content-type: text/xml');
header("Cache-Control: no-cache, must-revalidate");
$xs='<?xml version="1.0" encoding="utf-8"?>'."\n";
$xs.='<metadata fn="7">'."\n";
if(!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='')
{
$xs.=' <![CDATA[0]]><cmd><![CDATA['.$cmd.']]></cmd>'."\n";
}else
{
$xs.=' <![CDATA[1]]><cmd><![CDATA['.$cmd.']]></cmd>'."\n";
$res = $db->query('select * from '.$Schema.'p__Login('.getSQLValue($idType,$_SESSION['USER_ID']).',null,null,null,null,null);');
if($row = $res->fetch(PDO::FETCH_ASSOC))
{
$xs.=' <name><![CDATA['.$row['name'].']]></name>'."\n";
$xs.=' <surname><![CDATA['.$row['surname'].']]></surname>'."\n";
$xs.=' <patronymic><![CDATA['.$row['patronymic'].']]></patronymic>'."\n";
$xs.=' <company_id><![CDATA['.$row['company_id'].']]></company_id>'."\n";
}
}
$xs.='</metadata>';
echo $xs;
exit();
}elseif ($cmd==3) //Авторизация по логину и паролю
{
//По идентификатору выбираем информацию о пользователе
$ans='0';
$name='';
$surname='';
$patronymic='';
$sql="select * from ".$Schema."p__Login(".getSQLValue($idType,$_SESSION['USER_ID']).",'$login','$password',null,null,null);";
$res = $db->query($sql);
if($res->rowCount()>0)
{ $result = $res->fetch(PDO::FETCH_ASSOC);
$ans='1';
$_SESSION['USER_ID']=$result['id'];
$name=$result['name'];
$surname=$result['surname'];
$patronymic=$result['patronymic'];
}
header('Content-type: text/xml');
header("Cache-Control: no-cache, must-revalidate");
$xs='<?xml version="1.0" encoding="utf-8"?>'."\n";
$xs.='<metadata fn="7">'."\n";
$xs.='<![CDATA['.$ans.']]>';
$xs.=' <cmd><![CDATA['.$cmd.']]></cmd>'."\n";
$xs.=' <login><![CDATA['.$ans.']]></login>'."\n";
$xs.=' <name><![CDATA['.$name.' '.$surname.' '.$patronymic.']]></name>'."\n";
$xs.=' <sesid><![CDATA['.session_id().']]></sesid>'."\n";
$xs.=' <sesname><![CDATA['.session_name().']]></sesname>'."\n";
$xs.='</metadata>';
echo $xs;
exit();
}else{
sendError('Command "'.$cmd.'" not find!');
}
}else
if ($fn==8)//Получить отчёт как Excel.xls файл (почти тоже самое что и функция 4)
{
$dir='./temp/';
if(isset($_REQUEST['file'])) {
$file = $_REQUEST['file'];
$myFile = $dir.$file;
if(file_exists($myFile))
{
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Length: '.filesize($myFile));
readfile($myFile);
exit();
}else
{
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
echo 'File "'.$file.'" not found!';
exit;
}
exit;
}
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') sendError(trt('You are not logged in!'));
//Выбираем информацию о текущем пользователе
$name='';
$sql="select Coalesce(surname,'') || ' ' || Coalesce(name,'') || ' ' || Coalesce(patronymic,'') as name from ".$Schema."_users where id=".$_SESSION['USER_ID'].";";
$res = $db->query($sql);
if($res->rowCount()>0)
{ $result = $res->fetch(PDO::FETCH_ASSOC);
$name='<i>'.$result['name'].'</i><br>';
}
$res=null; //Чтоб сработал сборщик мусора, а то вываливается ошибка: "Cannot execute queries while other unbuffered queries are active".
$nTypeR=findFirstNode($reqNode,'type');
$typename=$nTypeR->getAttribute("n");
$ext=$nTypeR->getAttribute("ext");
$currNode=getMetadataNode($typename);
if ($currNode!=null)
{
$objXMLDocument=$currNode->ownerDocument;
$objListR = findFirstNode($nTypeR,'objects-list');
//В переданном запросе может быть не полный фильтр заполняем серверный значениями из переданного
$f1=findNodeOnPath($currNode,'objects-list/filter');
$f2=findNodeOnPath($nTypeR,'objects-list/filter');
setFilter($f1,$f2);//заменить все значения первого фильтра значениями из второго
//Текстовые данные заполняются в поле caption и они вставляются в поля для информации что было заполнено
//Выбираем параметры фильтра (Для информирования что было заполнено)
$filter='<b>'.trt('Filter_options').'</b><br>';
$nextnode=$f1->firstChild;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{
if($nextnode->getAttribute('visible')!='0')
{
$filter.='<i>'.$nextnode->getAttribute("d").': </i>';
if($nextnode->getAttribute("vt")=='object')
{
if(getCdataValue($nextnode)=='')
{ $filter.='';
}else
{
//Ищем нужный узел и выполняем запрос
$nTypeO=getMetadataNode($nextnode->getAttribute("object"));
//$nTypeO=findNodeOnAttribute($objXMLDocument->documentElement,"type","n",$nextnode->getAttribute("object"));
$sql_query=getCdataValue(findNodeOnPath($nTypeO, "objects-list/sql-query"));
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query);
$nOID=findNodeOnAttribute(findNodeOnPath($nTypeO, "objects-list/filter"), 'column', 'n', $nTypeO->getAttribute('ObjectID'));
$sql_query=str_replace('${'.$nOID->getAttribute('n').'}',getSQLValue($nOID->getAttribute('vt'), getCdataValue($nextnode)),$sql_query);
//Обнуляем остальные значения фильтра
$nCol=findNodeOnPath($nTypeO, "objects-list/filter")->firstChild;
while ($nCol)
{ if ($nCol->nodeName=='column')
{ $sql_query=str_replace('${'.$nCol->getAttribute("n").'}','NULL',$sql_query);
}
$nCol = $nCol->nextSibling;
}
$res=null;
try
{ $res = $db->query($sql_query);
} catch (Exception $e)
{ sendError($e->getMessage());
}
if($res->rowCount()!=1) sendError(trt('The number of records is not equal to one!').' '.$sql_query);
$columns=explode(",",$nextnode->getAttribute('FieldCaption'));
if($res->rowCount()>0)
{
$row = $res->fetch(PDO::FETCH_ASSOC);
for($i=0;$i<count($columns);$i++)
{
$filter.=$row[$columns[$i]].' ';
}
}
$res=null; //Чтоб сработал сборщик мусора, а то вываливается ошибка: "Cannot execute queries while other unbuffered queries are active".
}
}else if($nextnode->getAttribute("vt")=='b')
{
if(getCdataValue($nextnode)=='1') $filter.='Да';
if(getCdataValue($nextnode)=='0') $filter.='Нет';
}else
{
$filter.=getCdataValue($nextnode);
}
$filter.='<br>';
}
}
$nextnode = $nextnode->nextSibling;
}
$sql_query=getCdataValue(findNodeOnPath($currNode, "objects-list/sql-query"));
$nextnode=$f1->firstChild;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{ $vt=$nextnode->getAttribute("vt");
$val=getCdataValue($nextnode);
$val=getSQLValue($vt,$val);
$sql_query=str_replace('${'.$nextnode->getAttribute("n").'}',$val,$sql_query);
}
$nextnode = $nextnode->nextSibling;
}
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query);
if($objListR!=null && $objListR->getAttribute('order')!='' && $objListR->getAttribute('order')!=null && $objListR->getAttribute('order')!='null')
{
$sql_query=str_replace('${_order}',findNodeOnAttribute(findFirstNode($currNode,'objects-list'), "column","n",$objListR->getAttribute("order"))->getAttribute("order"),$sql_query);
}else $sql_query=str_replace('${_order}','1',$sql_query);
//Выполняем запрос
try
{ $res = $db->query($sql_query);
} catch (Exception $e)
{ sendError($e->getMessage().$sql_query);
}
//Сохраняем результсет в файл в виде HTML с расширением XLS
$file='file_'.rand(0,1000).'.xls';
$myFile = $dir.$file;
$fh = fopen($myFile, 'w');
if($fh)
{
fwrite($fh, '<html>'."\n");
fwrite($fh, ' <head>'."\n");
fwrite($fh, ' <title>'.$currNode->getAttribute("d").'</title>'."\n");
fwrite($fh, ' <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'."\n");
fwrite($fh, '<style>td {mso-number-format: "\@";}</style>');
fwrite($fh, ' </head>'."\n");
fwrite($fh, ' <body>'."\n");
fwrite($fh, '<b>'.trt('Time_and_date_of_generation').': </b><i>'.date('H:i:s m.d.Y').'</i><br>');
fwrite($fh, '<b>'.trt('Creator').': </b>'.$name);
fwrite($fh, $filter);
fwrite($fh, ' <table border="1" cellspacing="0">'."\n");
fwrite($fh, ' <caption><b>'.findNode($currNode,'objects-list')->getAttribute("d").'</b></caption>'."\n");
fwrite($fh, ' <thead>'."\n");
fwrite($fh, ' <tr>');
fwrite($fh, '<td bgcolor="#d1d1d1">№</td>');
$nextnode=findNode($currNode,'objects-list')->firstChild;
$col=0;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{ fwrite($fh, '<td bgcolor="#d1d1d1" width="'.$nextnode->getAttribute("width").'px"><b>'.$nextnode->getAttribute("d")."</b></td>");
}
$nextnode = $nextnode->nextSibling;
}
fwrite($fh, ' </tr>'."\n");
fwrite($fh, ' </thead>'."\n");
fwrite($fh, ' <tbody>'."\n");
$pos=0;
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
fwrite($fh, ' <tr>');
fwrite($fh, '<td>'.(++$pos).'</td>');
$nextnode=findNode($currNode,'objects-list')->firstChild;
while ($nextnode)
{ if ($nextnode->nodeName=='column')
{
fwrite($fh, '<td>'.$row[$nextnode->getAttribute("n")].'</td>');
}
$nextnode = $nextnode->nextSibling;
}
fwrite($fh, '</tr>'."\n");
}
$res->closeCursor(); //Мож поможет избавиться от ошибки: "Cannot execute queries while other unbuffered queries are active."
fwrite($fh, ' </tbody>'."\n");
fwrite($fh, ' </table>'."\n");
fwrite($fh, ' </body>'."\n");
fwrite($fh, '</html>'."\n");
fclose($fh);
}
if($ext=="pdf")
{
//Если в виде PDF
$mpdf = new mPDF('utf-8', 'A4', '8', '', 10, 10, 7, 7, 10, 10); // задаем формат, отступы и.т.д.
$mpdf->list_indent_first_level = 0;
$mpdf->WriteHTML(file_get_contents($myFile)); // формируем pdf
$dir='./temp/';
$file='file_'.rand(0,1000).'_'.time().'.pdf';
$myFile = $dir.$file;
$mpdf->Output($myFile, 'F');
}
$myFile=getFullPath().'temp/'.$file;
//отправляем ссылку на файл
header('Content-type: text/xml');
echo '<?xml version="1.0" encoding="utf-8"?><metadata fn="8"><file><![CDATA['.$file.']]></file></metadata>';
//deleteTempFiles($dir);
}else
{
sendError(trt('Not found the requested node:').' "'.$typename.'"!');
}
}else
if ($fn==9) //Сохранить файл во временную папку
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
$dir = "./temp/";
if (!file_exists($dir)) {
mkdir($dir, 0777);
}
//Так как у файлов могут быть одинаковые имена считаем CRC и переименовываем файл отправля пользователю новое название файла
//В базе данных название файла будет преобразовываться так: "файл.txt" -> "файл_crc32.txt"
if(isset($_FILES['file']))
{
if(file_exists($_FILES['file']['tmp_name']))
{
$hash = hash_file( 'crc32', $_FILES['file']['tmp_name'] );
if(move_uploaded_file($_FILES['file']['tmp_name'],delPHPExt($dir.$hash.'.'.strtolower(getExtension($_FILES['file']['name'])))))
{
//Отправляем новое название файла клиенту
print "ok=".beforeLast($_FILES['file']['name'],'.').'_'.$hash.'.'.strtolower(getExtension($_FILES['file']['name']))."\n";
}
}else { print "ok=\n File \"".$_FILES['file']['tmp_name']."\" not find"; }
}
//Данный код загружается в iframe
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">';
print '<html>';
print ' <head>';
print ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
print ' </head>';
print ' <body>';
print ' <form name="form" enctype="multipart/form-data" action="records.php?fn=9" method="post">';
print ' <input type="hidden" name="state" value=""/>';
print ' <input type="file" name="file"><br/>';
print ' <input type="submit" value="Send File">';
print ' <input type="reset" value="Reset">';
print ' </form>';
print ' </body>';
print '</html>';
//Отчищяем временные файлы которые больше суток на сервере
deleteTempFiles($dir);
}else
if ($fn==10) //Отправить двоичные данные клиенту в виде файла (пока без докачки)
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
//Клиент передаёт название таблицы, название поля, id поля
$typename = $_REQUEST['t']; //Тип
$field = $_REQUEST['f']; //Название поля с двоичными данными
$name = $_REQUEST['n']; //поле с названием файла
$idval = $_REQUEST['i']; //Идентификатор поля в базе
$xmls='';
$resX = $db->query('select xml from '.$Schema.'_metadata where del=false and name=\''.$typename.'\';');
while ($rowX = $resX->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$xmls='<?xml version="1.0" encoding="UTF-8"?><metadata>'.trts($rowX['xml']).'</metadata>';
}
if($xmls=='')
{
sendError("Metadata node \"".$name."\" is empty!");
}
//Ищем поле в метаданных
$objXMLDocument = new DOMDocument();
try
{
$objXMLDocument->loadXML($xmls);
} catch (Exception $e)
{ echo $e->getMessage();
}
$currNode=findNodeOnAttribute($objXMLDocument->documentElement,"type","n",$typename);
if ($currNode!=null)
{
$pnode=findFirstNode($currNode,'properties');
$fnode=findFirstNodeOnAttribute($pnode,"prop","n",$field); //Поле в metedata.xml файла
$nnode=findFirstNodeOnAttribute($pnode,"prop","n",$fnode->getAttribute("cd")); //Поле в metedata.xml с именем файла
if($fnode->getAttribute("vt")=="blob") //Отправить файл клиенту из базы данных
{
$stmt = $db->prepare("SELECT \"$field\",length(\"$field\"),substring(\"$name\", position('_' IN \"$name\")+1) as name FROM $Schema\"$typename\" WHERE id='$idval'");
$stmt->execute();
$stmt->bindColumn(1, $blob, PDO::PARAM_LOB);
$stmt->bindColumn(2, $size, PDO::PARAM_INT);
$stmt->bindColumn(3, $name, PDO::PARAM_STR);
$stmt->fetch(PDO::FETCH_BOUND);
$data = stream_get_contents($blob);
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="'.$name.'"');
header('Content-Length: '.$size);
echo $data;
}else if($fnode->getAttribute("vt")=="file") //Отправить файл клиенту из файловой системы
{
//Тип поля с ObjectID
$nField=findFirstNodeOnAttribute(findNode($currNode, 'properties'), "prop", "n", $currNode->getAttribute('ObjectID'));
$csql=findNode(findFirstNodeOnAttribute($currNode, "sql-query", "t", "s"), "#cdata-section");
if($csql!=NULL && $csql->nodeValue!="") //Есть ли SQL запрос
{
$sql_query=$csql->nodeValue;
$sql_query=str_replace('${'.$currNode->getAttribute("ObjectID").'}',getSQLValue($nField->getAttribute('vt'),$idval),$sql_query);
$sql_query=str_replace('${_user_id}',getSQLValue(gettype($_SESSION['USER_ID']),$_SESSION['USER_ID']),$sql_query);
}
$res = $db->query($sql_query);
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$fname = $row[$field];
}
$dataFName = afterLast($fname,'_');
$rezFName = beforeLast($fname,'_');
$rezFName .= '.'.afterLast($fname,'.');
if(file_exists($_SERVER['DOCUMENT_ROOT'].'/'.$fnode->getAttribute('path').$dataFName))
{
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="'.$rezFName.'"');
header('Content-Length: '.filesize($_SERVER['DOCUMENT_ROOT'].'/'.$fnode->getAttribute('path').$dataFName));
readfile($_SERVER['DOCUMENT_ROOT'].'/'.$fnode->getAttribute('path').$dataFName);
exit();
}else
{
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
echo 'File "'.$_SERVER['DOCUMENT_ROOT'].'/'.$fnode->getAttribute('path').$dataFName.'" not found!';
exit;
}
}
}
}else
{
sendError("Неизвестная функция \"$fn\"!");
}