'; 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=''.trts($rowX['xml']).''; } 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=''.$objXMLDocument->saveXML($currNode).''; 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=''; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); 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=''; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); 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.="\n"; $xmlstring.=''; $xmlstring.=" \n"; $xmlstring.="\n"; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); 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.=''."\n"; $xmlstring.=''."\n"; //Перечисляю название выбираемых столбцов через запятую $xmlstring.=''; $nextnode=findNode($currNode,'objects-list')->firstChild; while ($nextnode) { if ($nextnode->nodeName=='column') { $xmlstring.=''; } $nextnode = $nextnode->nextSibling; } $xmlstring.=''; $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.=' '; else $xmlstring.=' '; $nextnode=findNode($currNode,'objects-list')->firstChild; while ($nextnode) { if ($nextnode->nodeName=='column') { if(array_key_exists($nextnode->getAttribute("n"),$row)) { $xmlstring.='getAttribute("n")].']]>'; }else { sendError("Column \"".$nextnode->getAttribute("n")."\" not exists in \"$typename\" for select!"); } } $nextnode = $nextnode->nextSibling; } $xmlstring.=''."\n"; } $res->closeCursor(); $xmlstring.=''."\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=''.trts($rowX['xml']).''; } 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=''."\n"; $xmlstring.=''."\n"; $xmlstring.=''."\n"; while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов { $xmlstring.=''; $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") { $xmlstring.='getAttribute("cd")].']]>'."\n"; } //else if($nextnode->getAttribute("vt")=="file") { $xmlstring.='getAttribute("cd")].']]>'."\n"; } else { $xmlstring.='getAttribute("n")].']]>'."\n"; } }else { sendError('Поле "'.$nextnode->getAttribute("n").'" не найдено в результирующем наборе!'); } } catch (Exception $e) { sendError($e->getMessage()); } } $nextnode = $nextnode->nextSibling; } $xmlstring.=''; } $xmlstring.=''; $xmlstring.=''; 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"); //Название поля нигде не используется передаётся обратно в результат //Теперь а нутри фильтра передаётся поэтому ненужно $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=''."\n"; $xmlstring.=''."\n"; $xmlstring.=''."\n"; while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов { $xmlstring.=''; $val=""; for($i=0;$i'; $xmlstring.=''."\n"; } $xmlstring.=''."\n";; $xmlstring.=''."\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 { $recovery=false; $res = $db->query("select email from ".$Schema."_Users where del=false and (email = '$login' or login = '$login');"); if($res->rowCount()>0) { while ($row = $res->fetch(PDO::FETCH_ASSOC)) { /*$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["email"]; }*/ $password = getPassword(6); $sql = 'update ' . $Schema . '_users set password=md5(:password) where email=:email'; $stmt = $db->prepare($sql); $stmt->bindValue(':password', $password, PDO::PARAM_STR); $stmt->bindValue(':email', $row["email"], PDO::PARAM_STR); try { $stmt->execute(); if ($stmt->rowCount() > 0) { //$result = $stmt->fetch(PDO::FETCH_NUM); $recovery = true; } } catch (Exception $e) { $db->rollBack(); sendError(1, $e->getMessage()); } $html = 'Message'; $html .= '

New password:

'; $html .= '' . $password . ''; $html .= ''; //mail($login,'rigor.kz','Not implement',"Content-type: text/html; charset=utf-8\r\nFrom: rigor Site "); if (!mail($login, 'Password for transit.istt.kz', $html, "Content-type: text/html; charset=utf-8\r\nFrom: Transit Site ")) { sendError("Failed to send mail to: " . $row["email"]); } } } if($recovery) { $xs = '' . "\n"; $xs .= ''; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); echo $xs; exit(); }else{ $xs = '' . "\n"; $xs .= ''; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); echo $xs; exit(); } }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']); $xs=''."\n"; $xs.=''."\n"; $xs.=' '."\n"; $xs.=''; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); echo $xs; exit(); }elseif($cmd==2) //Проверить залогинен ли пользователь { $xs=''."\n"; $xs.=''."\n"; if(!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID']=='') { $xs.=' '."\n"; }else { $xs.=' '."\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.=' '."\n"; $xs.=' '."\n"; $xs.=' '."\n"; $xs.=' '."\n"; } } $xs.=''; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); 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']; } $xs=''."\n"; $xs.=''."\n"; $xs.=''; $xs.=' '."\n"; $xs.=' '."\n"; $xs.=' '."\n"; $xs.=' '."\n"; $xs.=' '."\n"; $xs.=''; header('Content-type: text/xml'); header("Cache-Control: no-cache, must-revalidate"); 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=''.$result['name'].'
'; } $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=''.trt('Filter_options').'
'; $nextnode=$f1->firstChild; while ($nextnode) { if ($nextnode->nodeName=='column') { if($nextnode->getAttribute('visible')!='0') { $filter.=''.$nextnode->getAttribute("d").': '; 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;$igetAttribute("vt")=='b') { if(getCdataValue($nextnode)=='1') $filter.='Да'; if(getCdataValue($nextnode)=='0') $filter.='Нет'; }else { $filter.=getCdataValue($nextnode); } $filter.='
'; } } $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, ''."\n"); fwrite($fh, ' '."\n"); fwrite($fh, ' '.$currNode->getAttribute("d").''."\n"); fwrite($fh, ' '."\n"); fwrite($fh, ''); fwrite($fh, ' '."\n"); fwrite($fh, ' '."\n"); fwrite($fh, ''.trt('Time_and_date_of_generation').': '.date('H:i:s m.d.Y').'
'); fwrite($fh, ''.trt('Creator').': '.$name); fwrite($fh, $filter); fwrite($fh, ' '."\n"); fwrite($fh, ' '."\n"); fwrite($fh, ' '."\n"); fwrite($fh, ' '); fwrite($fh, ''); $nextnode=findNode($currNode,'objects-list')->firstChild; $col=0; while ($nextnode) { if ($nextnode->nodeName=='column') { fwrite($fh, '"); } $nextnode = $nextnode->nextSibling; } fwrite($fh, ' '."\n"); fwrite($fh, ' '."\n"); fwrite($fh, ' '."\n"); $pos=0; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { fwrite($fh, ' '); fwrite($fh, ''); $nextnode=findNode($currNode,'objects-list')->firstChild; while ($nextnode) { if ($nextnode->nodeName=='column') { fwrite($fh, ''); } $nextnode = $nextnode->nextSibling; } fwrite($fh, ''."\n"); } $res->closeCursor(); //Мож поможет избавиться от ошибки: "Cannot execute queries while other unbuffered queries are active." fwrite($fh, ' '."\n"); fwrite($fh, '
'.findNode($currNode,'objects-list')->getAttribute("d").'
'.$nextnode->getAttribute("d")."
'.(++$pos).''.$row[$nextnode->getAttribute("n")].'
'."\n"); fwrite($fh, ' '."\n"); fwrite($fh, ''."\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 ''; //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 ''; print ''; print ' '; print ' '; print ' '; print ' '; print '
'; print ' '; print '
'; print ' '; print ' '; print '
'; print ' '; print ''; //Отчищяем временные файлы которые больше суток на сервере 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=''.trts($rowX['xml']).''; } 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\"!"); }