1
0
mirror of https://github.com/e107inc/e107.git synced 2025-01-17 20:58:30 +01:00
php-e107/e107_handlers/db_verify_class.php

1831 lines
44 KiB
PHP
Raw Normal View History

2006-12-02 04:36:16 +00:00
<?php
/*
* e107 website system
*
2009-11-18 01:06:08 +00:00
* Copyright (C) 2008-2009 e107 Inc (e107.org)
* Released under the terms and conditions of the
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
*
* Administration - DB Verify Class
*
* $URL: /cvs_backup/e107_0.8/e107_admin/db_verify.php,v $
* $Revision: 12255 $
* $Id: 2011-06-07 17:16:42 -0700 (Tue, 07 Jun 2011) $
* $Author: e107coders $
*
2006-12-02 04:36:16 +00:00
*/
if (!defined('e107_INIT')) { exit; }
2006-12-02 04:36:16 +00:00
2017-01-23 09:41:23 -08:00
e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE.'/admin/lan_db_verify.php');
/**
*
*/
class db_verify
{
2017-02-03 13:02:08 -08:00
var $backUrl = "";
public $sqlFileTables = array();
2017-02-03 13:02:08 -08:00
private $sqlDatabaseTables = array();
var $sqlLanguageTables = array();
var $results = array();
var $indices = array(); // array(0) - Issue?
var $fixList = array();
private $currentTable = null;
private $internalError = false;
2011-06-09 07:03:55 +00:00
var $fieldTypes = array('time','timestamp','datetime','year','tinyblob','blob',
'mediumblob','longblob','tinytext','mediumtext','longtext','text','date', 'json');
2011-06-09 07:03:55 +00:00
var $fieldTypeNum = array('bit','tinyint','smallint','mediumint','integer','int','bigint',
'real','double','float','decimal','numeric','varchar','char ','binary','varbinary','enum','set'); // space after 'char' required.
2011-06-09 07:03:55 +00:00
var $modes = array(
'missing_table' => 'create',
'mismatch' => 'alter',
'missing_field' => 'insert',
'missing_index' => 'index',
'mismatch_index' => '', // TODO
);
var $errors = array();
const cachetag = 'Dbverify';
2011-06-09 07:03:55 +00:00
/**
* Setup
*/
function __construct()
{
2011-06-07 02:25:55 +00:00
2017-01-07 11:18:32 -08:00
$sql = e107::getDb();
$sql->gen('SET SQL_QUOTE_SHOW_CREATE = 1');
$this->backUrl = e_SELF;
if(!deftrue('e_DEBUG') && $tmp = e107::getCache()->retrieve(self::cachetag, 15, true, true))
{
2017-02-03 13:02:08 -08:00
$this->sqlFileTables = e107::unserialize($tmp);
}
else
{
$this->sqlFileTables = $this->load();
$data = e107::serialize($this->sqlFileTables,'json');
e107::getCache()->set(self::cachetag,$data, true, true, true);
}
2017-02-03 13:02:08 -08:00
$this->sqlLanguageTables = $this->getSqlLanguages();
// $this->loadCreateTableData();
return $this;
}
/**
* @return bool
*/
public function clearCache()
{
return e107::getCache()->clear(self::cachetag, true);
}
/**
* @return array
*/
private function load()
{
$mes = e107::getMessage();
$pref = e107::getPref();
$ret = array();
$core_data = file_get_contents(e_CORE.'sql/core_sql.php');
2017-02-03 13:02:08 -08:00
$ret['core'] = $this->getSqlFileTables($core_data);
if(!empty($pref['e_sql_list']))
{
foreach($pref['e_sql_list'] as $path => $file)
{
$filename = e_PLUGIN.$path.'/'.$file.'.php';
if(is_readable($filename))
{
$id = str_replace('_sql','',$file);
$data = file_get_contents($filename);
$this->currentTable = $id;
2017-02-03 13:02:08 -08:00
$ret[$id] = $this->getSqlFileTables($data);
unset($data);
}
else
{
$message = str_replace("[x]",$filename,DBVLAN_22);
$mes->add($message, E_MESSAGE_WARNING);
}
}
}
2011-06-09 07:03:55 +00:00
return $ret;
2017-02-03 13:02:08 -08:00
}
/**
* Permissive field validation
*/
private function diffStructurePermissive($expected, $actual)
{
$expected['default'] = isset($expected['default']) ? $expected['default'] : '';
$actual['default'] = isset($actual['default']) ? $actual['default'] : '';
if($expected['type'] === 'JSON') // Fix for JSON alias MySQL 5.7+
{
$expected['type'] = 'LONGTEXT';
}
// Permit actual text types that default to null even when
// expected does not explicitly default to null
if(0 === strcasecmp($expected['type'], $actual['type']) &&
1 === preg_match('/[A-Z]*TEXT/i', $expected['type']) &&
0 === strcasecmp($actual['default'], "DEFAULT NULL"))
{
$expected['default'] = $actual['default'];
}
// Loosely typed default value for numeric types
if(1 === preg_match('/([A-Z]*INT|NUMERIC|DEC|FIXED|FLOAT|REAL|DOUBLE)/i', $expected['type']))
{
$expected['default'] = preg_replace("/DEFAULT '(\d*\.?\d*)'/i", 'DEFAULT $1', $expected['default']);
$actual['default'] = preg_replace("/DEFAULT '(\d*\.?\d*)'/i", 'DEFAULT $1', $actual['default'] );
}
/**
* Display width specification for integer data types was deprecated in MySQL 8.0.17
* @see https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html
*/
if(1 === preg_match('/([A-Z]*INT)/i', $expected['type']))
{
$expected['value'] = '';
$actual['value'] = '';
}
// Correct difference on CREATE TABLE statement between MariaDB and MySQL
if(1 === preg_match('/(DATE|DATETIME|TIMESTAMP|TIME|YEAR)/i', $expected['default']))
{
$expected['default'] = preg_replace("/CURRENT_TIMESTAMP\(\)/i", 'CURRENT_TIMESTAMP', $expected['default']);
$actual['default'] = preg_replace("/CURRENT_TIMESTAMP\(\)/i", 'CURRENT_TIMESTAMP', $actual['default'] );
}
return array_diff_assoc($expected, $actual);
}
2011-06-09 07:03:55 +00:00
/**
* Main Routine for checking and rendering results.
*/
function verify()
{
if(!empty($_POST['runfix']))
{
$this->runFix($_POST['fix']);
}
if(!empty($_POST['verify_table']))
2011-06-09 07:03:55 +00:00
{
$this->runComparison($_POST['verify_table']);
}
else
{
$this->renderTableSelect();
2011-06-09 07:03:55 +00:00
}
}
/**
* @param $fileArray
* @return void
*/
2011-06-09 07:03:55 +00:00
function runComparison($fileArray)
{
$mes = e107::getMessage();
2011-06-09 07:03:55 +00:00
foreach($fileArray as $tab)
{
$this->compare($tab);
foreach($this->sqlLanguageTables as $lng=>$lantab)
{
$this->compare($tab,$lng);
}
}
2011-06-09 07:03:55 +00:00
if($cnt = count($this->errors))
{
2011-06-09 07:03:55 +00:00
$message = str_replace("[x]",$cnt,DBVLAN_26); // Found [x] issues.
$mes->add($message, E_MESSAGE_WARNING);
$this->renderResults($fileArray);
}
2011-06-09 07:03:55 +00:00
else
{
if($this->internalError === false)
{
$mes->addSuccess(DBLAN_111);
$mes->addSuccess("<a class='btn btn-primary' href='".$this->backUrl."'>".LAN_BACK."</a>");
}
//$debug = "<pre>".print_r($this->results,TRUE)."</pre>";
//$mes->add($debug,E_MESSAGE_DEBUG);
2011-06-09 07:03:55 +00:00
//$text .= "<div class='buttons-bar center'>".$frm->admin_button('back', DBVLAN_17, 'back')."</div>";
echo $mes->render();
// $ns->tablerender("Okay",$mes->render().$text);
2011-06-09 07:03:55 +00:00
}
}
// $this->sqlTables = $this->sqlTableList();
// print_a($this->tables);
// $this->renderTableSelect();
// print_a($field);
// print_a($match[2]);
// echo "<pre>".$sql_data."</pre>";
2011-06-09 07:03:55 +00:00
/**
* Check core tables and installed plugin tables
* @param $exclude - array of plugins to exclude.
*/
2013-04-15 19:46:35 -07:00
function compareAll($exclude = null)
{
2013-04-15 19:46:35 -07:00
if(is_array($exclude))
{
2013-04-15 19:46:35 -07:00
foreach($exclude as $val)
{
2017-02-03 13:02:08 -08:00
unset($this->sqlFileTables[$val]);
2013-04-15 19:46:35 -07:00
}
}
2017-02-03 13:02:08 -08:00
$dtables = array_keys($this->sqlFileTables);
foreach($dtables as $tb)
{
$this->compare($tb);
}
2015-01-28 01:46:49 -08:00
if(!empty($this->sqlLanguageTables)) // language tables.
{
2015-01-28 01:46:49 -08:00
foreach($this->sqlLanguageTables as $lng=>$lantab)
{
2015-01-28 01:46:49 -08:00
foreach($dtables as $tb)
{
$this->compare($tb,$lng);
}
}
}
}
/**
* @param $selection
* @param $language
* @return false|void
*/
public function compare($selection, $language='')
{
$this->currentTable = $selection;
// var_dump($this->sqlFileTables[$selection]);
2017-02-03 13:02:08 -08:00
if(!isset($this->sqlFileTables[$selection])) // doesn't have an SQL file.
{
// e107::getMessage()->addDebug("No SQL File for ".$selection);
return false;
}
2017-02-03 13:02:08 -08:00
if(empty($this->sqlFileTables[$selection]['tables']))
2015-01-28 01:46:49 -08:00
{
//$this->internalError = true;
e107::getMessage()->addDebug("Couldn't read table data for ".$selection);
return false;
2015-01-28 01:46:49 -08:00
}
2017-02-03 13:02:08 -08:00
foreach($this->sqlFileTables[$selection]['tables'] as $key=>$tbl)
{
//$this->errors[$tbl]['_status'] = 'ok'; // default table status
$rawSqlData = $this->getSqlData($tbl,$language);
if($rawSqlData === false)
{
if($language) continue;
$this->errors[$tbl]['_status'] = 'missing_table';
$this->results[$tbl]['_file'] = $selection;
// echo "missing table: $tbl";
continue;
}
// echo "<h4>RAW</h4>";
// print_a($rawSqlData);
// $this->currentTable = $tbl;v
2017-02-03 13:02:08 -08:00
$sqlDataArr = $this->getSqlFileTables($rawSqlData);
// echo "<h4>PARSED</h4>";
// print_a($sqlDataArr);
$fileData['field'] = $this->getFields($this->sqlFileTables[$selection]['data'][$key]);
$sqlData['field'] = $this->getFields($sqlDataArr['data'][0]);
$fileData['index'] = $this->getIndex($this->sqlFileTables[$selection]['data'][$key]);
$sqlData['index'] = $this->getIndex($sqlDataArr['data'][0]);
/*
$debugA = print_r($fileFieldData,TRUE); // Extracted Field Arrays
$debugA .= "<h2>Index</h2>";
$debugA .= print_r($fileIndexData,TRUE);
$debugB = print_r($sqlFieldData,TRUE); // Extracted Field Arrays
$debugB .= "<h2>Index</h2>";
$debugB .= print_r($sqlIndexData,TRUE);
*/
2017-02-03 13:02:08 -08:00
$debugA = $this->sqlFileTables[$selection]['data'][$key]; // Extracted Raw Field Text
// $debugB = $rawSqlData;
$debugB = $sqlDataArr['data'][0]; // Extracted Raw Field Text
2011-06-07 02:25:55 +00:00
2017-01-29 18:43:52 -08:00
if(isset($debugA) && (e_PAGE === 'db.php'))
{
2021-02-27 06:52:07 -08:00
$debug = "<table class='table table-bordered table-condensed'>
<tr><td style='padding:5px;font-weight:bold'>FILE: ".$tbl." (key=".$key.")</td>
<td style='padding:5px;font-weight:bold'>SQL: ".$tbl."</td>
</tr>
<tr><td style='width:50%'><pre>".$debugA."</pre></td>
<td style='width:50%'><pre>".$debugB."</pre></td></tr></table>";
$mes = e107::getMessage();
$mes->add($debug,E_MESSAGE_DEBUG);
}
2011-06-07 02:25:55 +00:00
if($language)
{
$tbl = "lan_".$language."_".$tbl;
}
$this->prepareResults($tbl, $selection, $sqlData, $fileData);
unset($data);
}
}
/**
* @param string $type fields|indices
* @return array
*/
public function getResults($type='fields')
{
if($type === 'indices')
{
return $this->indices;
}
return $this->results;
}
/**
* @param string $tbl table name without prefix.
* @param string $selection 'core' OR plugin-folder name.
* @param array $sqlData ie. array('field'=>getFields($data), 'index'=>getFields($data));
* @param array $fileData ie. array('field'=>getFields($data), 'index'=>getFields($data));
* @todo Check for additional fields in SQL that should be removed.
* @todo Add support for MYSQL 5 table layout .eg. journal_id INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
*/
public function prepareResults($tbl, $selection, $sqlData, $fileData)
{
// Check field and index data
foreach(['field', 'index'] as $type)
{
$results = 'results';
if ($type === 'index')
{
$results = 'indices';
}
foreach($fileData[$type] as $key => $value)
{
$this->{$results}[$tbl][$key]['_status'] = 'ok';
if(!isset($sqlData[$type][$key]) || !is_array($sqlData[$type][$key]))
{
$this->errors[$tbl]['_status'] = 'error'; // table status
$this->{$results}[$tbl][$key]['_status'] = "missing_$type"; // type status
$this->{$results}[$tbl][$key]['_valid'] = $value;
$this->{$results}[$tbl][$key]['_file'] = $selection;
}
elseif(count($diff = $this->diffStructurePermissive($value, $sqlData[$type][$key])))
{
$this->errors[$tbl]['_status'] = "mismatch_$type";
$this->{$results}[$tbl][$key]['_status'] = 'mismatch';
$this->{$results}[$tbl][$key]['_diff'] = $diff;
$this->{$results}[$tbl][$key]['_valid'] = $value;
$this->{$results}[$tbl][$key]['_invalid'] = $sqlData[$type][$key];
$this->{$results}[$tbl][$key]['_file'] = $selection;
}
}
}
return null;
}
/**
* Compile Results into a complete list of Fixes that could be run without the need of a form selection.
*/
function compileResults()
{
foreach($this->results as $tabs => $field)
{
$file = varset($this->results[$tabs]['_file']);
$errorStatus = !empty($this->errors[$tabs]['_status']) ? $this->errors[$tabs]['_status'] : null;
if($errorStatus === 'missing_table') // Missing Table
{
$this->fixList[$file][$tabs]['all'][] = 'create';
}
elseif($this->errors[$tabs] != 'ok') // All Other Issues..
{
foreach($field as $k=>$f)
{
if($f['_status']=='ok') continue;
$status = $f['_status'];
if(!empty($this->modes[$status]))
{
$this->fixList[$f['_file']][$tabs][$k][] = $this->modes[$status];
}
}
}
}
// Index
if(count($this->indices))
{
foreach($this->indices as $tabs => $field)
{
if($this->errors[$tabs] != 'ok')
{
foreach($field as $k=>$f)
{
if($f['_status']=='ok') continue;
$this->fixList[$f['_file']][$tabs][$k][] = $this->modes[$f['_status']];
}
}
}
}
}
/**
* Returns the number of errors
*/
public function errors()
{
return count($this->errors);
}
/**
* @param $fileArray
* @return void
*/
function renderResults($fileArray=array())
{
$frm = e107::getForm();
$ns = e107::getRender();
$mes = e107::getMessage();
$text = "
<form method='post' action='".e_SELF."?".e_QUERY."'>
<fieldset id='core-db-verify-results'>
<legend id='core-db-verify-results-legend'>".DBVLAN_16."</legend>
2012-11-26 14:41:32 -08:00
<table class='table adminlist'>
<colgroup>
<col style='width: 25%'></col>
<col style='width: 25%'></col>
<col style='width: 10%'></col>
<col style='width: 30%'></col>
<col style='width: 10%'></col>
</colgroup>
<thead>
<tr>
<th>".DBVLAN_4."</th>
<th>".DBVLAN_5."</th>
<th class='center'>".DBVLAN_6."</th>
<th>".DBVLAN_7."</th>
<th class='center last'>".DBVLAN_19."</th>
</tr>
</thead>
<tbody>
";
$info = array(
'missing_table' => DBVLAN_13,
'mismatch' => DBVLAN_8,
'missing_field' => DBVLAN_11,
'ok' => ADMIN_TRUE_ICON,
'missing_index' => DBVLAN_25,
);
foreach($this->results as $tabs => $field)
{
2017-01-29 18:43:52 -08:00
if($this->errors[$tabs]['_status'] === 'missing_table') // Missing Table
{
$text .= "
<tr>
<td>".$this->renderTableName($tabs)."</td>
<td>&nbsp;</td>
<td class='center middle error'>".$info[$this->errors[$tabs]['_status']]."</td>
<td>&nbsp;</td>
<td class='center middle autocheck e-pointer'>".$this->fixForm($this->results[$tabs]['_file'],$tabs, 'all', '', 'create') . "</td>
</tr>
";
}
2011-06-09 07:03:55 +00:00
elseif($this->errors[$tabs] != 'ok') // All Other Issues..
{
foreach($field as $k=>$f)
{
if($f['_status']=='ok') continue;
$fstat = $info[$f['_status']];
$text .= "
<tr>
<td>".$this->renderTableName($tabs)."</td>
<td>".$k."&nbsp;</td>
<td class='center middle error'>".$fstat."</td>
<td>".$this->renderNotes($f)."&nbsp;</td>
<td class='center middle autocheck e-pointer'>".$this->fixForm($f['_file'],$tabs, $k, $f['_valid'], $this->modes[$f['_status']]) . "</td>
</tr>
";
}
}
}
// Indices
if(count($this->indices))
{
foreach($this->indices as $tabs => $field)
{
if($this->errors[$tabs] != 'ok')
{
foreach($field as $k=>$f)
{
if($f['_status']=='ok') continue;
$fstat = $info[$f['_status']];
$text .= "
<tr>
<td>".$this->renderTableName($tabs)."</td>
<td>".$k."&nbsp;</td>
<td class='center middle error'>".$fstat."</td>
<td>".$this->renderNotes($f,'index')."&nbsp;</td>
<td class='center middle autocheck e-pointer'>".$this->fixForm($f['_file'],$tabs, $k, $f['_valid'], $this->modes[$f['_status']]) . "</td>
</tr>
";
}
}
}
}
$text .= "
</tbody>
</table>
<br/>
";
$text .= "
<div class='buttons-bar right'>
".$frm->admin_button('runfix', DBVLAN_21, 'execute', '', array('id'=>false))."
".$frm->admin_button('check_all', 'jstarget:fix', 'action', LAN_CHECKALL, array('id'=>false))."
".$frm->admin_button('uncheck_all', 'jstarget:fix', 'action', LAN_UNCHECKALL, array('id'=>false));
foreach($fileArray as $tab)
{
$text .= $frm->hidden('verify_table[]',$tab);
}
$text .= "
</div>
</fieldset>
</form>
";
$ns->tablerender(DBVLAN_23.' - '.DBVLAN_16, $mes->render().$text);
}
/**
* @param $tabs
* @return mixed|string
*/
function renderTableName($tabs)
{
if(strpos($tabs,"lan_") === 0)
{
list($tmp,$lang,$table) = explode("_",$tabs,3);
return $table. " (".ucfirst($lang).")";
}
return $tabs;
}
/**
* @param $file
* @param $table
* @param $field
* @param $newvalue
* @param $mode
* @param $after
* @return string
*/
function fixForm($file, $table, $field, $newvalue, $mode, $after ='')
{
$frm = e107::getForm();
2015-02-15 02:37:36 -08:00
$text = $frm->checkbox("fix[$file][$table][$field][]", $mode, false, array('id'=>false));
return $text;
}
/**
* @param $data
* @param $mode
* @return string
*/
function renderNotes($data, $mode='field')
{
// return "<pre>".print_r($data,TRUE)."</pre>";
$v = $data['_valid'];
$i = $data['_invalid'];
$valid = $this->toMysql($v,$mode);
$invalid = $this->toMysql($i,$mode);
$text = "";
if($invalid)
{
$text .= "<strong>".DBVLAN_9."</strong>
<div class='indent'>".$invalid."</div>";
}
$text .= "<strong>".DBVLAN_10."</strong>
<div class='indent'>".$valid."</div>";
return $text;
}
/**
* @param $data
* @param $mode
* @return string|void
*/
public function toMysql($data, $mode = 'field')
{
if(!$data) return;
2017-01-29 18:43:52 -08:00
if($mode === 'index')
{
// print_a($data);
if($data['type'])
{
//return $data['type']." (".$data['field'].");";
// Check if index keyname exists and add backticks
$keyname = (!empty($data['keyname']) ? " `".$data['keyname']."`" : "");
return $data['type'] . $keyname . " (" . $data['field'] . ");";
}
else
{
return "INDEX `".$data['keyname']."` (".$data['field'].");";
}
}
2011-06-09 07:03:55 +00:00
if(!in_array(strtolower($data['type']), $this->fieldTypes))
{
$ret = $data['type']."(".$data['value'].") ".$data['attributes']." ".$data['null']." ".$data['default'];
return trim($ret);
}
else
{
$ret = $data['type'];
$ret .= !empty($data['attributes']) ? " ".$data['attributes'] : '';
$ret .= !empty($data['null']) ? " ".$data['null'] : '';
$ret .= !empty($data['default']) ? " ".$data['default'] : '';
return $ret;
}
}
// returns the previous Field
/**
* @param $array
* @param $cur
* @return int|mixed|string
*/
function getPrevious($array, $cur)
{
$fkeys = array_keys($array);
$cur_key = array_search($cur, $fkeys);
return @$fkeys[$cur_key - 1];
}
/**
* get the key ID for the current table which is being Fixed.
*/
function getId($tabl,$cur)
{
$key = array_flip($tabl);
if(strpos($cur,"lan_") === 0) // language table adjustment.
{
list($tmp,$lang,$cur) = explode("_",$cur,3);
}
if(isset($key[$cur]))
{
return $key[$cur];
}
}
/**
* @param string $mode index|alter|insert|drop|create|indexdrop
* @param string $table eg. submitnews
* @param string $field eg. submitnews_id
* @param string $sqlFileData (after CREATE) eg. dblog_id int(10) unsigned NOT NULL auto_increment, ..... KEY....
* @param string $engine MyISAM|InnoDB
* @return string SQL query
*/
function getFixQuery($mode, $table, $field, $sqlFileData, $engine = 'MyISAM' )
{
if(strpos($mode, 'index') === 0)
{
$fdata = $this->getIndex($sqlFileData);
$newval = $this->toMysql($fdata[$field],'index');
}
else
{
$fdata = $this->getFields($sqlFileData);
$newval = $this->toMysql($fdata[$field]);
}
switch($mode)
{
case 'alter':
$query = "ALTER TABLE `".MPREFIX.$table."` CHANGE `$field` `$field` $newval";
break;
case 'insert':
$after = ($aft = $this->getPrevious($fdata,$field)) ? " AFTER {$aft}" : "";
$query = "ALTER TABLE `".MPREFIX.$table."` ADD `$field` $newval{$after}";
break;
case 'drop':
$query = "ALTER TABLE `".MPREFIX.$table."` DROP `$field`";
break;
case 'index':
$newval = str_replace("PRIMARY", "PRIMARY KEY", $newval);
$query = "ALTER TABLE `".MPREFIX.$table."` ADD ".$newval;
break;
case 'indexdrop':
$query = "ALTER TABLE `".MPREFIX.$table."` DROP INDEX `$field`";
break;
case 'create':
$query = "CREATE TABLE `".MPREFIX.$table."` (".$sqlFileData.") ENGINE=".$engine.";";
break;
}
return $query;
}
/**
* Fix tables
* FixArray eg. [core][table][field] = alter|create|index| etc.
*/
function runFix($fixArray='')
{
$mes = e107::getMessage();
$log = e107::getLog();
if(!is_array($fixArray))
{
$fixArray = $this->fixList; // Fix All
}
foreach($fixArray as $j=>$file)
{
foreach($file as $table=>$val)
{
2017-02-03 13:02:08 -08:00
$id = $this->getId($this->sqlFileTables[$j]['tables'],$table);
$toFix = count($val);
foreach($val as $field=>$fixes)
{
foreach($fixes as $mode)
{
$query = $this->getFixQuery($mode,$table,$field,$this->sqlFileTables[$j]['data'][$id],$this->sqlFileTables[$j]['engine'][$id]);
// $mes->addDebug("Query: ".$query);
// continue;
if(e107::getDb()->gen($query) !== false)
{
$log->addDebug(LAN_UPDATED.' ['.$query.']');
$toFix--;
}
else
{
$log->addWarning(LAN_UPDATED_FAILED.' ['.$query.']');
$log->addWarning(e107::getDb()->getLastErrorText()); // PDO compatible.
/*if(mysql_errno())
{
$log->addWarning('SQL #'.mysql_errno().': '.mysql_error());
}*/
}
}
}
if(empty($toFix))
{
unset($this->errors[$table], $this->fixList[$j][$table]); // remove from error list since we are using a singleton
}
} //
}
2015-07-10 14:24:39 -07:00
$log->flushMessages("Database Table(s) Modified");
}
/**
* @param $sql_data
* @return array|false
*/
2017-02-03 13:02:08 -08:00
function getSqlFileTables($sql_data)
{
if(!$sql_data)
{
e107::getMessage()->addError("No SQL Data found in file");
return false;
}
$ret = array();
$sql_data = preg_replace("#\/\*.*?\*\/#mis", '', $sql_data); // remove comments
// echo "<h4>SqlData</h4>";
// print_a($sql_data);
// $regex = "/CREATE TABLE `?([\w]*)`?\s*?\(([\s\w\+\-_\(\),'\. `]*)\)\s*(ENGINE|TYPE)\s*?=\s?([\w]*)[\w =]*;/i";
2020-12-20 19:42:09 -08:00
// $regex = "/CREATE TABLE (?:IF NOT EXISTS )?`?([\w]*)`?\s*?\(([\s\w\+\-_\(\),:'\. `]*)\)\s*(ENGINE|TYPE)\s*?=\s?([\w]*)[\w =]*;/i";
// also support non-alphanumeric chars.
$regex = "/CREATE TABLE (?:IF NOT EXISTS )?`?([\w]*)`?\s*?\(([^;]*)\)\s*(ENGINE|TYPE)\s*?=\s?([\w]*)[\w =]*;/i";
preg_match_all($regex,$sql_data,$match);
$tables = array();
foreach($match[1] as $c=>$k)
{
if(strpos($k,'e107_') === 0) // remove prefix if found in sql dump.
{
$k = substr($k, 5);
}
$tables[$c] = $k;
}
$ret['tables'] = $tables;
$data = array();
if(!empty($match[2])) // clean/trim data.
{
foreach($match[2] as $dat)
{
$dat = str_replace("\t", '', $dat); // remove tab chars.
$data[] = trim($dat);
}
}
$ret['data'] = $data;
$ret['engine'] = $match[4];
if(empty($ret['tables']))
{
e107::getMessage()->addDebug("Unable to parse ".$this->currentTable."_sql.php file data. Possibly missing a ';' at the end?");
e107::getMessage()->addDebug(print_a($regex,true));
}
return $ret;
}
/**
* @param $data
* @param $print
* @return array
*/
2013-02-08 11:50:05 +02:00
function getFields($data, $print = false)
{
// Clean $data and add ` ` arond field-names - prevents issues when field == field-type.
$tmp = explode("\n",$data);
$newline = array();
foreach($tmp as $line)
{
$line = trim($line);
$newline[] = preg_replace("/^([^`A-Z\s][a-z_]*[0-9]?)/","`$1`", $line);
}
$data = implode("\n",$newline);
// --------------------
2011-06-09 07:03:55 +00:00
$mes = e107::getMessage();
// $regex = "/`?([\w]*)`?\s*?(".implode("|",$this->fieldTypes)."|".implode("|",$this->fieldTypeNum).")\s?(?:\([\s]?([0-9,]*)[\s]?\))?[\s]?(unsigned)?[\s]?.*?(?:(NOT NULL|NULL))?[\s]*(auto_increment|default .*)?[\s]?(?:PRIMARY KEY)?[\s]*?,?\s*?\n/im";
$regex = "/^\s*?`?([\w]*)`?\s*?(".implode("|",$this->fieldTypes)."|".implode("|",$this->fieldTypeNum).")\s?(?:\([\s]?([0-9,]*)[\s]?\))?[\s]?(unsigned)?[\s]?.*?(?:(NOT NULL|NULL))?[\s]*(auto_increment|default|AUTO_INCREMENT|DEFAULT [\w'\s.\(:\)-]*)?[\s]?(comment [\w\s'.-]*)?[\s]?(?:PRIMARY KEY)?[\s]*?,?\s*?\n/im";
// echo $regex."<br /><br />";
// $regex = "/`?([\w]*)`?\s*(int|varchar|tinyint|smallint|text|char|tinyint) ?(?:\([\s]?([0-9]*)[\s]?\))?[\s]?(unsigned)?[\s]?.*?(NOT NULL|NULL)?[\s]*(auto_increment|default .*)?[\s]?,/i";
2011-06-09 07:03:55 +00:00
// $regex = "/^\s*?`?([\w]*)`?\s*?(".implode("|",$this->fieldTypes)."|".implode("|",$this->fieldTypeNum).")\s?(?:\([\s]?([0-9,]*)[\s]?\))?[\s]?(unsigned)?[\s]?.*?(?:(NOT NULL|NULL))?[\s]*?(auto_increment|default [\w'\".-]*)?[\s]?(?:PRIMARY KEY)?[\s]*?,?\n/im";
//$regex = "/^\s*?`?([\w]*)`?\s*?(date|time|timestamp|datetime|year|tinyblob|blob|mediumblob|longblob|tinytext|mediumtext|longtext|text|bit|tinyint|smallint|mediumint|integer|int|bigint|real|double|float|decimal|numeric|varchar|char|binary|varbinary|enum|set)\s?(?:\([\s]?([0-9,]*)[\s]?\))?[\s]?(unsigned)?[\s]*?(?:(NOT NULL|NULL))?[\s]*?(auto_increment|default [\w'\".-]*)?[\s]?(?:PRIMARY KEY)?[\s]*?,?\n/im";
// $mes->addDebug($regex);
//$regex = "/^\s*?`?([\w]*)`?\s*?(date|time|timestamp|datetime|year|text|bit|tinyint|smallint|mediumint|integer|int|bigint|real|double|float|decimal|numeric|varchar|char|binary|varbinary|enum|set)\s?(?:\([\s]?([0-9,]*)[\s]?\))?[\s]?(unsigned)?[\s]*?(?:(NOT NULL|NULL))?[\s]*?(auto_increment|default [\w'.-]*)?[\s]?(?:PRIMARY KEY)?[\s]*?,?\n/i";
// echo "reg=".$regex;
preg_match_all($regex,$data,$m);
$ret = array();
2011-06-09 07:03:55 +00:00
2013-02-08 11:50:05 +02:00
if($print) var_dump($regex, $m);
foreach($m[1] as $k=>$val)
{
$ret[$val] = array(
'type' => trim(strtoupper($m[2][$k])),
'value' => $m[3][$k],
'attributes' => strtoupper($m[4][$k]),
'null' => strtoupper($m[5][$k]),
'default' => strtoupper($m[6][$k])
);
}
return $ret;
}
/**
* @param $data
* @param $print
* @return array
*/
2013-02-08 11:50:05 +02:00
function getIndex($data, $print = false)
{
// $regex = "/(?:(PRIMARY|UNIQUE|FULLTEXT))?[\s]*?KEY (?: ?`?([\w]*)`?)[\s]* ?(?:\([\s]?`?([\w,]*[\s]?)`?\))?,?/i";
// $regex = "/(?:(PRIMARY|UNIQUE|FULLTEXT|FOREIGN))?[\s]*?KEY (?: ?`?([\w]*)`?)[\s]* ?(?:\([\s]?([\w\s,`]*[\s]?)`?\))?,?/i";
$regex = "/(?:(PRIMARY|UNIQUE|FULLTEXT|FOREIGN))?[\s]*?(INDEX|KEY) (?: ?`?([\w]*)`?)[\s]* ?(?:\([\s]?([\w\s,`]*[\s]?)`?\))?,?/i";
preg_match_all($regex,$data,$m);
if (count($m) > 0)
{
unset($m[2]);
$m = array_combine(range(0, count($m)-1), array_values($m));
}
$ret = array();
if($print)
{
e107::getDebug()->log($m);
}
2013-02-08 11:50:05 +02:00
// Standard Detection Method.
$fieldReplace = array("`"," ");
foreach($m[3] as $k=>$val)
{
2011-06-09 07:03:55 +00:00
if(!$val) continue;
$val = str_replace("`","",$val);
$key = !empty($m[2][$k]) ? $m[2][$k] : $val;
$ret[$key] = array(
'type' => strtoupper($m[1][$k]),
'keyname' => (!empty($m[2][$k])) ? str_replace("`","",$m[2][$k]) : str_replace("`","",$m[3][$k]),
'field' => str_replace($fieldReplace,"",$m[3][$k])
);
}
2011-06-09 07:03:55 +00:00
//Alternate Index detection method.
// eg. `table_id` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
$regex = "/`?([\w]*)`? .*((?:AUTO_INCREMENT))\s?(PRIMARY|UNIQUE|FULLTEXT|FOREIGN)\s?KEY\s?,/i";
2011-06-09 07:03:55 +00:00
preg_match_all($regex,$data,$m);
foreach($m[1] as $k=>$val)
{
if(!$val) continue;
$ret[$val] = array(
'type' => strtoupper($m[3][$k]),
'keyname' => $m[1][$k],
'field' => str_replace($fieldReplace,"",$m[1][$k])
2011-06-09 07:03:55 +00:00
);
}
if($print)
{
e107::getDebug()->log($ret);
}
return $ret;
2011-06-09 07:03:55 +00:00
}
/**
* @param $tbl
* @param $language
* @return false|string
*/
function getSqlData($tbl, $language='')
{
$mes = e107::getMessage();
$prefix = MPREFIX;
if($language)
{
if(!in_array($tbl,$this->sqlLanguageTables[$language]))
{
return FALSE;
}
$prefix .= "lan_".$language."_";
// $mes->addDebug("<h2>Retrieving Language Table Data: ".$prefix . $tbl."</h2>");
}
2017-02-03 13:02:08 -08:00
2013-05-08 17:09:58 -07:00
$sql = e107::getDb();
if(!$sql->isTable($tbl))
{
$mes->addDebug('Missing table on db-verify: '.$tbl);
return false;
}
2017-01-07 11:18:32 -08:00
2013-05-08 17:09:58 -07:00
// mysql_query('SET SQL_QUOTE_SHOW_CREATE = 1');
$qry = 'SHOW CREATE TABLE `' . $prefix . $tbl . "`";
2013-05-08 17:09:58 -07:00
// $z = mysql_query($qry);
$z = $sql->gen($qry);
if($z)
{
2013-05-08 17:09:58 -07:00
// $row = mysql_fetch_row($z);
2016-02-14 12:15:55 -08:00
$row = $sql->fetch('num');
//return $row[1];
2017-02-03 13:02:08 -08:00
return stripslashes($row[1]).';'; // backticks needed.
// return str_replace("`", "", stripslashes($row[1])).';';
}
else
{
$mes->addDebug('Failed: '.$qry);
$this->internalError = true;
return FALSE;
}
}
/**
* @return array
*/
function getSqlLanguages()
{
$sql = e107::getDb();
2020-12-14 16:21:48 -08:00
$list = $sql->tables('lan');
$array = array();
foreach($list as $tb)
{
list($tmp,$lang,$table) = explode("_",$tb,3);
$array[$lang][] = $table;
}
return $array;
}
/**
* @return void
*/
function renderTableSelect()
{
$frm = e107::getForm();
$ns = e107::getRender();
$mes = e107::getMessage();
$text = "
<form method='post' action='".e_SELF.(e_QUERY ? '?'.e_QUERY : '')."' id='core-db-verify-sql-tables-form'>
<fieldset id='core-db-verify-sql-tables'>
<legend>".DBVLAN_14."</legend>
2015-07-18 20:40:14 -07:00
<table class='table table-striped adminlist'>
<colgroup>
<col style='width: 100%'></col>
</colgroup>
<thead>
<tr>
2015-07-18 20:40:14 -07:00
<th class='first form-inline'><label for='check-all-verify-jstarget-verify-table'>".$frm->checkbox_toggle('check-all-verify', 'verify_table', false )." ".LAN_CHECKALL.' | '.LAN_UNCHECKALL."</label></th>
</tr>
</thead>
<tbody>
";
2017-02-03 13:02:08 -08:00
foreach(array_keys($this->sqlFileTables) as $t=>$x)
{
$text .= "
<tr>
2015-07-18 20:40:14 -07:00
<td>".$frm->checkbox('verify_table['.$t.']', $x, false, array('label'=>$x))."</td>
</tr>
";
}
$text .= "
</tbody>
</table>
<div class='buttons-bar center'>
".$frm->admin_button('db_verify', DBVLAN_15)."
2011-06-09 07:03:55 +00:00
".$frm->admin_button('db_tools_back', LAN_BACK, 'back')."
</div>
</fieldset>
</form>
";
$ns->tablerender(DBVLAN_23.' - '.DBVLAN_16, $mes->render().$text);
}
}
/*
2006-12-02 04:36:16 +00:00
function check_tables($what)
{
global $tablines, $table_list, $frm, $emessage;
$cur = 0;
2006-12-02 04:36:16 +00:00
$table_list = "";
read_tables($what);
$fix_active = FALSE; // Flag set as soon as there's a fix - enables 'Fix it' button
$text = "
<form method='post' action='".e_SELF."'>
<fieldset id='core-db-verify-{$what}'>
<legend id='core-db-verify-{$what}-legend'>".DBVLAN_16." - $what ".DBVLAN_18."</legend>
";
foreach(array_keys($table_list) as $k)
{ // $k is the DB table name (less prefix)
$ttcount = 0;
$ttext = "
2012-11-26 14:41:32 -08:00
<table class='table adminlist'>
<colgroup >
<col style='width: 25%'></col>
<col style='width: 25%'></col>
<col style='width: 10%'></col>
<col style='width: 30%'></col>
<col style='width: 10%'></col>
</colgroup>
<thead>
<tr>
<th>".DBVLAN_4.": {$k}</th>
<th>".DBVLAN_5."</th>
<th class='center'>".DBVLAN_6."</th>
<th>".DBVLAN_7."</th>
<th class='center last'>".DBVLAN_19."</th>
</tr>
</thead>
<tbody>
";
$prefix = MPREFIX;
$current_tab = get_current($k, $prefix); // Get list of fields and keys from actual table
unset($fields);
unset($xfields);
$xfield_errors = 0;
if ($current_tab)
{
2010-01-22 20:59:07 +00:00
$lines = explode("\n", $current_tab); // Actual table - create one element of $lines per field or other line of info
$fieldnum = 0;
foreach($tablines[$k] as $x)
{ // $x is a line of the DB definition from the *_sql.php file
$x = str_replace(' ',' ',$x); // Remove double spaces
$fieldnum++;
$ffound = 0;
list($fname, $fparams) = explode(' ', $x, 2); // Pull out first word of definition
if ($fname == 'UNIQUE' || $fname == 'FULLTEXT')
{
2010-01-22 20:59:07 +00:00
list($key, $key1, $keyname, $keyparms) = explode(' ', $x, 4);
$fname = $key." ".$key1." ".$keyname;
$fparams = $keyparms;
}
elseif ($fname == 'KEY')
{
2010-01-22 20:59:07 +00:00
list($key, $keyname, $keyparms) = explode(' ', $x, 3);
$fname = $key." ".$keyname;
$fparams = $keyparms;
}
elseif ($fname == 'PRIMARY')
{ // Nothing to do ATM
}
else
{ // Must be a field name
$fname = str_replace('`','',$fname); // Just remove back ticks if present
}
$fields[$fname] = 1;
$fparams = ltrim(rtrim($fparams));
$fparams = preg_replace("/\r?\n$|\r[^\n]$|,$/", '', $fparams);
if(stristr($k, "lan_") !== FALSE && $cur != 1)
{
$cur = 1;
2006-12-02 04:36:16 +00:00
}
$head_txt = "
<tr>
<td>{$k}</td>
<td>{$fname}
";
if (strpos($fparams, 'KEY') !== FALSE)
{
$head_txt .= " {$fparams} aa";
}
$head_txt .= "</td>
";
$xfieldnum = -1;
$body_txt = '';
foreach($lines as $l)
{
$xfieldnum++;
list($xl, $tmp) = explode("\n", $l, 2); // $tmp should be null
$xl = ltrim(rtrim(stripslashes($xl)));
$xl = preg_replace('/\r?\n$|\r[^\n]$/', '', $xl);
$xl = str_replace(' ',' ',$xl); // Remove double spaces
list($xfname, $xfparams) = explode(" ", $xl, 2); // Field name and the rest
if ($xfname == 'UNIQUE' || $xfname == 'FULLTEXT')
{
list($key, $key1, $keyname, $keyparms) = explode(" ", $xl, 4);
$xfname = $key." ".$key1." ".$keyname;
$xfparams = $keyparms;
}
elseif ($xfname == "KEY")
{
list($key, $keyname, $keyparms) = explode(" ", $xl, 3);
$xfname = $key." ".$keyname;
$xfparams = $keyparms;
}
if ($xfname != "CREATE" && $xfname != ")")
{
$xfields[$xfname] = 1;
}
$xfparams = preg_replace('/,$/', '', $xfparams);
$fparams = preg_replace('/,$/', '', $fparams);
if ($xfname == $fname)
{ // Field names match - or it could be the word 'KEY' and its name which matches
$ffound = 1;
//echo "Field: ".$xfname." Actuals: ".$xfparams." Expected: ".$fparams."<br />";
$xfsplit = explode(' ',$xfparams);
$fsplit = explode(' ',$fparams);
$skip = FALSE;
$i = 0;
$fld_err = FALSE;
foreach ($xfsplit as $xf)
{
if ($skip)
{
$skip = FALSE;
// echo " Unskip: ".$xf."<br />";
}
elseif (strcasecmp(trim($xf),'collate') == 0)
{ // Strip out the collation definition
$skip = TRUE;
// cho "Skip = ".$xf;
}
else
{
// echo "Compare: ".$xf." - ".$fsplit[$i]."<br />";
// Since VARCHAR and CHAR are interchangeable, convert to CHAR (strictly, VARCHAR(3) and smalller becomes CHAR() )
if (stripos($xf,'VARCHAR') === 0) $xf = substr($xf,3);
if (stripos($fsplit[$i],'VARCHAR') === 0) $fsplit[$i] = substr($fsplit[$i],3);
if (strcasecmp(trim($xf),trim($fsplit[$i])) != 0)
{
$fld_err = TRUE;
//echo "Mismatch: ".$xf." - ".$fsplit[$i]."<br />";
}
$i++;
}
}
if ($fld_err)
{
$body_txt .= "
<td class='center middle error'>".DBVLAN_8."</td>
<td>
<strong>".DBVLAN_9."</strong>
<div class='indent'>{$xfparams}</div>
<strong>".DBVLAN_10."</strong>
<div class='indent'>{$fparams}</div>
</td>
<td class='center middle autocheck e-pointer'>".fix_form($k, $fname, $fparams, "alter")."</td>
";
$fix_active = TRUE;
$xfield_errors++;
}
/* FIXME - can't stay if there is no way of fixing the field numbers (e.g. AFTER query)
elseif ($fieldnum != $xfieldnum)
{ // Field numbers different - missing field?
$body_txt .= "
<td class='center middle error'>".DBVLAN_5." ".DBVLAN_8."</td>
<td>
<strong>".DBVLAN_9.": </strong>#{$xfieldnum}
<br />
<strong>".DBVLAN_10.": </strong>#{$fieldnum}
</td>
<td class='center middle'>&nbsp;</td>
";
}
// DISABLED for now (show only errors), could be page setting
// else
// {
// $body_txt .= "
// <td class='center'>OK</td>
// <td>&nbsp;</td>
// <td class='center middle'>&nbsp;</td>
// ";
// }
//
}
} // Finished checking one field
if ($ffound == 0)
{
$prev_fname = $fname; //FIXME - wrong $prev_fname!
$body_txt .= "
<td class='center middle error'>".DBVLAN_11."</td>
<td>
<strong>".DBVLAN_10."</strong>
<div class='indent'>{$fparams}</div>
</td>
<td class='center middle autocheck e-pointer'>".fix_form($k, $fname, $fparams, "insert", $prev_fname)."</td>
";
$fix_active = TRUE;
$xfield_errors++;
}
if($xfield_errors && $body_txt)
{
$ttext .= $head_txt.$body_txt."
</tr>
";
}
2006-12-02 04:36:16 +00:00
}
foreach(array_keys($xfields) as $tf)
{
if (!$fields[$tf] && $k != "user_extended")
{
$fix_active = TRUE;
$xfield_errors++;
$ttext .= "
<tr>
<td>$k</td>
<td>$tf</td>
<td class='center middle'>".DBVLAN_12."</td>
<td>&nbsp;</td>
<td class='center middle autocheck e-pointer'>".fix_form($k, $tf, $fparams, "drop")."</td>
</tr>
";
}
}
}
else
{ // Table Missing.
$ttext .= "
<tr>
<td>{$k}</td>
<td>&nbsp;</td>
<td class='center middle error'>".DBVLAN_13."</td>
<td>&nbsp;</td>
<td class='center middle autocheck e-pointer'>".fix_form($k, $tf, $tablines[$k], "create") . "</td>
</tr>
";
2006-12-02 04:36:16 +00:00
$fix_active = TRUE;
$xfield_errors++;
2006-12-02 04:36:16 +00:00
}
if(!$xfield_errors)
{
//no errors, so no table rows yet
$ttext .= "
<tr>
<td colspan='5' class='center'>Table status OK</td>
</tr>
";
}
$ttext .= "
</tbody>
</table>
<br/>
";
//FIXME - add 'show_if_ok' switch
if($xfield_errors || (!$xfield_errors && varsettrue($_GET['show_if_ok'])))
{
$text .= $ttext;
$ttcount++;
}
2006-12-02 04:36:16 +00:00
}
if(!$fix_active)
{
//Everything should be OK
$emessage->add('DB successfully verified - no problems were found.', E_MESSAGE_SUCCESS);
if(!$ttcount)
{
//very tired and sick of this page, so quick and dirty
$text .= "
<script>
\$('core-db-verify-{$what}-legend').hide();
</script>
";
}
}
if($fix_active)
{
$text .= "
<div class='buttons-bar right'>
".$frm->admin_button('do_fix', DBVLAN_21, 'execute', '', array('id'=>false))."
".$frm->admin_button('check_all', 'jstarget:fix_active', 'action', LAN_CHECKALL, array('id'=>false))."
".$frm->admin_button('uncheck_all', 'jstarget:fix_active', 'action', LAN_UNCHECKALL, array('id'=>false))."
</div>
";
2006-12-02 04:36:16 +00:00
}
foreach(array_keys($_POST) as $j)
{
$match = array();
if (preg_match('/table_(.*)/', $j, $match))
{
$lx = $match[1];
$text .= "<div><input type='hidden' name='table_{$lx}' value='1' /></div>\n";
2006-12-02 04:36:16 +00:00
}
}
$text .= "
</fieldset>
<div class='buttons-bar center'>
".$frm->admin_button('back', DBVLAN_17, 'back')."
</div>
</form>
";
2006-12-02 04:36:16 +00:00
return $text;
}
global $table_list;
// -------------------- Table Fixing ------------------------------
if(isset($_POST['do_fix']))
{
//$emessage->add(DBVLAN_20);
foreach( $_POST['fix_active'] as $key=>$val)
{
2006-12-02 04:36:16 +00:00
if (MAGIC_QUOTES_GPC == TRUE)
{
2006-12-02 04:36:16 +00:00
$table = stripslashes($_POST['fix_table'][$key][0]);
$newval = stripslashes($_POST['fix_newval'][$key][0]);
$mode = stripslashes($_POST['fix_mode'][$key][0]);
$after = stripslashes($_POST['fix_after'][$key][0]);
}
else
{
2006-12-02 04:36:16 +00:00
$table = $_POST['fix_table'][$key][0];
$newval = $_POST['fix_newval'][$key][0];
$mode = $_POST['fix_mode'][$key][0];
$after = $_POST['fix_after'][$key][0];
}
$field= $key;
switch($mode)
{
case 'alter':
$query = "ALTER TABLE `".MPREFIX.$table."` CHANGE `$field` `$field` $newval";
break;
case 'insert':
if($after) $after = " AFTER {$after}";
$query = "ALTER TABLE `".MPREFIX.$table."` ADD `$field` $newval{$after}";
break;
case 'drop':
$query = "ALTER TABLE `".MPREFIX.$table."` DROP `$field` ";
break;
case 'index':
$query = "ALTER TABLE `".MPREFIX.$table."` ADD INDEX `$field` ($newval)";
break;
case 'indexalt':
$query = "ALTER TABLE `".MPREFIX.$table."` ADD $field ($newval)";
break;
case 'indexdrop':
$query = "ALTER TABLE `".MPREFIX.$table."` DROP INDEX `$field`";
break;
case 'create':
$query = "CREATE TABLE `".MPREFIX.$table."` ({$newval}";
if (!preg_match('#.*?\s+?(?:TYPE|ENGINE)\s*\=\s*(.*?);#is', $newval))
{
$query .= ') TYPE=MyISAM;';
}
break;
2006-12-02 04:36:16 +00:00
}
return $query;
//FIXME - db handler!!!
if(mysql_query($query)) $emessage->add(LAN_UPDATED.' [&nbsp;'.$query.'&nbsp;]', E_MESSAGE_SUCCESS);
else
{
$emessage->add(LAN_UPDATED_FAILED.' [&nbsp;'.$query.'&nbsp;]', E_MESSAGE_WARNING);
if(mysql_errno())
{
$emessage->add('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SQL #'.mysql_errno().': '.mysql_error(), E_MESSAGE_WARNING);
}
2006-12-02 04:36:16 +00:00
}
}
}
2006-12-02 04:36:16 +00:00
$text = "
<form method='post' action='".e_SELF.(e_QUERY ? '?'.e_QUERY : '')."' id='core-db-verify-sql-tables-form'>
<fieldset id='core-db-verify-sql-tables'>
<legend>".DBVLAN_14."</legend>
2012-11-26 14:41:32 -08:00
<table class='table adminlist'>
<colgroup>
<col style='width: 100%'></col>
</colgroup>
<thead>
<tr>
<th class='last'>".$frm->checkbox_toggle('check-all-verify', 'table_').LAN_CHECKALL.' | '.LAN_UNCHECKALL."</th>
</tr>
</thead>
<tbody>
";
foreach(array_keys($tables) as $x) {
$text .= "
<tr>
<td>
".$frm->checkbox('table_'.$x, $x).$frm->label($x, 'table_'.$x, $x)."
</td>
</tr>
";
}
2006-12-02 04:36:16 +00:00
$text .= "
</tbody>
</table>
<div class='buttons-bar center'>
".$frm->admin_button('db_verify', DBVLAN_15)."
".$frm->admin_button('db_tools_back', DBVLAN_17, 'back')."
</div>
</fieldset>
</form>
";
$e107->ns->tablerender(DBVLAN_23.' - '.DBVLAN_16, $emessage->render().$text);
require_once(e_ADMIN."footer.php");
exit;
2006-12-02 04:36:16 +00:00
// --------------------------------------------------------------
function fix_form($table,$field, $newvalue,$mode,$after ='')
{
global $frm;
if($mode == 'create')
{
2006-12-02 04:36:16 +00:00
$newvalue = implode("\n",$newvalue);
$field = $table; // Value for $field may be rubbish!
2006-12-02 04:36:16 +00:00
}
else
{
if(stristr($field, 'KEY ') !== FALSE)
{
$field = chop(str_replace('KEY ','',$field));
$mode = ($mode == 'drop') ? 'indexdrop' : 'index';
$search = array('(', ')');
$newvalue = str_replace($search,'',$newvalue);
$after = '';
}
if($mode == 'index' && (stristr($field, 'FULLTEXT ') !== FALSE || stristr($field, 'UNIQUE ') !== FALSE))
{
$mode = 'indexalt';
}
elseif($mode == 'indexdrop' && (stristr($field, 'FULLTEXT ') !== FALSE || stristr($field, 'UNIQUE ') !== FALSE))
{
$field = trim(str_replace(array('FULLTEXT ', 'UNIQUE '), '', $field));
}
$field = trim($field, '`');
}
2006-12-02 04:36:16 +00:00
$text .= "\n\n";
$text .= $frm->checkbox("fix_active[$field][]", 1, false, array('id'=>false));
2006-12-02 04:36:16 +00:00
$text .= "<input type='hidden' name=\"fix_newval[$field][]\" value=\"$newvalue\" />\n";
$text .= "<input type='hidden' name=\"fix_table[$field][]\" value=\"$table\" />\n";
$text .= "<input type='hidden' name=\"fix_mode[$field][]\" value=\"$mode\" />\n";
$text .= ($after) ? "<input type='hidden' name=\"fix_after[$field][]\" value=\"$after\" />\n" : "";
$text .= "\n\n";
2006-12-02 04:36:16 +00:00
return $text;
}
function table_list()
{
2006-12-02 04:36:16 +00:00
// grab default language lists.
global $mySQLdefaultdb;
$exclude[] = "banlist"; $exclude[] = "banner";
$exclude[] = "cache"; $exclude[] = "core";
$exclude[] = "online"; $exclude[] = "parser";
$exclude[] = "plugin"; $exclude[] = "user";
$exclude[] = "upload"; $exclude[] = "userclass_classes";
$exclude[] = "rbinary"; $exclude[] = "session";
$exclude[] = "tmp"; $exclude[] = "flood";
$exclude[] = "stat_info"; $exclude[] = "stat_last";
$exclude[] = "submit_news"; $exclude[] = "rate";
$exclude[] = "stat_counter";$exclude[] = "user_extended";
2009-11-23 00:52:27 +00:00
$exclude[] = "user_extended_struct";
2006-12-02 04:36:16 +00:00
$exclude[] = "pm_messages";
$exclude[] = "pm_blocks";
2009-11-23 00:52:27 +00:00
$replace = array();
$lanlist = explode(",",e_LANLIST);
foreach($lanlist as $lang)
{
if($lang != $pref['sitelanguage'])
{
$replace[] = "lan_".strtolower($lang)."_";
}
}
2006-12-02 04:36:16 +00:00
$tables = mysql_list_tables($mySQLdefaultdb);
while (list($temp) = mysql_fetch_array($tables))
{
2006-12-02 04:36:16 +00:00
$prefix = MPREFIX."lan_";
$match = array();
2009-11-23 00:52:27 +00:00
if(strpos($temp,$prefix)!==FALSE)
{
2009-11-23 00:52:27 +00:00
$e107tab = str_replace(MPREFIX, "", $temp);
$core = str_replace($replace,"",$e107tab);
if (str_replace($exclude, "", $e107tab))
{
2006-12-02 04:36:16 +00:00
$tabs[$core] = $e107tab;
2009-11-23 00:52:27 +00:00
}
2006-12-02 04:36:16 +00:00
}
}
return $tabs;
}
*/
2006-12-02 04:36:16 +00:00
2020-06-05 11:34:17 -07:00