pnd8_rasp/app/engine/admin/modules/admin_schema.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').'" ) ');
}
}
}
?>