382 lines
14 KiB
PHP
382 lines
14 KiB
PHP
<?php
|
|
|
|
class admin_schema extends module {
|
|
|
|
var $templ = "admin_schema.htm";
|
|
var $_get_vars = array( 'act', 'obj_name', 'attr_name' );
|
|
var $_post_vars = array( 'act', 'attr_name', 'attr_type', '_obj', 'obj_names', 'obj_title' );
|
|
var $obj_cache = array();
|
|
var $migrationPrefix = '';
|
|
|
|
function _init() {
|
|
$this->migrationPrefix = date('Ymd-Hi');
|
|
return parent::_init();
|
|
}
|
|
|
|
function _on_() {
|
|
global $R, $core_db;
|
|
$tpl = $R->getTpl( $this->templ, 'body' );
|
|
$tplr = $R->getTpl( $this->templ, 'row' );
|
|
|
|
$db2 = $core_db->q( "SELECT DISTINCT `obj_name` FROM `_sys_datatypes` ORDER BY `obj_name`" );
|
|
while( $db2->r() ) {
|
|
$tt = $R->set('obj_name', $db2->f('obj_name'), $tplr );
|
|
$tpl = $R->parse( 'rows', $tt, $tpl );
|
|
$this->obj_cache[] = $db2->f('obj_name');
|
|
}
|
|
$tpl = $R->set( 'form', $this->r_table(), $tpl );
|
|
|
|
return $R->clear( $tpl );
|
|
}
|
|
|
|
|
|
function r_table() {
|
|
global $R, $core_db;
|
|
|
|
if (!$this->obj_name) return;
|
|
|
|
$tpl = $R->getTpl( $this->templ, 'edit_table' );
|
|
$tplr = $R->getTpl( $this->templ, 'edit_table_row' );
|
|
|
|
$db2 = $core_db->q( 'SELECT * FROM `_sys_datatypes` WHERE `obj_name` = "' . $this->obj_name . '" ORDER BY `attr_order`' );
|
|
while( $db2->r() ) {
|
|
$tt = $R->set('name', $db2->f('attr_name'), $tplr );
|
|
$tt = $R->set('attr_desc', $db2->f('attr_desc'), $tt );
|
|
$tt = $R->set('attr_templ', $db2->f('attr_templ'), $tt );
|
|
$tt = $R->set('attr_order', $db2->f('attr_order'), $tt );
|
|
$tt = $R->set('attr_hide', $db2->f('attr_hide')?'checked':'', $tt );
|
|
$tt = $R->set('attr_mand', $db2->f('attr_mand')?'checked':'', $tt );
|
|
$tt = $R->set('attr_view', $this->r_types( $db2->f('attr_type') ), $tt );
|
|
$tpl = $R->parse( 'rows', $tt, $tpl );
|
|
}
|
|
$tpl = $R->set('obj_name', $this->obj_name, $tpl );
|
|
$tpl = $R->set('attr_view', $this->r_types(), $tpl );
|
|
|
|
$sql = "SELECT TABLE_COMMENT FROM `information_schema`.`TABLES` where TABLE_SCHEMA = '".$core_db->dbname."' and TABLE_NAME = '".$this->obj_name."' ";
|
|
$db2 = $core_db->q($sql);
|
|
$db2->nr();
|
|
$tpl = $R->set('obj_title', htmlspecialchars($db2->f('TABLE_COMMENT')), $tpl);
|
|
|
|
|
|
return $R->clear( $tpl );
|
|
}
|
|
|
|
function r_types( $val = '' ) {
|
|
global $loaded_attrs;
|
|
sort($loaded_attrs);
|
|
sort($this->obj_cache);
|
|
$html = '<option value="" selected>---</option>';
|
|
foreach ($loaded_attrs as $v ) {
|
|
$classname = 'attr_' . $v;
|
|
$size = $classname::getDBType();
|
|
|
|
//eval('$'."size = attr_$v::getDBType();");
|
|
|
|
switch( $v ) {
|
|
case 'LINK':
|
|
$html .= '<optgroup label="'.$v.'">';
|
|
foreach( $this->obj_cache as $obj_name ) {
|
|
$vv = $v . '|' . $obj_name;
|
|
$title = "LINK " . $obj_name;
|
|
if ( $vv == $val )
|
|
$html .= '<option value="' . $vv . '" selected>' . $title . " [$size]" .'</option>';
|
|
else
|
|
$html .= '<option value="' . $vv . '">' . $title . " [$size]" .'</option>';
|
|
}
|
|
$html .= '</optgroup>';
|
|
break;
|
|
case 'MLINK':
|
|
$html .= '<optgroup label="'.$v.'">';
|
|
foreach( $this->obj_cache as $obj_name ) {
|
|
$vv = $v . '|' . $obj_name;
|
|
$title = "MLINK " . $obj_name;
|
|
if ( $vv == $val )
|
|
$html .= '<option value="' . $vv . '" selected>' . $title . " [$size]" .'</option>';
|
|
else
|
|
$html .= '<option value="' . $vv . '">' . $title . " [$size]" .'</option>';
|
|
}
|
|
$html .= '</optgroup>';
|
|
break;
|
|
default:
|
|
if ( $v == $val )
|
|
$html .= '<option value="' . $v . '" selected>' . $v ." [$size]" . '</option>';
|
|
else
|
|
$html .= '<option value="' . $v . '">' . $v . " [$size]" .'</option>';
|
|
break;
|
|
}
|
|
}
|
|
return $html;
|
|
}
|
|
|
|
function _on_add_attr() {
|
|
global $cat, $core_db, $auth;
|
|
if (!$this->attr_name ) cdie('no attr name');
|
|
if (!$this->attr_type ) cdie('no attr type');
|
|
|
|
$this->sLog( "-- [" . date('Y-m-d H:i:s') . "] Создание атрибута" );
|
|
$this->do_add($this->obj_name, $this->attr_name, $this->attr_type);
|
|
|
|
_redirect('?cat=' .$cat->cat .'&obj_name='.$this->obj_name);
|
|
}
|
|
|
|
function do_add( $obj_name, $attr_name, $attr_type, $attr_title = '', $attr_templ = '', $attr_order = 100 ) {
|
|
global $cat, $core_db, $auth;
|
|
$sys_obj = false;
|
|
if ( ( strpos( $obj_name, '_sys_') !== false ) ) {
|
|
$sys_obj = true;
|
|
}
|
|
|
|
|
|
/* CREATE TABLE */
|
|
$sql = "CREATE TABLE IF NOT EXISTS `" . $obj_name . "` (";
|
|
$sql .= " `id` INT(12) NOT NULL AUTO_INCREMENT PRIMARY KEY ";
|
|
$sql .= ") ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci";
|
|
$core_db->q( $sql );
|
|
$this->sLog( $sql );
|
|
/* ADD Attribute */
|
|
|
|
$v = explode('|',$attr_type);
|
|
$v = $v[0];
|
|
eval('$'."size = attr_$v::getDBType();");
|
|
|
|
$sql = "ALTER TABLE `" . $obj_name . "` ADD `" . $attr_name . "` " . $size . " NOT NULL";
|
|
$core_db->q( $sql );
|
|
$this->sLog( $sql );
|
|
|
|
if (substr($attr_type,0,4) == 'LINK') {
|
|
/* ADD index */
|
|
$sql = "ALTER TABLE `" . $obj_name . "` ADD INDEX ( `" . $attr_name . "` )";
|
|
$core_db->q( $sql );
|
|
$this->sLog( $sql );
|
|
}
|
|
|
|
|
|
if ($attr_type == 'tree_object') {
|
|
/* ADD index */
|
|
$sql = "ALTER TABLE `" . $obj_name . "` ADD INDEX ( `" . $attr_name . "` )";
|
|
$core_db->q( $sql );
|
|
$this->sLog( $sql );
|
|
}
|
|
|
|
/* ADD to Datatype table */
|
|
$sql = 'REPLACE INTO `_sys_datatypes` (`obj_name`, `attr_name`,`attr_type`,`attr_desc`,`attr_templ`,`attr_order`) VALUES ("'.$obj_name.'","'.$attr_name.'","'.$attr_type.'","'.$attr_title.'","'.$attr_templ.'","'.$attr_order.'")';
|
|
|
|
$core_db->q( $sql );
|
|
$this->sLog( $sql );
|
|
}
|
|
|
|
function _on_do_urled() {
|
|
global $cat;
|
|
|
|
$this->sLog( "-- [" . date('Y-m-d H:i:s') . "] Создание атрибутов" );
|
|
$this->do_add($this->obj_name, 'title', 'input', 'Название','', 50);
|
|
$this->do_add($this->obj_name, 'url', 'full_url', 'Полный URL','prefix|cat_id',60 );
|
|
$this->do_add($this->obj_name, 'description', 'redactor_html', 'Текстовый блок');
|
|
$this->do_add($this->obj_name, 'page_description', 'input', 'seo description','',504);
|
|
$this->do_add($this->obj_name, 'page_h1', 'input', 'seo H1','',502);
|
|
$this->do_add($this->obj_name, 'page_keywords', 'input', 'seo keywords','',503);
|
|
$this->do_add($this->obj_name, 'page_title', 'input', 'seo title','',501);
|
|
$this->do_add($this->obj_name, '_sys_deleted', 'checkbox', 'Удалённый','', 1000);
|
|
$this->do_add($this->obj_name, '_sys_order', 'int12', 'Порядок сортировки','', 800);
|
|
$this->do_add($this->obj_name, '_sys_unvisible', 'checkbox', 'Невидимый','', 999);
|
|
$this->do_add($this->obj_name, '_sys_lastchange', 'datetime_modify', 'Последнее изменение','', 999);
|
|
|
|
_redirect('?cat=' .$cat->cat .'&obj_name='.$this->obj_name);
|
|
}
|
|
|
|
|
|
function _on_do_treeobj() {
|
|
|
|
global $cat;
|
|
|
|
$this->sLog( "-- [" . date('Y-m-d H:i:s') . "] Создание атрибутов" );
|
|
$this->do_add($this->obj_name, 'title', 'input', 'Название','', 50);
|
|
$this->do_add($this->obj_name, 'parent_id', 'tree_object', 'Родитель','',60 );
|
|
$this->do_add($this->obj_name, 'path_ids', 'input', 'Путь по ID');
|
|
$this->do_add($this->obj_name, 'path_titles', 'input', 'Путь по названию','',504);
|
|
$this->do_add($this->obj_name, 'level', 'int12', 'Уровень','',502);
|
|
$this->do_add($this->obj_name, '_sys_unvisible', 'checkbox', 'Невидимый','', 999);
|
|
|
|
_redirect('?cat=' .$cat->cat .'&obj_name='.$this->obj_name);
|
|
}
|
|
|
|
|
|
function _on_save_object() {
|
|
global $core_db, $cat, $auth;
|
|
$attrs = array( 'attr_type', 'attr_templ', 'attr_desc', 'attr_hide', 'attr_mand', 'attr_order', '_sys_deleted' );
|
|
$obj = $this->_obj[$this->obj_name];
|
|
|
|
$sys_obj = false;
|
|
if ( ( strpos( $this->obj_name, '_sys_') !== false ) ) {
|
|
$sys_obj = true;
|
|
}
|
|
|
|
|
|
// Вычисляем текущие хеши, чтобы понять, есть ли изменения в данных
|
|
$oldObjHash = [];
|
|
$db2 = $core_db->q( 'SELECT * FROM `_sys_datatypes` WHERE `obj_name` = "' . $this->obj_name . '" ORDER BY `attr_order`' );
|
|
while( $db2->r() ) {
|
|
$attr_hash_array = [];
|
|
foreach ($attrs as $k ) {
|
|
$attr_hash_array[$k] = $db2->f($k);
|
|
}
|
|
$oldObjHash[$db2->f('attr_name')] = md5(json_encode($attr_hash_array));
|
|
}
|
|
|
|
$sql = "SELECT TABLE_COMMENT FROM `information_schema`.`TABLES` where TABLE_SCHEMA = '".$core_db->dbname."' and TABLE_NAME = '".$this->obj_name."' ";
|
|
$db2 = $core_db->q($sql);
|
|
$db2->nr();
|
|
$oldObjTitle = $db2->f('TABLE_COMMENT');
|
|
|
|
|
|
foreach ( $obj as $attr_name => $attr_vals ) {
|
|
$presave = [];
|
|
foreach ($attrs as $k ) {
|
|
if (isset( $attr_vals[$k])) {
|
|
$presave[$k] = $attr_vals[$k];
|
|
} else {
|
|
$presave[$k] = "0";
|
|
}
|
|
}
|
|
$attr_hash = md5(json_encode($presave));
|
|
|
|
$presave['obj_name'] = $this->obj_name;
|
|
$presave['attr_name'] = $attr_name;
|
|
if ($attr_hash != $oldObjHash[$attr_name]) {
|
|
$this->sLog( "-- [" . date('Y-m-d H:i:s') . "] Изменение атрибута " . $attr_name );
|
|
$sql = 'REPLACE INTO `_sys_datatypes` (`' . implode('`, `',array_keys($presave)) . '`) VALUES ("'.implode('" , "',array_values($presave)) . '")';
|
|
$core_db->q( $sql );
|
|
$this->sLog( $sql );
|
|
}
|
|
}
|
|
|
|
if ($oldObjTitle != $this->obj_title) {
|
|
$sql = "ALTER TABLE `".$this->obj_name."` COMMENT = '".db_escape_string($this->obj_title)."';";
|
|
$core_db->q( $sql );
|
|
$this->sLog( "-- [" . date('Y-m-d H:i:s') . "] Изменение комментария " . $this->obj_name );
|
|
$this->sLog( $sql );
|
|
}
|
|
|
|
|
|
_redirect('?cat=' .$cat->cat .'&obj_name='.$this->obj_name);
|
|
}
|
|
|
|
function sLog( $txt = '' ) {
|
|
$f = fopen( _ENGINE_DIR . 'migrations/' . $this->migrationPrefix . '-' . $this->obj_name . ".sql", "a" );
|
|
fputs($f, $txt . ";\n" );
|
|
fclose($f);
|
|
|
|
$this->saveMigration($this->migrationPrefix . '-' . $this->obj_name . ".sql");
|
|
|
|
}
|
|
|
|
|
|
function _on_del_attr() {
|
|
global $core_db, $cat;
|
|
$obj_name = $this->obj_name;
|
|
$attr_name = $this->attr_name;
|
|
if ( $obj_name && $attr_name ) {
|
|
|
|
$this->sLog( "-- [" . date('Y-m-d H:i:s') . "] Удаление атрибута " . $attr_name );
|
|
|
|
$core_db->q("DELETE FROM `_sys_datatypes` WHERE `obj_name` = '".$obj_name."' AND `attr_name` = '".$attr_name."'");
|
|
$this->sLog("DELETE FROM `_sys_datatypes` WHERE `obj_name` = '".$obj_name."' AND `attr_name` = '".$attr_name."'");
|
|
|
|
$core_db->q("ALTER TABLE `".$obj_name."` DROP `".$attr_name."`");
|
|
$this->sLog("ALTER TABLE `".$obj_name."` DROP `".$attr_name."`");
|
|
}
|
|
|
|
_redirect('?cat=' . $cat->cat . '&obj_name='. $obj_name);
|
|
}
|
|
|
|
function _on_export() {
|
|
global $cat, $core_db;
|
|
|
|
$objname = $this->obj_name;
|
|
|
|
$sql = "SHOW CREATE TABLE `".$objname."`";
|
|
$db2 = $core_db->q($sql);
|
|
$db2->nr();
|
|
$sql_arr[] = $db2->f('Create Table');
|
|
|
|
|
|
$sql = "SELECT * FROM `_sys_datatypes` WHERE `obj_name` = '".$objname."'";
|
|
$db2 = $core_db->q($sql);
|
|
while( $db2->nr() ) {
|
|
|
|
$sql_arr[] = "REPLACE INTO `_sys_datatypes`
|
|
(`obj_name`,`attr_name`,`attr_type`,`attr_templ`,`attr_desc`,`attr_hide`,`attr_mand`,`attr_order`)
|
|
VALUES
|
|
(
|
|
'".db_escape_string($db2->f('obj_name'))."',
|
|
'".db_escape_string($db2->f('attr_name'))."',
|
|
'".db_escape_string($db2->f('attr_type'))."',
|
|
'".db_escape_string($db2->f('attr_templ'))."',
|
|
'".db_escape_string($db2->f('attr_desc'))."',
|
|
'".db_escape_string($db2->f('attr_hide'))."',
|
|
'".db_escape_string($db2->f('attr_mand'))."',
|
|
'".db_escape_string($db2->f('attr_order'))."'
|
|
)
|
|
";
|
|
}
|
|
|
|
|
|
$html .= implode($sql_arr, ';<br>');
|
|
|
|
echo $html;
|
|
die();
|
|
}
|
|
|
|
function _on_export_grp() {
|
|
global $core_db;
|
|
|
|
foreach( $this->obj_names as $objname ) {
|
|
$sql = "SHOW CREATE TABLE `".$objname."`";
|
|
$db2 = $core_db->q($sql);
|
|
$db2->nr();
|
|
$sql_arr[] = $db2->f('Create Table');
|
|
|
|
|
|
$sql = "SELECT * FROM `_sys_datatypes` WHERE `obj_name` = '".$objname."'";
|
|
$db2 = $core_db->q($sql);
|
|
while( $db2->nr() ) {
|
|
|
|
$sql_arr[] = "REPLACE INTO `_sys_datatypes`
|
|
(`obj_name`,`attr_name`,`attr_type`,`attr_templ`,`attr_desc`,`attr_hide`,`attr_mand`,`attr_order`)
|
|
VALUES
|
|
(
|
|
'".db_escape_string($db2->f('obj_name'))."',
|
|
'".db_escape_string($db2->f('attr_name'))."',
|
|
'".db_escape_string($db2->f('attr_type'))."',
|
|
'".db_escape_string($db2->f('attr_templ'))."',
|
|
'".db_escape_string($db2->f('attr_desc'))."',
|
|
'".db_escape_string($db2->f('attr_hide'))."',
|
|
'".db_escape_string($db2->f('attr_mand'))."',
|
|
'".db_escape_string($db2->f('attr_order'))."')
|
|
";
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
header('Content-Disposition: attachment; filename=dump.sql');
|
|
|
|
$html .= implode($sql_arr, ';' . PHP_EOL);
|
|
echo $html;
|
|
|
|
die();
|
|
}
|
|
|
|
|
|
function saveMigration($filename) {
|
|
global $core_db;
|
|
$core_db->q('SELECT apply_datetime FROM _sys_db_migrations WHERE `filename` = "'.db_escape_string($filename).'" ');
|
|
if (!$core_db->nr()) {
|
|
$core_db->q('INSERT INTO _sys_db_migrations (`filename`,`apply_datetime`) values ("'.db_escape_string($filename).'", "'.date('Y-m-d H:i:s').'" ) ');
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
?>
|