This commit is contained in:
2024-03-25 23:13:12 +05:00
parent ba933a0712
commit 975d9ee310
16 changed files with 4710 additions and 0 deletions

0
.tgitconfig Normal file
View File

78
metadata/dbms/data.json Normal file
View File

@ -0,0 +1,78 @@
{
"type":{
"n":"Terminals",
"d":"trt('Terminal')",
"ObjectID":"id",
"edit_object":{
"columns":[
{"d":"id", "n":"id", "vt":"i4", "visible":"0"},
{"d":"trt('Company')", "n":"company_id", "vt":"object", "maybenull":"0", "ot":"Companies", "FieldCaption":"name", "selector":"combo"},
{"d":"trt('Phone')", "n":"phone", "vt":"string", "size":"20"},
{"d":"trt('Serial_number')", "n":"serial", "vt":"string", "size":"50"},
{"d":"IMEI", "n":"imei", "vt":"string", "size":"50", "maybenull":"0"},
{"d":"trt('Terminal model')", "n":"terminal_model_id", "vt":"object", "maybenull":"0", "ot":"TerminalsModels", "FieldCaption":"name", "selector":"combo"},
{"d":"trt('Description')", "n":"description", "vt":"text", "size":"500"}
],
"insert-query":"select * from main.p_Terminals_i(${_user_id},${company_id},${phone},${serial},${imei},${terminal_model_id},${description});",
"update-query":"select * from main.p_Terminals_u(${_user_id},${id},${company_id},${phone},${serial},${imei},${terminal_model_id},${description});",
"delete-query":"select * from main.p_Terminals_d(${_user_id},${id});",
"select-query":"select * from main.p_Terminals_s(${_user_id},${id},0,NULL);"
},
"show-object":{
"d":"trt('Terminals')",
"width":"1000",
"sql-query":"select * from main.p_terminals_ss(${_user_id},${id},${company_id},${terminal_id},${install},${imei},${serial});",
"filter":{
"columns":[
{"d":"id","n":"id","vt":"string","visible":"0"},
{"d":"trt('Company')","n":"company_id","vt":"object","object":"Companies","FieldCaption":"name","selector":"combo"},
{"d":"terminal_id","n":"terminal_id","vt":"i4","visible":"0"},
{"d":"trt('Installed')","n":"install","vt":"b"},
{"d":"trt('IMEI')","n":"imei","vt":"string"},
{"d":"trt('Serial_number')","n":"serial","vt":"string"}
]
},
"columns":[
{"d":"trt('Terminal_model')", "n":"terminal_model_name", "width":"150"},
{"d":"trt('Company')", "n":"campany_name", "width":"150"},
{"d":"trt('Installed_on')", "n":"object_name", "width":"150"},
{"d":"trt('Phone')", "n":"phone", "width":"150"},
{"d":"trt('Serial_number')", "n":"serial", "width":"120"},
{"d":"IMEI", "n":"imei", "width":"300"},
{"d":"trt('Description')", "n":"description", "width":"300"},
{"d":"trt('Count_sensors')", "n":"tscnt", "width":"120",
"type":{
"n":"TerminalsSensors",
"show-object":{
"d":"trt('Sensors_types')",
"filter":{
"height":"1",
"columns":[
{
"n":"terminal_id",
"data":"${id}"
}
]
}
}
}
},
{"d":"Настройки", "n":"tstcnt", "width":"120",
"type":{
"n":"TerminalsSettings",
"show-object":{
"filter":{
"columns":[
{
"n":"terminal_id",
"data":"${id}"
}
]
}
}
}
}
]
}
}
}

1450
metadata/dbms/dbms.xyz Normal file

File diff suppressed because it is too large Load Diff

View File

View File

@ -0,0 +1,40 @@
<template>
<h1>{{ type.d }}</h1>
<div v-for="(column,index) in type.edit_object.columns">
<div v-if="column.vt=='i4'" :style="{ backgroundColor: index % 2 === 0 ? 'var(--row-color-1)' : 'var(--row-color-2)' }">
<div style="width:150px;display:inline-block;">{{column.d}}</div>
<input type="text" v-model="column.value">
<input type="button" class="button-secondary" style="width:22px;margin:0px;padding:0px;" :click="column.value += 1" value="+" title="trt('Increase_by_1')">
<input type="button" class="button-secondary" style="width:22px;margin:0px;padding:0px;" :click="column.value -= 1" value="-" title="trt('Decrease_by_1')">
</div>
<div v-if="column.vt=='object'" :style="{ backgroundColor: index % 2 === 0 ? 'var(--row-color-1)' : 'var(--row-color-2)' }">
<div style="width:150px;display:inline-block;">{{column.d}}</div>
<input type="text">
</div>
<div v-if="column.vt=='string'" :style="{ backgroundColor: index % 2 === 0 ? 'var(--row-color-1)' : 'var(--row-color-2)' }">
<div style="width:150px;display:inline-block;">{{column.d}}</div>
<input type="text">
</div>
</div>
<div style="display: flex; justify-content: space-between;">
<div>
<label><input type="checkbox">trt('Repeat_the_addition_of_the_entry')</label>
</div>
<div>
<div style="display: inline-block;">
<input type="button" class="button-secondary" value="trt('Apply')">
<input type="button" class="button-secondary" value="trt('Cancel')">
</div>
</div>
</div>
</template>
<script>
export default {
name: "show_object"
}
</script>
<style scoped>
</style>

1450
metadata/dbms/records.xyz Normal file

File diff suppressed because it is too large Load Diff

44
metadata/dbms/session.xyz Normal file
View File

@ -0,0 +1,44 @@
<?
//Скрипт должен возвращять время в секундах когда умрёт сесия
//Скрипт работающий как AJAX в связке с javascript функцией 1 после загрузки выдать наименование сессионной переменной потом проверять на существование соответствующего файла в базе данных
//Проверить обновляется ли файлик сесии
//http://leopard.in.ua/2008/09/20/otslezhivanie-istecheniya-sroka-dejstviya-sessij/
//session_save_path('C:\ses');
require_once("../include/tools.php");
$host = $_SERVER['HTTP_HOST'];
$host = '.'.cutAfterLast($host,'.',2);
ini_set('session.cookie_domain', $host);
error_reporting(E_ALL);
if(isset($_GET['fn'])) $fn=$_GET['fn']; else $fn='';
if($fn=='0')
{
echo session_name();
exit;
}else
if($fn=='1')
{
@session_start(['cookie_lifetime' => 43200,'cookie_secure' => true,'cookie_httponly' => true]);
echo session_id();
exit;
}else
if($fn=='2') //Вернуть время до смерти сесии в секундах
{
if(isset($_GET[session_name()])) $id=$_GET[session_name()]; else exit;
$sessionfile = ini_get('session.save_path') . DIRECTORY_SEPARATOR . 'sess_'.$id;
if ( file_exists($sessionfile) )
{
//echo ini_get('session.gc_maxlifetime') - (time() - filemtime($sessionfile));
echo '1'; //Чтоб только если файл удалился
}else echo '-1';
exit;
}else
{
echo 'error';
}

View File

View File

@ -0,0 +1,13 @@
<template>
</template>
<script>
export default {
name: "show_object"
}
</script>
<style scoped>
</style>

488
metadata/dbms/window.js Normal file
View File

@ -0,0 +1,488 @@
//Класс окна
class TWin
{
constructor(dialog,path)
{
this.dialog=dialog; //Показывать окно как диалог (без возможности изменения размеров)
if(typeof path !== 'undefined')
this.path=path;
else
this.path='../resources';
this.disableClosing=false;
this.closed=false; //Закрыли (те. удалили из родителя и детей и из DOM)
this.onClose=null; //слушатель закрытия окна
this.childs=new Array(); //Подчинёные окна
this.parent=null; //родительское окно
this.name="TWin";
this.tWinId=0;
this.dx=0;
this.dy=0;
this.sel=false;
this.obj=null; //user data
this.div=document.createElement('div'); //Окно
this.divsh=document.createElement('div'); //Тень для модального окна
this.tbl=null;
this.h0=null;
this.ca=null;
this.co=null;
this.shadow = false; //Показывать ли тень вокруг окошка
this.uid=getUID(); //Уникальныйидентификатор
this.pBarCnt=0; //Прогресс бар
this.pBarDiv=null; //Прогресс бар
this.fnResizeListener=null;
}
addResizeListener(func)
{
this.fnResizeListener=func;
this.fnResizeListener();
}
onResize(x,y)
{
let win=this;
return function(e){
if(!e) e = window.event;
win.dx=e.pageX || e.x
win.dy=e.pageY || e.y
document.onmousedown = function() {
if(win.fnResizeListener!=null) win.fnResizeListener();
return false;
};
document.onmousemove = function(e) {
if(!e) e = window.event;
let x2 = e.pageX || e.x;
let y2 = e.pageY || e.y;
let w=parseInt(win.div.style.width)-(win.dx-x2)*x;
let h=parseInt(win.div.style.height)-(win.dy-y2)*y;
if(w<0)w=0;
if(h<0)h=0;
win.setWidth(w+"px");
win.setHeight(h+"px");
if(x<0)win.div.style.left=parseInt(win.div.style.left)-(win.dx-x2)+"px";
if(y<0)win.div.style.top=parseInt(win.div.style.top)-(win.dy-y2)+"px";
win.dx=x2;
win.dy=y2;
if(win.fnResizeListener!=null) win.fnResizeListener();
return false;
};
document.onmouseup = function() {
document.onmousedown = null;
document.onmousemove = MMove//null;
if(win.fnResizeListener!=null) win.fnResizeListener();
return false;
};
return false;
};
}
Close() //Закрыть и удалить окно из родителя и менеджера
{
if(this.disableClosing)
return;
//Переместил перед удалением компонент так как бывает нужно поработать с ними перед удалением
if(this.onClose!=null)
{
this.onClose();
}
this.hide(true);
this.setParent(null);
for(let i=0;i<this.childs.length;i++) if(this.childs[i]!=null) this.childs[i].parent=null
//??? зачем коментил (пояснение не понятное)? раскоментил потому что после пересоздания формы HTML id сохранялись (Вот непонятный комент: Закоментил потому что в магазине могут закрыть окно а оно больше не появится...)
if(this.div.parentNode!=null) this.div.parentNode.removeChild(this.div);
if(this.divsh.parentNode!=null) this.divsh.parentNode.removeChild(this.divsh);
this.closed=true;
};
//Типа конструктор создать окно с заданой позицией
BuildGUI(x,y)
{
this.tWinId=g_wins.add(this);
/*
let hd='';
hd+='<table style="width: 100%;">';
hd+=' <tr>';
hd+=' <td style="vertical-align:bottom;cursor:move;" id="TWin_H1_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/t1.gif" style="width: 20px; height: 20px; display: block;" alt="" border="0px" draggable="false"/></td>';
hd+=' <td align="center" width="100%" bgcolor="#3366CC" style="font-weight: bold; cursor:move; background: #92b5df url('+this.path+'/metadata/dbms/form/1.gif) repeat-x top;" id="TWin_H2_'+this.tWinId+'"><nobr id="TWin_Ca_'+this.tWinId+'"></nobr></td>';
hd+=' <td style="vertical-align:bottom;cursor:move;" id="TWin_H3_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/t2.gif" alt="" style="width: 20px; height: 20px; display: block;" border="0px" draggable="false"/></td>';
//hd+=' <td width="100%">&nbsp;</td>';
hd+=' <td style="vertical-align:bottom;cursor:pointer;"><img src="'+this.path+'/metadata/dbms/form/none.gif" alt="" style="width: 21px; height: 21px; display: block;" border="0px" draggable="false"/></td>';
hd+=' <td style="vertical-align:bottom;cursor:pointer;"><img src="'+this.path+'/metadata/dbms/form/none.gif" alt="" style="width: 21px; height: 21px; display: block;" border="0px" draggable="false"/></td>';
hd+=' <td style="vertical-align:bottom;cursor:pointer;"><img src="'+this.path+'/metadata/dbms/form/close.gif" alt="X" style="width: 21px; height: 21px; display: block;" border="0px" draggable="false" id="TWin_CL_'+this.tWinId+'"/></td>';
hd+=' <td style="vertical-align:bottom;"><img src="'+this.path+'/metadata/dbms/form/none.gif" alt="" style="width: 21px; height: 21px; display: block;" border="0px" draggable="false"/></td>';
hd+=' </tr>';
hd+='</table>';
let str='';
str+='<table id="TWin_TBL_'+this.tWinId+'" border="0px" style="width: 100%; height: 100%;">';
str+=' <tr id="TWin_H0_'+this.tWinId+'"><td colspan=3>'+hd+'</td></tr>';
str+=' <tr>';
str+=' <td style="width: 10px; height: 10px; cursor:nw-resize;"><img src="'+this.path+'/metadata/dbms/form/_t-l.gif" alt="" style="width: 10px; height: 10px; display: block;" border="0px" draggable="false" id="TWin_TL_'+this.tWinId+'"></td>';
str+=' <td style="vertical-align:top; height: 10px; cursor:n-resize;" background="'+this.path+'/metadata/dbms/form/t.gif" id="TWin_T_'+this.tWinId+'"></td>';
str+=' <td style="width: 10px; height: 10px; cursor:ne-resize;" id="TWin_TR_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/t-r.gif" alt="" style="width: 10px; height: 10px; display: block;" border="0px" draggable="false"></td>';
str+=' </tr>';
str+=' <tr style="height: 100%">';
str+=' <td style="vertical-align:top;height: 10px; cursor:w-resize;" background="'+this.path+'/metadata/dbms/form/l.gif" id="TWin_L_'+this.tWinId+'"></td>';
str+=' <td style="vertical-align:top;cursor:default;"><table style="width: 100%; height: 100%;"><tr><td id="TWin_Co_'+this.tWinId+'" style="vertical-align:top;">&nbsp;</td></tr></table></td>';
str+=' <td style="vertical-align: top; height: 10px; cursor:e-resize;" background="'+this.path+'/metadata/dbms/form/r.gif" id="TWin_R_'+this.tWinId+'"></td>';
str+=' </tr>';
str+=' <tr>';
str+=' <td style="width: 10px; height: 10px; cursor:sw-resize;" id="TWin_BL_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/b-l.gif" alt="" style="width: 10px; height: 10px; display: block;" border="0px" draggable="false"></td>';
str+=' <td style="vertical-align: top; height: 10px; cursor:s-resize;" background="'+this.path+'/metadata/dbms/form/b.gif" id="TWin_B_'+this.tWinId+'"></td>';
str+=' <td style="width: 10px; height: 10px; cursor:se-resize;" id="TWin_BR_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/b-r.gif" alt="" style="width: 10px; height: 10px; display: block;" border="0px" draggable="false"></td>';
str+=' </tr>';
str+='</table>';
*/
/*
let str='';
str+='<table id="TWin_TBL_'+this.tWinId+'" class="TWin">';
str+=' <tr id="TWin_H0_'+this.tWinId+'" style="border-bottom: 1px solid #b3b3b3;"><td></td><td><table style="width: 100%; height: 29px;"><tr><td id="TWin_Ca_'+this.tWinId+'" style="vertical-align: middle; cursor: move; font-weight: bold; white-space: nowrap;"></td><td style="width: 10px; vertical-align: middle;"><img src="'+this.path+'/metadata/dbms/form/x.gif" id="TWin_CL_'+this.tWinId+'" style="cursor:pointer;"></td></tr></table></td><td></td></tr>';
str+=' <tr>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:nw-resize;' : '')+'" id="TWin_TL_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' <td style="vertical-align: top; height: 5px;'+(!this.dialog ? ' cursor: n-resize;' : '')+'" id="TWin_T_'+this.tWinId+'"></td>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:ne-resize;' : '')+'" id="TWin_TR_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' </tr>';
str+=' <tr style="height: 100%">';
str+=' <td style="height: 5px;'+(!this.dialog ? ' cursor:w-resize;' : '')+'" id="TWin_L_'+this.tWinId+'"></td>';
str+=' <td style="vertical-align:top; cursor: default;"><table style="width: 100%; height: 100%;"><tr><td id="TWin_Co_'+this.tWinId+'" style="vertical-align:top;"></td></tr></table></td>';
str+=' <td style="height: 5px;'+(!this.dialog ? ' cursor:e-resize;' : '')+'" id="TWin_R_'+this.tWinId+'"></td>';
str+=' </tr>';
str+=' <tr>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:sw-resize;' : '')+'" id="TWin_BL_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' <td style="vertical-align:top;height: 5px;'+(!this.dialog ? ' cursor: s-resize;' : '')+'" id="TWin_B_'+this.tWinId+'"></td>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:se-resize;' : '')+'" id="TWin_BR_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' </tr>';
str+='</table>';
*/
let str='';
str+='<table id="TWin_TBL_'+this.tWinId+'" class="DBMSShadow" style="width: 100%; height: 100%; border: 1px solid #000000;">';
str+=' <tr id="TWin_H0_'+this.tWinId+'" style="background: var(--path-grad) repeat-x;"><td></td><td><table style="width: 100%; height: 29px;"><tr><td id="TWin_Ca_'+this.tWinId+'" style="vertical-align: middle; cursor: move; font-weight: bold; white-space: nowrap;"></td><td style="width: 10px; vertical-align: middle;">'+(this.disableClosing ? '' : '<div id="TWin_CL_'+this.tWinId+'" style="display: inline-block; width: 10px; height: 10px; background-image: var(--path-X); background-repeat: no-repeat; cursor:pointer;padding-right: 5px;"></div>')+'</td></tr></table></td><td></td></tr>';
str+=' <tr>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:nw-resize;' : '')+'" id="TWin_TL_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' <td style="vertical-align:top;height: 5px;'+(!this.dialog ? ' cursor:n-resize;' : '')+'" id="TWin_T_'+this.tWinId+'"></td>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:ne-resize;' : '')+'" id="TWin_TR_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' </tr>';
str+=' <tr style="height: 100%">';
str+=' <td style="height: 5px;'+(!this.dialog ? ' cursor:w-resize;' : '')+'" id="TWin_L_'+this.tWinId+'"></td>';
str+=' <td style="vertical-align:top;cursor:default;"><table style="width: 100%; height: 100%;"><tr><td id="TWin_Co_'+this.tWinId+'" style="vertical-align:top;"></td></tr></table></td>';
str+=' <td style="height: 5px;'+(!this.dialog ? ' cursor:e-resize;' : '')+'" id="TWin_R_'+this.tWinId+'"></td>';
str+=' </tr>';
str+=' <tr>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:sw-resize;' : '')+'" id="TWin_BL_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' <td style="vertical-align:top; height: 5px;'+(!this.dialog ? ' cursor:s-resize;' : '')+'" id="TWin_B_'+this.tWinId+'"></td>';
str+=' <td style="width: 5px; height: 5px;'+(!this.dialog ? ' cursor:se-resize;' : '')+'" id="TWin_BR_'+this.tWinId+'"><img src="'+this.path+'/metadata/dbms/form/5.gif" alt="" style="display: block;" border="0px" draggable="false"></td>';
str+=' </tr>';
str+='</table>';
//создаём невидемую тень
this.divsh.style.cssText="display: none; position: fixed; top:0; left:0; height: 100%; width: 100%; background: rgba(0,0,0,0.3);";
this.divsh.onclick=function(win){return function(){ win.Close(); };}(this);
document.body.appendChild( this.divsh );
//Создаём родительский элемент для окна
this.div = document.createElement('div');
this.div.setAttribute("id","TWin_"+this.tWinId);
this.div.style.cssText="position:absolute; height:50px; width:640px;";
this.div.innerHTML=str;
document.body.appendChild( this.div );
this.tbl=document.getElementById('TWin_TBL_'+this.tWinId);
this.h0=document.getElementById('TWin_H0_'+this.tWinId);
this.co=document.getElementById('TWin_Co_'+this.tWinId);
this.ca=document.getElementById('TWin_Ca_'+this.tWinId);
this.setSel();
this.div.onmousedown=(e)=>this.setSel();
//Кнопка закрыть окно
let obj=document.getElementById('TWin_CL_'+this.tWinId);
if(obj!=null){
//obj.onclick=function(win){return function(){ win.Close(); };}(this);
obj.onclick=(function(){ this.Close(); }).bind(this);
}
if(!this.dialog)
{
document.getElementById('TWin_B_'+this.tWinId).onmousedown=this.onResize(0,1);
document.getElementById('TWin_T_'+this.tWinId).onmousedown=this.onResize(0,-1);
document.getElementById('TWin_BR_'+this.tWinId).onmousedown=this.onResize(1,1);
document.getElementById('TWin_TL_'+this.tWinId).onmousedown=this.onResize(-1,-1);
document.getElementById('TWin_BL_'+this.tWinId).onmousedown=this.onResize(-1,1);
document.getElementById('TWin_R_'+this.tWinId).onmousedown=this.onResize(1,0);
document.getElementById('TWin_L_'+this.tWinId).onmousedown=this.onResize(-1,0);
document.getElementById('TWin_TR_'+this.tWinId).onmousedown=this.onResize(1,-1);
}
this.setMove(document.getElementById('TWin_H0_'+this.tWinId));
//this.setMove(document.getElementById('TWin_H1_'+this.tWinId));
//this.setMove(document.getElementById('TWin_H2_'+this.tWinId));
//this.setMove(document.getElementById('TWin_H3_'+this.tWinId));
this.setLeftTop(x,y);
}
getCaption()
{
return document.getElementById('TWin_Ca_'+this.tWinId);
}
setCaption(val)
{
if(val==null) val='';
let obj=document.getElementById('TWin_Ca_'+this.tWinId);
if (typeof val === 'string' || val instanceof String)
obj.innerHTML=val;
else
obj.appendChild(val);
}
//Присвоить содержимое в виде строки
setContent(html)
{
let obj=document.getElementById('TWin_Co_'+this.tWinId);
if(obj!=null)
{
obj.innerHTML=html;
if(this.tbl.offsetHeight>this.div.offsetHeight) this.div.style.height=this.tbl.offsetHeight+"px";
if(this.tbl.offsetWidth>this.div.offsetWidth) this.div.style.width=this.tbl.offsetWidth+"px";
}
}
//Выбрать (активизировать) окно
setSel()
{
for(let i=0;i<g_wins.mas.length;i++) if(g_wins.mas[i]!=null)
{
g_wins.mas[i].sel=false;
g_wins.mas[i].ca.style.color="var(--inactive-font-color)";
}
this.sel=true;
this.ca.style.color="var(--main-font-color)";
this.setWinZ(true);
}
//Получить значение Z индекса TODO сделать через геттер
getZ()
{
return parseInt(this.div.style.zIndex);
}
//Установить значение Z индекса TODO сделать через setter
setZ(z)
{
this.div.style.zIndex=z;
this.divsh.style.zIndex=z-1;
};
setMove(elm)
{
elm.onmousedown=function(win){
return function(event){
move_me(event,win);
};
}(this);
};
//В центр видимой части экрана
setCenter()
{
let scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
this.div.style.left=(scrollLeft+((document.documentElement.clientWidth || document.body.clientWidth)-parseInt(this.div.style.width))/2)+"px"
this.div.style.top=(scrollTop+((document.documentElement.clientHeight || document.body.clientHeight)-parseInt(this.div.style.height))/2)+"px"
if(parseInt(this.div.style.top)<0) this.div.style.top="1px";
if(parseInt(this.div.style.left)<0) this.div.style.left="1px";
};
setLeftTop(x,y)
{
this.div.style.left=x+"px"
if(y<0) y=0;this.div.style.top=y+"px"
};
setTop(y){if(y<0) y=0;this.div.style.top=y+"px"};
getTop(){return parseInt(this.div.style.top)};
getLeft(){return parseInt(this.div.style.left)};
setSize(w,h)
{
this.setWidth(w)
this.setHeight(h)
};
//Где w вида '100px' или '100%'
setWidth(w)
{ if(w==null || w=='') return;
w=''+w;
if(w.indexOf('px')<0 && w.indexOf('%')<0) w+='px'; //По умолчанию пиксели
this.div.style.width=w
if(this.tbl.offsetWidth>this.div.offsetWidth) this.div.style.width=this.tbl.offsetWidth+"px"
};
getWidth(){
if(this.tbl!=null)
return parseInt(this.tbl.offsetWidth);
else
return 0;
};
setHeight(h)
{
if(h==null || h=='') return;
h=''+h;
if(h.indexOf('%')>-1) h=(this.div.parentNode.offsetHeight/100*parseInt(h));
this.co.style.height=(parseInt(h)-20-this.h0.offsetHeight)+"px";
this.div.style.height=parseInt(h)+'px';
if(this.tbl.offsetHeight>this.div.offsetHeight)
this.div.style.height=this.tbl.offsetHeight+"px";
};
//Подстроить размер окна по содержимому
/*adjustHeight()
{
}*/
//Подгрузить содержимое окна из указаного места
//json - объект который передастца в виде JSON строки по URL
//func - функция которая выполниться после загрузки данных в форму
load(url,json,func,tr)
{
this.showProgressBar();
var r=createRequestObject();
r.onreadystatechange = function(r,w,thiz,func)
{
return function(){
if(r.readyState == 4){
if(tr) w.innerHTML=trts(r.responseText);
else w.innerHTML=r.responseText;
thiz.hideProgressBar();
if(func !== undefined && func!=null) func();
//Для подстройки формы под новый размер, а то showProgressBar не по размеру было
thiz.div.style.width=thiz.tbl.offsetWidth+"px"
thiz.div.style.height=thiz.tbl.offsetHeight+"px";
thiz.setCenter();
}
}
}(r,this.co,this,func,tr)
r.open( "POST", url, true );
if(json!=null)
r.send(JSON.stringify(json));
else
r.send();
};
//Переместить окно на передний план (Обычно при щелчке на нём)
setWinZ(s)
{
let i;
this.setZ(g_wins.getMaxZ()+2); //+2 это для тени
if(s && this.parent!=null) //Переносим текущий элемент в 0й элемент массива детей родительского
{
var tmp=this.parent.childs[0];
for(i=1;i<this.parent.childs.length;i++)
{
if(tmp==this) break;
let t=this.parent.childs[i];
this.parent.childs[i]=tmp;
tmp=t;
}
this.parent.childs[0]=tmp;
}
for(i=this.childs.length;i>0;i--) if(this.childs[i-1]!=null) this.childs[i-1].setWinZ(false) //Забыл зачем это делаю
}
setParent(w)
{
if(this.parent!=null)
{
for(let i=0;i<this.parent.childs.length;i++) if(this.parent.childs[i]==this) this.parent.childs[i]=null;
}
if(typeof w !== 'undefined' && w!=null)
{
this.parent=w;
w.childs[w.childs.length]=this;
}
}
hide(val)
{
if(val)
{ this.div.style.display='none';
this.divsh.style.display='none';
}else
{
this.div.style.display='inline';
if(this.shadow) this.divsh.style.display='block';
}
}
//Показать прогрес бар
showProgressBar()
{
this.pBarCnt++;
if(this.pBarDiv==null)
{
var img='loading.gif';
if(this.getWidth()<230) img='loading3.gif';
this.pBarDiv=document.createElement('div');
this.pBarDiv.style.cssText='position: absolute; left: 0px; top: 0px; z-index: 1; width:100%; height: 100%; margin-top:30px; padding-bottom:30px;';
this.pBarDiv.innerHTML='<table style="background-color: rgba(0,0,0,0.5);" width="100%" height="100%" cellpadding="0" cellspacing="0"><tr><td align="center" style="vertical-align: middle;"><img src="'+this.path+'/metadata/dbms/images/'+img+'" alt=""></td></tr></table>';
//var eDiv=document.getElementById('eDiv'+this.uid);
this.div.appendChild(this.pBarDiv);
}
}
//Спрятать прогрес бар
hideProgressBar()
{
this.pBarCnt--;
if(this.pBarCnt<=0)
{
if(this.pBarDiv!==null) deleteHTML(this.pBarDiv);
this.pBarCnt=0;
this.pBarDiv=null;
}
}
}
class TWins
{
constructor()
{
this.mas = new Array();
}
add(win) //Добавить окно в список
{
this.mas.push(win);
return this.mas.length-1;
};
getMaxZ() //Получить максимальный Z индекс
{
var z=100; //По умолчанию
for(var i=0;i<this.mas.length;i++) if(this.mas[i]!==null && this.mas[i].getZ()>z) z=this.mas[i].getZ();
return z;
};
getSel() //Получить выделенное окно
{
for(var i=0;i<this.mas.length;i++) if(this.mas[i].sel) return this.mas[i];
return null;
};
}
var g_wins=new TWins(); //Global object

148
metadata/dbms/xmltojson.js Normal file
View File

@ -0,0 +1,148 @@
class xmltojson {
constructor(xml) {
let parser = new DOMParser();
let xmlDoc = parser.parseFromString(xml, "text/xml");
this.xType = xmlDoc.documentElement;
this.jType = {};
this.setType(this.xType, this.jType);
}
toString(){
return JSON.stringify(this.jType);
}
setType(xType, jType) {
jType.n = xType.getAttribute("n");
jType.d = xType.getAttribute("d");
jType.ObjectID = xType.getAttribute("ObjectID");
let nodeProperties = findNodeOnPath(xType, 'properties');
if (nodeProperties != null) {
jType.edit_object = {};
jType.edit_object.width = nodeProperties.getAttribute("width");
jType.edit_object.columns = [];
let nodeProp = nodeProperties.firstChild;
while (nodeProp != null) {
if (nodeProp.nodeName == "prop") {
let jProp = {};
let column = this.setProp(nodeProp, jProp);
jType.edit_object.columns.push(column);
}
nodeProp = nodeProp.nextSibling;
}
let node;
node = findFirstNodeOnAttribute(nodeProperties, 'sql-query', 't', 'i');
if (node != null)
jType.edit_object.insert_query = getCdataValue(node);
node = findFirstNodeOnAttribute(nodeProperties, 'sql-query', 't', 'u');
if (node != null)
jType.edit_object.update_query = getCdataValue(node);
node = findFirstNodeOnAttribute(nodeProperties, 'sql-query', 't', 'd');
if (node != null)
jType.edit_object.delete_query = getCdataValue(node);
node = findFirstNodeOnAttribute(nodeProperties, 'sql-query', 't', 's');
if (node != null)
jType.edit_object.select_query = getCdataValue(node);
}
let nodeObjectsList = findNodeOnPath(xType, 'objects-list');
if (nodeObjectsList != null) {
jType.show_object = {};
jType.show_object.width = nodeObjectsList.getAttribute("width");
jType.show_object.d = nodeObjectsList.getAttribute("d");
let node;
node = findFirstNode(nodeObjectsList, 'sql-query');
if (node != null)
jType.show_object.select_query = getCdataValue(node);
let nFilter = findFirstNode(nodeObjectsList, 'filter');
if (nFilter != null) {
jType.show_object.filter = {};
if (nFilter.hasAttribute("height"))
jType.show_object.filter.height = nFilter.getAttribute("height");
jType.show_object.filter.columns = [];
let nextNode = nFilter.firstChild;
while (nextNode != null) {
if (nextNode.nodeName == "column") {
let jColumn = {};
let column = this.setFilterColumn(nextNode, jColumn);
jType.show_object.filter.columns.push(column);
}
nextNode = nextNode.nextSibling;
}
}
//jType.show_object.columns = [];
}
//this.win.setWidth(nodeProperties.getAttribute("width"));
}
//Переписываю колонки редактирования
setProp(xProp, jProp) {
if (xProp.hasAttribute("d"))
jProp.d = xProp.getAttribute("d");
if (xProp.hasAttribute("n"))
jProp.n = xProp.getAttribute("n");
if (xProp.hasAttribute("vt"))
jProp.vt = xProp.getAttribute("vt");
if (xProp.hasAttribute("maybenull"))
jProp.maybenull = xProp.getAttribute("maybenull");
if (xProp.hasAttribute("ot"))
jProp.ot = xProp.getAttribute("ot");
if (xProp.hasAttribute("FieldCaption"))
jProp.FieldCaption = xProp.getAttribute("FieldCaption");
if (xProp.hasAttribute("selector"))
jProp.selector = xProp.getAttribute("selector");
jProp.value = getCdataValue(xProp);
/*
if (nodeFilter.getAttribute("n")==nodeProp.getAttribute("n"))
{
let cdata1=findFirstNode(nodeFilter,'#cdata-section');
if((cdata1!=null)&&(cdata1.nodeValue!=""))
{
let cdata2=findFirstNode(nodeProp,'#cdata-section');
if (cdata2==null)
{
cdata2 = nodeProp.ownerDocument.createCDATASection("");
nodeProp.appendChild(cdata2);
}
cdata2.nodeValue=cdata1.nodeValue;
}
}
* */
return jProp;
}
//Переписать из "type->objects-list->filter"
setFilterColumn(xColumn, jColumn) {
if (xColumn.hasAttribute("d"))
jColumn.d = xColumn.getAttribute("d");
if (xColumn.hasAttribute("n"))
jColumn.n = xColumn.getAttribute("n");
if (xColumn.hasAttribute("vt"))
jColumn.vt = xColumn.getAttribute("vt");
if (xColumn.hasAttribute("object"))
jColumn.object = xColumn.getAttribute("object");
if (xColumn.hasAttribute("FieldCaption"))
jColumn.FieldCaption = xColumn.getAttribute("FieldCaption");
if (xColumn.hasAttribute("selector"))
jColumn.selector = xColumn.getAttribute("selector");
if (xColumn.hasAttribute("visible"))
jColumn.visible = xColumn.getAttribute("visible");
jColumn.value = getCdataValue(xColumn);
return jColumn;
}
}

View File

@ -0,0 +1,68 @@
<?php
@session_start(['cookie_lifetime' => 43200,'cookie_secure' => true,'cookie_httponly' => true]);
//if(isset($_SESSION['REMOTE_ADDR']) && $_SESSION['REMOTE_ADDR'] != $_SERVER['REMOTE_ADDR']) unset($_SESSION["USER_ID"]); //Делаемся не авторизованным если зашли с другого ip адреса
if (isset($_REQUEST['id'])) $id = $_REQUEST['id']; else $id = '';
$width = 115; //Ширина изображения
$height = 40; //Высота изображения
$font_size = 14; //Размер шрифта
$let_amount = 5; //Количество символов, которые нужно набрать
$fon_let_amount = 40; //Количество символов, которые находятся на фоне
$path_fonts = getcwd().'/fonts/'; //Путь к шрифтам
//$letters = array('a','b','c','d','e','f','g','h','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z','2','3','4','5','6','7','9');
$letters = array('0','1','2','3','4','5','6','7','8','9');
//$colors = array('100','200','150','170','190','210','190','160','170','190','210'); //для тёмного стиля
$colors = array('50','100','75','85','95','105','90','80','85','95','105'); //Для светлого стиля
$src = imagecreatetruecolor($width,$height);
//$fon = imagecolorallocate($src,58,58,58); //Для тёмного стиля
$fon = imagecolorallocate($src,241,241,241); //Для светлого стиля
imagefill($src,0,0,$fon);
$fonts = array();
$dir=opendir($path_fonts);
while($fontName = readdir($dir))
{
if($fontName != "." && $fontName != ".." && pathinfo($fontName, PATHINFO_EXTENSION)=='ttf')
{
$fonts[] = $fontName;
}
}
closedir($dir);
for($i=0;$i<$fon_let_amount;$i++)
{
$color = imagecolorallocatealpha($src,rand(0,255),rand(0,255),rand(0,255),100);
$font = $path_fonts.$fonts[rand(0,sizeof($fonts)-1)];
$letter = $letters[rand(0,sizeof($letters)-1)];
$size = rand($font_size-2,$font_size+2);
imagettftext(
$src,
$size,
rand(0,45),
rand((int)($width*0.1),(int)($width-$width*0.1)),
rand((int)($height*0.2),$height),
$color,
$font,
$letter
);
}
for($i=0;$i<$let_amount;$i++)
{
$color = imagecolorallocatealpha($src,$colors[rand(0,sizeof($colors)-1)],$colors[rand(0,sizeof($colors)-1)],$colors[rand(0,sizeof($colors)-1)],rand(20,40));
$font = $path_fonts.$fonts[rand(0,sizeof($fonts)-1)];
$letter = $letters[rand(0,sizeof($letters)-1)];
$size = rand((int)($font_size*2.1-2),(int)($font_size*2.1+2));
$x = (int)(($i+0.9)*$font_size + rand(4,7));
$y = (int)((($height*2.3)/3) + rand(0,5));
$cod[] = $letter;
imagettftext($src,$size,rand(0,15),$x,$y,$color,$font,$letter);
}
$_SESSION['secpic'.$id] = implode('',$cod);
header ("Content-type: image/gif");
imagegif($src);

View File

@ -0,0 +1,25 @@
<?php
//Для одностраничного приложения с AJAX запросами для определения времени жизни сесии
//$prolong==true для продления виртуальной сессии
function startSession($prolong=true)
{
$sessionLifetime = 3600; //В секундах (время жизни должно быть меньше чем session.gc_maxlifetime там значение по умолчанию: 1440/60=24 минутs (60*60=3600 то это час))
if (!@session_start()){
return false;
}
$t = time();
if(!isset($_SESSION['lastactivity']) || $prolong){
$_SESSION['lastactivity']=$t;
}
if ( $t-$_SESSION['lastactivity'] >= $sessionLifetime )
{
$t=$_SESSION['lastactivity'];
//session_unset(); Удалить все переменные сессии (устарела)
//$_SESSION = array();
session_reset(); // Удалить все переменные сессии
$_SESSION['lastactivity']=$t;
return false;
}
return true;
}

514
metadata/include/tools.xyz Normal file
View File

@ -0,0 +1,514 @@
<?php
// Из файла file.js делаем file_v123456789.js добавив время
function getScript($path)
{
if (file_exists($_SERVER['DOCUMENT_ROOT'].$path))
{
return '<script src="'.beforeLast($path,'.').'_v'.filectime($_SERVER['DOCUMENT_ROOT'].$path).'.'.afterLast($path,'.').'"></script>'."\n";
}
return '';
}
//Функция для перевода текста без применения GetText "trt("
function trt($text)
{
global $db,$Schema,$language_id;
$result='';
$sql='select translation from '.$Schema.'_translations where del=false and language_id='.$language_id.' and identifier=\''.$text.'\';';
//$sql='select translation from main._translations where del=false and language_id=(select id from main._languages where short_name=\''.$language_id.'\') and identifier=\''.$text.'\';';
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$result=$row[0];
}
}else
{
$result=str_replace("_", " ", $text);
}
return $result;
}
//Перевод для строки в которой встречаются подстроки вида: trt('')
function trts($text)
{
$result='';
$pLen=4; //Длина преамбулы trt(
$cut=0;
$from = 0; // Позиция поиска для итерации
while (true)
{
$pos1 = strpos($text, 'trt(', $from); //')
if($pos1 !== false)
{
$from = $pos1+$pLen+1;
$pos2 = false;
if($text[$pos1+$pLen] == '"') $pos2 = strpos($text, '")', $from);
if($text[$pos1+$pLen] == '\'') $pos2 = strpos($text, '\')', $from);
if($pos2 !== false)
{
$result.=substr($text, $cut, $pos1 - $cut );
$toTranslate=substr($text, $pos1+$pLen+1, $pos2 - $pos1 - $pLen-1 );
$result.=trt($toTranslate);
$cut=$pos2+2;
$from = $pos2;
}
}else break;
}
$result.=substr($text, $cut); //Копируем остатки
return $result;
}
//Выбираю из текста ${конкретные} слова для перевода
function trs($text)
{
if(!$text) return '';
$pos1=0;
while(true)
{
$pos1 = strpos($text, '${',$pos1);
if($pos1 !== false)
{
$pos2 = strpos($text, '}', $pos1);
if($pos1 !== false)
{
$sub=substr($text,$pos1+2,$pos2-$pos1-2);
$text=substr($text,0, $pos1).trt($sub).substr($text,$pos2+1);
}else
{
break;
}
}else
{
break;
}
}
return $text;
}
//Получить разрешения для текущего пользователя
function getAccess($key)
{
global $db;
$result=false;
$sql="select main.p_getaccess(:user_id,:key) as acc;";
$stmt = $db->prepare($sql);
if(isset($_SESSION['USER_ID']))
$stmt->bindValue(':user_id', $_SESSION['USER_ID'], PDO::PARAM_INT);
else
$stmt->bindValue(':user_id', 0, PDO::PARAM_INT);
$stmt->bindValue(':key', $key, PDO::PARAM_STR);
$res=null;
try
{
$res=$stmt->execute();
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res && $stmt->rowCount()>0)
{
while ($row = $stmt->fetch(PDO::FETCH_NUM))
{
$result=$row[0];
}
}
return $result;
}
function delPHPExt($fName)
{
$pos = strrpos($fName, '.')+1;
if(strtolower(substr($fName,$pos))=='php')
{
return substr($fName,0,$pos).'VIRUS';
}else {
return $fName;
}
}
function getURLText($url,$data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, trim($url));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_HEADER,0); //Change this to a 1 to return headers
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.12) Gecko/20050919 Firefox/1.0.7');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = trim(curl_exec($ch));
curl_close($ch);
return $data;
}
// array imageResize (string $src, string $dest, integer $width, integer $height);
// $src - имя исходного файла
// $dest - имя генерируемого файла
// $width, $height - максимальные ширина и высота генерируемого изображения
// возвращает массив (0=>$width, 1=>$height) с шириной и высотой получившегося изображения
function imageResize ($src, $dest, $width, $height)
{
if (!file_exists($src)) return false;
if (($size=getimagesize($src))===false) return false;
$format=strtolower(substr($size['mime'],strpos($size['mime'],'/')+1));
$icfunc='imagecreatefrom'.$format;
if (!function_exists($icfunc)) return false;
$x_ratio=$width/$size[0];
$y_ratio=$height/$size[1];
$ratio=min($x_ratio, $y_ratio);
$use_x_ratio=($x_ratio==$ratio);
$new_width=$use_x_ratio?$width:floor($size[0]*$ratio);
$new_height=!$use_x_ratio?$height:floor($size[1]*$ratio);
$new_left=$use_x_ratio?0:floor(($width-$new_width)/2);
$new_top=!$use_x_ratio?0:floor(($height-$new_height)/2);
$isrc=$icfunc($src);
$idest=imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($idest, $isrc, 0, 0, 0, 0, $new_width, $new_height, $size[0], $size[1]);
//Пишем в файл
if ($format=='jpeg') imagejpeg($idest, $dest, 70);
else if ($format=='gif') imagegif($idest, $dest);
else imagepng($idest, $dest, 7);
imagedestroy($isrc);
imagedestroy($idest);
return array($new_width, $new_height);
}
//Залить недостающие края заданным цветом (использую для фото без прозрачности для удобства в HTML верстке)
function imageFillBorder($src, $dest, $width, $height){
if (!file_exists($src)) return false;
if (($size=getimagesize($src))===false) return false;
$format=strtolower(substr($size['mime'],strpos($size['mime'],'/')+1));
// создание jpg изображения
if ($format=='jpeg')
{
if(!$oldImg = imagecreatefromjpeg($src))
{
error_log('Error imagecreatefromjpeg '.$_SERVER['REQUEST_URI']);
}
}else if ($format=='gif') $oldImg = imagecreatefromgif($src);
else $oldImg = imagecreatefrompng($src);
//Создаю новое изображение
$newImg=imagecreatetruecolor($width, $height);
$background_color = imagecolorallocate($newImg, 255, 255, 255);
imagefill($newImg, 0, 0, $background_color);
//Ищем центр
$x = ($width - imagesx($oldImg)) / 2;
$y = ($height - imagesy($oldImg)) / 2;
imagecopy($newImg, $oldImg, $x, $y, 0, 0, imagesx($oldImg), imagesy($oldImg));
//Пишем в файл
if ($format=='jpeg') imagejpeg($newImg,$dest);
else if ($format=='gif') imagegif($newImg,$dest);
else imagepng($newImg,$dest);
// освобождаем память
imagedestroy($oldImg);
imagedestroy($newImg);
}
//Водяной знак (размножит по поверхности одного изображения другое)
function watermark($src,$stm)
{
if (!file_exists($src) || !file_exists($stm)) return false;
if (($size=getimagesize($src))===false) return false;
$format=strtolower(substr($size['mime'],strpos($size['mime'],'/')+1));
// создание водяного знака в формате png
$watermark = imagecreatefrompng($stm);
// получаем ширину и высоту
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
// создание jpg изображения
if ($format=='jpeg')
{
if(!$image = imagecreatefromjpeg($src))
{
error_log('Error imagecreatefromjpeg '.$_SERVER['REQUEST_URI']);
}
}else if ($format=='gif') $image = imagecreatefromgif($src);
else $image = imagecreatefrompng($src);
//Выясняем количество повторов по оси X и по Y
$dx=ceil($size[0] / $watermark_width);
$dy=ceil($size[1] / $watermark_height);
imagealphablending($image, true);
imagealphablending($watermark, true);
// создаём новое изображение
for($y=0;$y<$dy;$y++)
for($x=0;$x<$dx;$x++)
imagecopy($image, $watermark, $x * $watermark_width, $y * $watermark_height, 0, 0, $watermark_width, $watermark_height);
//Пишем в файл
if ($format=='jpeg') imagejpeg($image,$src);
else if ($format=='gif') imagegif($image,$src);
else imagepng($image,$src);
// освобождаем память
imagedestroy($image);
imagedestroy($watermark);
}
//вернёт только цифры
function getInt($str)
{
$res='';
for($i=0;$i<strlen($str);$i++)
{
if($str[$i]=='-'||$str[$i]=='0'||$str[$i]=='1'||$str[$i]=='2'||$str[$i]=='3'||$str[$i]=='4'||$str[$i]=='5'||$str[$i]=='6'||$str[$i]=='7'||$str[$i]=='8'||$str[$i]=='9')
$res.=$str[$i];
}
return $res;
}
//вернёт только цифры
function getUInt($str)
{
$res='';
for($i=0;$i<strlen($str);$i++)
{
if($str[$i]=='0'||$str[$i]=='1'||$str[$i]=='2'||$str[$i]=='3'||$str[$i]=='4'||$str[$i]=='5'||$str[$i]=='6'||$str[$i]=='7'||$str[$i]=='8'||$str[$i]=='9')
$res.=$str[$i];
}
return $res;
}
//вернёт только цифры
function getPhoneNum($str)
{
$res='';
for($i=0;$i<strlen($str);$i++)
{
if($str[$i]=='+'||$str[$i]=='0'||$str[$i]=='1'||$str[$i]=='2'||$str[$i]=='3'||$str[$i]=='4'||$str[$i]=='5'||$str[$i]=='6'||$str[$i]=='7'||$str[$i]=='8'||$str[$i]=='9')
$res.=$str[$i];
}
return $res;
}
function translit($str)
{
$rus = array('А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я', 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я');
$lat = array('A', 'B', 'V', 'G', 'D', 'E', 'E', 'Gh', 'Z', 'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F', 'H', 'C', 'Ch', 'Sh', 'Sch', 'Y', 'Y', 'Y', 'E', 'Yu', 'Ya', 'a', 'b', 'v', 'g', 'd', 'e', 'e', 'gh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sh', 'sch', 'y', 'y', 'y', 'e', 'yu', 'ya');
return str_replace($rus, $lat, $str);
}
//Расширение файла транслитерованное в строчных буквах
function getExtension($fileName)
{
return strtolower(translit(substr($fileName, strrpos($fileName, '.') + 1)));
}
//Проверка емайла на валидность
function is_email($email)
{
if (function_exists("filter_var"))
{
$s=filter_var($email, FILTER_VALIDATE_EMAIL);
return !empty($s);
}
$p = '/^[a-z0-9!#$%&*+-=?^_`{|}~]+(\.[a-z0-9!#$%&*+-=?^_`{|}~]+)*';
$p.= '@([-a-z0-9]+\.)+([a-z]{2,3}';
$p.= '|info|arpa|aero|coop|name|museum|mobi)$/ix';
return preg_match($p, $email);
}
function deleteTempFiles($dir)
{
$time_sec=time(); // текущее время
if (is_dir($dir))
{
$dh = opendir($dir);
if ($dh)
{
while (($file = readdir($dh)) !== false)
{
if($file == '..' || $file == '.') continue;
$time_file=filemtime($dir.$file); // время изменения файла
$time=$time_sec-$time_file; // тепрь узнаем сколько прошло времени (в секундах)
if($time>24*60*60) unlink($dir.$file);
}
closedir($dh);
}
}
}
function getFilesTree($dir,$cut="",$result = null){
if($result==null)
$result = new stdClass();
if (is_dir($dir))
{
$result->list = array();
$dh = opendir($dir);
if ($dh)
{
while (($file = readdir($dh)) !== false)
{
if($file == '..' || $file == '.') continue;
if(is_dir($dir.DIRECTORY_SEPARATOR.$file)){
$sub = new stdClass();
$sub->name=$file;
$sub->path=$dir.DIRECTORY_SEPARATOR.$file;
if($cut) $sub->path = str_replace($cut, "",$sub->path);
array_push($result->list, $sub);
getFilesTree($dir.DIRECTORY_SEPARATOR.$file, $cut, $sub);
}else{
$sub = new stdClass();
$sub->name=$file;
$sub->path=$dir.DIRECTORY_SEPARATOR.$file;
if($cut) $sub->path = str_replace($cut, "",$sub->path);
array_push($result->list, $sub);
}
}
closedir($dh);
}
}
return $result;
}
//Генерация пароля
function getPassword($max)
{
$chars="qazxswedcvfrtgbnhyujmkiolp1234567890";
$size=StrLen($chars)-1;
$password='';
while($max--)
$password.=$chars[rand(0,$size)];
return $password;
}
//Полный путь к текущему URL включая http и название скрипта
function selfURL()
{
if(!isset($_SERVER['REQUEST_URI'])){ $suri = $_SERVER['PHP_SELF']; }
else { $suri = $_SERVER['REQUEST_URI']; }
$s = empty($_SERVER["HTTPS"]) ? '' : (($_SERVER["HTTPS"] == "on") ? "s" : "");
$sp=strtolower($_SERVER["SERVER_PROTOCOL"]);
$pr = substr($sp,0,strpos($sp,"/")).$s;
$pt = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
return $pr."://".$_SERVER['SERVER_NAME'].$pt.$suri;
}
//Путь без файла пример: http://truemisha.ru
function selfDomain()
{
//if(!isset($_SERVER['REQUEST_URI'])) $suri = $_SERVER['PHP_SELF'];
//else $suri = $_SERVER['REQUEST_URI'];
$s = empty($_SERVER["HTTPS"]) ? '' : (($_SERVER["HTTPS"] == "on") ? "s" : "");
$sp=strtolower($_SERVER["SERVER_PROTOCOL"]);
$pr = substr($sp,0,strpos($sp,"/")).$s;
$pt = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
return $pr."://".$_SERVER['SERVER_NAME'].$pt;//.$suri;
}
//Строка до последнего найденого символа если символа нет то всю строку
function beforeLast(&$str,$ch)
{
return substr($str, 0, strrpos($str, $ch));
}
//Строка после последнего найденого символа если символа нет то всю строку
function afterLast(&$str,$ch)
{
return substr($str, strrpos($str, $ch)+strlen($ch));
}
//Строка до первого попавшегося символа
function beforeFirst(&$str,$ch)
{
return substr($str, 0, strpos($str, $ch));
}
//Строка после первого попавшегося символа
function afterFirst(&$str,$ch)
{
return substr($str, strpos($str, $ch)+strlen($ch));
}
/**
* Вернёт подстроку если символа нет то всю строку
* @param string $str
* @param string $chr
* @return string Подстрока
*/
function cutStr(&$str,$chr)
{
$pos = strpos($str, $chr);
if($pos===false)
{
return $str;
}else
{
$buf = substr($str, 0, $pos);
$str = substr($str, $pos + strlen($chr));
return $buf;
}
}
//Вырезаеи всё после заданого разделителя удаляя разделитель если разделителя нет возвращает всю строку
//$fstr - Разделитель
//$num - На каком разделителе остановиться
function cutAfterLast(&$sstr,$fstr,$num = 1)
{
$sub='';
$pos=strlen($sstr);
for($i=0;$i<$num;$i++)
{
$pos = strripos($sstr, $fstr, $pos-strlen($sstr)-1);
if($pos === false) { break; }
}
if($pos === false)
{
$sub=$sstr;
$sstr='';
return $sub;
}else
{
$sub = substr( $sstr , $pos + strlen($fstr));
$sstr = substr( $sstr , 0, $pos);
return $sub;
}
}
//Зачем коментил?
//Отрезаем от строки всё до заданой подстроки если подстроки нет отрезается вся строка
function cutBeforeFirst(&$sstr,$fstr)
{
$sub='';
$pos = strpos($sstr, $fstr);
if($pos === false)
{
$sub=$sstr;
$sstr='';
return $sub;
}else
{
$sub = substr( $sstr , 0, $pos);
$sstr = substr( $sstr , $pos + strlen($fstr));
return $sub;
}
}

View File

@ -0,0 +1,172 @@
<?php
/**
* Вернуть строку по DOMNode
* @param DOMNode $node Узел XML
* @return string
*/
function getXML($node)
{
if($node==null) return '';
return $node->ownerDocument->saveXML($node);
}
/**
* Найти первый попавшийся узел с заданным именем nodeName.
* @param DOMNode $node Узел.
* @param string $nodename Название узла.
* @return DOMNode Найденный узел либо null.
*/
function findNode($node, $nodename)
{
if($node==null) return null;
$nextNode = $node->firstChild;
while ($nextNode != null)
{
if($nextNode->nodeName==$nodename)
{
return $nextNode;
}
$nextNode=$nextNode->nextSibling;
}
return null;
}
/**
* Найти первый попавшийся узел с заданным именем nodeName и атрибутом $attribute со значением $val.
* @param <type> $node
* @param <type> $nodename
* @param <type> $attribute
* @param <type> $val
* @return <type>
*/
function findNodeOnAttribute($node, $nodename,$attribute,$val)
{
if($node==null) return null;
$nextNode = $node->firstChild;
while ($nextNode != null)
{
if(($nextNode->nodeName==$nodename)&&($nextNode->getAttribute($attribute)==$val))
{
return $nextNode;
}
$nextNode=$nextNode->nextSibling;
}
return null;
}
/**
* Вернуть первый попавшийся узел среди всех дочерних (без рекурсии).
* @param XMLNode $node Родительский узел.
* @param String $nodename Название узла.
* @return XMLNode Найденный узел
*/
function findFirstNode($node, $nodename)
{
$mas=array();
$pos=0;
$mas[$pos] = $node->firstChild;
while ($mas[$pos])
{
if($mas[$pos]->nodeName==$nodename)
{
return $mas[$pos];
}
if($mas[$pos]->firstChild)
{
$pos++;
$mas[$pos]=$mas[$pos-1]->firstChild;
}else
{
//если не идёт дальше пытаемся подняться в верх по дереву
while (true)
{
$mas[$pos] = $mas[$pos]->nextSibling;
if (!$mas[$pos])
{
if($pos>0){ $pos--; }else{ break; }
}else
{
break;
}
}
}
}
return '';
}
//рекурсию не буду использовать, обойдусь массивом вложенности
function findFirstNodeOnAttribute($node, $nodename,$attribute,$val)
{
$mas=array();
$pos=0;
$mas[$pos] = $node->firstChild;
while ($mas[$pos])
{
if(($mas[$pos]->nodeName==$nodename)&&($mas[$pos]->getAttribute($attribute)==$val))
{
return $mas[$pos];
}
if($mas[$pos]->firstChild)
{
$pos++;
$mas[$pos]=$mas[$pos-1]->firstChild;
}else
{
//если не идёт дальше пытаемся подняться в верх по дереву
while (true)
{
$mas[$pos] = $mas[$pos]->nextSibling;
if (!$mas[$pos])
{
if($pos>0){ $pos--; }else{ break; }
}else
{
break;
}
}
}
}
return '';
}
//найти узелы по пути "node1->node2"
function findNodeOnPath($node, $path)
{
if($node==null) return null;
$params=explode("/",$path);
for($i=0;$i<count($params);$i++)
{
if($node==null) return null;
$node=findNode($node,$params[$i]);
}
return $node;
}
/**
* Вернёт первую CDATA секцию если её нет то создаст.
* @param DOMNode $node Узел XML.
* @return DOMCdataSection Узел CDATA либо null.
*/
function getCdata($node)
{
if($node==null) return null;
$result=findNode($node,'#cdata-section');
if($result==null)
{
$result=$node->ownerDocument->createCDATASection('');
$node->appendChild($result);
}
return $result;
}
/**
* Получить строку данных из первой попавшейся CDATA.
* @param DOMNode $node Узел XML.
* @return String Строка результата
*/
function getCdataValue($node)
{
$n=findNode($node,'#cdata-section');
if($n!=null)
{ return $n->nodeValue;
}
return '';
}

220
metadata/test.xyz Normal file
View File

@ -0,0 +1,220 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Пример POST-запроса</title>
<script src="./vue.js"></script>
<link rel="stylesheet" type="text/css" href="../metadata/dbms/dbms.css"/>
</head>
<body>
<table class="SEdit" id="app0" border="0px" cellspacing="1" cellpadding="1" style="width: 100%; height: 100%;">
<caption><b id="caption'+this.uid+'"></b></caption>
<thead>
<tr bgcolor="#dadada">
<th style="width:20%">trt('Name')</th>
<th style="width:80%">trt('Value')</th>
</tr>
</thead>
<tbody>
<tr bgcolor="#dadada">
<td style="width:20%">trt('Name')</td>
<td style="width:80%">trt('Value')</td>
</tr>
</tbody>
</table>
<div id="app" style="border: 2px solid;">
<h1>{{ type.d }}</h1>
<div v-for="(column,index) in type.edit_object.columns">
<div v-if="column.vt=='i4'" :style="{ backgroundColor: index % 2 === 0 ? 'var(--row-color-1)' : 'var(--row-color-2)' }">
<div style="width:150px;display:inline-block;">{{column.d}}</div>
<input type="text" v-model="column.value">
<input type="button" class="button-secondary" style="width:22px;margin:0px;padding:0px;" v-on:click="column.value += 1" value="+" title="trt('Increase_by_1')">
<input type="button" class="button-secondary" style="width:22px;margin:0px;padding:0px;" v-on:click="column.value -= 1" value="-" title="trt('Decrease_by_1')">
</div>
<div v-if="column.vt=='object'" :style="{ backgroundColor: index % 2 === 0 ? 'var(--row-color-1)' : 'var(--row-color-2)' }">
<div style="width:150px;display:inline-block;">{{column.d}}</div>
<input type="text">
</div>
<div v-if="column.vt=='string'" :style="{ backgroundColor: index % 2 === 0 ? 'var(--row-color-1)' : 'var(--row-color-2)' }">
<div style="width:150px;display:inline-block;">{{column.d}}</div>
<input type="text">
</div>
</div>
<div style="display: flex; justify-content: space-between;">
<div>
<label><input type="checkbox">trt('Repeat_the_addition_of_the_entry')</label>
</div>
<div>
<div style="display: inline-block;">
<input type="button" class="button-secondary" value="trt('Apply')">
<input type="button" class="button-secondary" value="trt('Cancel')">
</div>
</div>
</div>
</div>
if (rpos%2==0) bgColor='var(--row-color-1)'; else bgColor='var(--row-color-2)';
<script>
/*
<type n="Terminals" d="trt('Terminal')" ObjectID="id">
<properties>
<prop d="id" n="id" vt="i4" visible="0"/>
<prop d="trt('Company')" n="company_id" vt="object" maybenull="0" ot="Companies" FieldCaption="name" selector="combo"/>
<prop d="trt('Phone')" n="phone" vt="string" size="20"/>
<prop d="trt('Serial_number')" n="serial" vt="string" size="50"/>
<prop d="IMEI" n="imei" vt="string" size="50" maybenull="0"/>
<prop d="trt('Terminal model')" n="terminal_model_id" vt="object" maybenull="0" ot="TerminalsModels" FieldCaption="name" selector="combo"/>
<prop d="trt('Description')" n="description" vt="text" size="500"/>
<sql-query t="i">
<![CDATA[select * from main.p_Terminals_i(${_user_id},${company_id},${phone},${serial},${imei},${terminal_model_id},${description});]]>
</sql-query>
<sql-query t="u">
<![CDATA[select * from main.p_Terminals_u(${_user_id},${id},${company_id},${phone},${serial},${imei},${terminal_model_id},${description});]]>
</sql-query>
<sql-query t="d">
<![CDATA[select * from main.p_Terminals_d(${_user_id},${id});]]>
</sql-query>
<sql-query t="s">
<![CDATA[select * from main.p_Terminals_s(${_user_id},${id},0,NULL);]]>
</sql-query>
</properties>
<objects-list d="trt('Terminals')" width="1000">
<sql-query>
<![CDATA[
select * from main.p_terminals_ss(${_user_id},${id},${company_id},${terminal_id},${install},${imei},${serial});
]]>
</sql-query>
<filter height="1">
<column d="id" n="id" vt="string" visible="0"/>
<column d="trt('Company')" n="company_id" vt="object" object="Companies" FieldCaption="name" selector="combo"/>
<column d="terminal_id" n="terminal_id" vt="i4" visible="0"/>
<column d="trt('Installed')" n="install" vt="b"/>
<column d="trt('IMEI')" n="imei" vt="string"/>
<column d="trt('Serial_number')" n="serial" vt="string"/>
</filter>
<column d="trt('Terminal_model')" n="terminal_model_name" width="150"/>
<column d="trt('Company')" n="campany_name" width="150"/>
<column d="trt('Installed_on')" n="object_name" width="150"/>
<column d="trt('Phone')" n="phone" width="150"/>
<column d="trt('Serial_number')" n="serial" width="120"/>
<column d="IMEI" n="imei" width="300"/>
<column d="trt('Description')" n="description" width="300"/>
<column d="trt('Count_sensors')" n="tscnt" width="120">
<type n="TerminalsSensors">
<objects-list d="trt('Sensors_types')">
<filter height="1">
<column n="terminal_id"><![CDATA[${id}]]>
</column>
</filter>
</objects-list>
</type>
</column>
<column d="Настройки" n="tstcnt" width="120">
<type n="TerminalsSettings">
<objects-list>
<filter>
<column n="terminal_id"><![CDATA[${id}]]>
</column>
</filter>
</objects-list>
</type>
</column>
</objects-list>
</type>
*/
let str= `
{
"type":{
"n":"Terminals",
"d":"trt('Terminal')",
"ObjectID":"id",
"edit_object":{
"columns":[
{"d":"id", "n":"id", "vt":"i4", "visible":"0", "value":6},
{"d":"trt('Company')", "n":"company_id", "vt":"object", "maybenull":"0", "ot":"Companies", "FieldCaption":"name", "selector":"combo"},
{"d":"trt('Phone')", "n":"phone", "vt":"string", "size":"20"},
{"d":"trt('Serial_number')", "n":"serial", "vt":"string", "size":"50"},
{"d":"IMEI", "n":"imei", "vt":"string", "size":"50", "maybenull":"0"},
{"d":"trt('Terminal model')", "n":"terminal_model_id", "vt":"object", "maybenull":"0", "ot":"TerminalsModels", "FieldCaption":"name", "selector":"combo"},
{"d":"trt('Description')", "n":"description", "vt":"text", "size":"500"}
],
"insert_query":"",
"update_query":"",
"delete_query":"",
"select_query":""
},
"show-object":{
"d":"trt('Terminals')",
"width":"1000",
"sql-query":"",
"filter":{
"columns":[
{"d":"id","n":"id","vt":"string","visible":"0"},
{"d":"trt('Company')","n":"company_id","vt":"object","object":"Companies","FieldCaption":"name","selector":"combo"},
{"d":"terminal_id","n":"terminal_id","vt":"i4","visible":"0"},
{"d":"trt('Installed')","n":"install","vt":"b"},
{"d":"trt('IMEI')","n":"imei","vt":"string"},
{"d":"trt('Serial_number')","n":"serial","vt":"string"}
]
},
"columns":[
{"d":"trt('Terminal_model')", "n":"terminal_model_name", "width":"150"},
{"d":"trt('Company')", "n":"campany_name", "width":"150"},
{"d":"trt('Installed_on')", "n":"object_name", "width":"150"},
{"d":"trt('Phone')", "n":"phone", "width":"150"},
{"d":"trt('Serial_number')", "n":"serial", "width":"120"},
{"d":"IMEI", "n":"imei", "width":"300"},
{"d":"trt('Description')", "n":"description", "width":"300"},
{"d":"trt('Count_sensors')", "n":"tscnt", "width":"120",
"type":{
"n":"TerminalsSensors",
"show-object":{
"d":"trt('Sensors_types')",
"filter":{
"height":"1",
"columns":[
{
"n":"terminal_id",
"data":""
}
]
}
}
}
},
{"d":"Настройки", "n":"tstcnt", "width":"120",
"type":{
"n":"TerminalsSettings",
"show-object":{
"filter":{
"columns":[
{
"n":"terminal_id",
"data":""
}
]
}
}
}
}
]
}
}
}
`;
var myObject = new Vue({
el: '#app',
data: JSON.parse(str)
});
</script>
</body>
</html>