initial commit

This commit is contained in:
Chris Sewell
2012-11-28 03:55:08 -05:00
parent 7adb399b2e
commit cf140a2e97
3247 changed files with 492437 additions and 0 deletions

View File

@ -0,0 +1,3 @@
# This folder does not require access over HTTP
# (the following directive denies access by default)
Order allow,deny

View File

@ -0,0 +1,347 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* A simple rules engine, that parses and executes the rules in advisory_rules.txt. Adjusted to phpMyAdmin
*
*
* @package PhpMyAdmin
*/
class Advisor
{
var $variables;
var $parseResult;
var $runResult;
function run()
{
// HowTo: A simple Advisory system in 3 easy steps.
// Step 1: Get some variables to evaluate on
$this->variables = array_merge(
PMA_DBI_fetch_result('SHOW GLOBAL STATUS', 0, 1),
PMA_DBI_fetch_result('SHOW GLOBAL VARIABLES', 0, 1)
);
if (PMA_DRIZZLE) {
$this->variables = array_merge(
$this->variables,
PMA_DBI_fetch_result(
"SELECT concat('Com_', variable_name), variable_value
FROM data_dictionary.GLOBAL_STATEMENTS", 0, 1
)
);
}
// Add total memory to variables as well
include_once 'libraries/sysinfo.lib.php';
$sysinfo = getSysInfo();
$memory = $sysinfo->memory();
$this->variables['system_memory'] = $memory['MemTotal'];
// Step 2: Read and parse the list of rules
$this->parseResult = $this->parseRulesFile();
// Step 3: Feed the variables to the rules and let them fire. Sets $runResult
$this->runRules();
return array(
'parse' => array('errors' => $this->parseResult['errors']),
'run' => $this->runResult
);
}
function runRules()
{
$this->runResult = array(
'fired' => array(),
'notfired' => array(),
'unchecked'=> array(),
'errors' => array()
);
foreach ($this->parseResult['rules'] as $rule) {
$this->variables['value'] = 0;
$precond = true;
if (isset($rule['precondition'])) {
try {
$precond = $this->ruleExprEvaluate($rule['precondition']);
} catch (Exception $e) {
$this->runResult['errors'][] = 'Failed evaluating precondition for rule \''
. $rule['name'] . '\'. PHP threw following error: '
. $e->getMessage();
continue;
}
}
if (! $precond) {
$this->addRule('unchecked', $rule);
} else {
try {
$value = $this->ruleExprEvaluate($rule['formula']);
} catch(Exception $e) {
$this->runResult['errors'][] = 'Failed calculating value for rule \''
. $rule['name'] . '\'. PHP threw following error: '
. $e->getMessage();
continue;
}
$this->variables['value'] = $value;
try {
if ($this->ruleExprEvaluate($rule['test'])) {
$this->addRule('fired', $rule);
} else {
$this->addRule('notfired', $rule);
}
} catch(Exception $e) {
$this->runResult['errors'][] = 'Failed running test for rule \''
. $rule['name'] . '\'. PHP threw following error: '
. $e->getMessage();
}
}
}
return true;
}
/**
* Escapes percent string to be used in format string.
*
* @param string $str string to escape
*
* @return string
*/
function escapePercent($str)
{
return preg_replace('/%( |,|\.|$|\(|\)|<|>)/', '%%\1', $str);
}
/**
* Wrapper function for translating.
*
* @param string $str
* @param mixed $param
*
* @return string
*/
function translate($str, $param = null)
{
if (is_null($param)) {
return sprintf(_gettext(Advisor::escapePercent($str)));
} else {
$printf = 'sprintf("' . _gettext(Advisor::escapePercent($str)) . '",';
return $this->ruleExprEvaluate(
$printf . $param . ')',
strlen($printf)
);
}
}
/**
* Splits justification to text and formula.
*
* @param string $rule
*
* @return array
*/
function splitJustification($rule)
{
$jst = preg_split('/\s*\|\s*/', $rule['justification'], 2);
if (count($jst) > 1) {
return array($jst[0], $jst[1]);
}
return array($rule['justification']);
}
// Adds a rule to the result list
function addRule($type, $rule)
{
switch($type) {
case 'notfired':
case 'fired':
$jst = Advisor::splitJustification($rule);
if (count($jst) > 1) {
try {
/* Translate */
$str = $this->translate($jst[0], $jst[1]);
} catch (Exception $e) {
$this->runResult['errors'][] = sprintf(
__('Failed formatting string for rule \'%s\'. PHP threw following error: %s'),
$rule['name'],
$e->getMessage()
);
return;
}
$rule['justification'] = $str;
} else {
$rule['justification'] = $this->translate($rule['justification']);
}
$rule['name'] = $this->translate($rule['name']);
$rule['issue'] = $this->translate($rule['issue']);
// Replaces {server_variable} with 'server_variable'
// linking to server_variables.php
$rule['recommendation'] = preg_replace(
'/\{([a-z_0-9]+)\}/Ui',
'<a href="server_variables.php?' . PMA_generate_common_url() . '#filter=\1">\1</a>',
$this->translate($rule['recommendation'])
);
// Replaces external Links with PMA_linkURL() generated links
$rule['recommendation'] = preg_replace(
'#href=("|\')(https?://[^\1]+)\1#ie',
'\'href="\' . PMA_linkURL("\2") . \'"\'',
$rule['recommendation']
);
break;
}
$this->runResult[$type][] = $rule;
}
private function ruleExprEvaluate_var1($matches)
{
// '/fired\s*\(\s*(\'|")(.*)\1\s*\)/Uie'
return '1'; //isset($this->runResult[\'fired\']
}
private function ruleExprEvaluate_var2($matches)
{
// '/\b(\w+)\b/e'
return isset($this->variables[$matches[1]])
? (is_numeric($this->variables[$matches[1]])
? $this->variables[$matches[1]]
: '"'.$this->variables[$matches[1]].'"')
: $matches[1];
}
// Runs a code expression, replacing variable names with their respective values
// ignoreUntil: if > 0, it doesn't replace any variables until that string
// position, but still evaluates the whole expr
function ruleExprEvaluate($expr, $ignoreUntil = 0)
{
if ($ignoreUntil > 0) {
$exprIgnore = substr($expr, 0, $ignoreUntil);
$expr = substr($expr, $ignoreUntil);
}
$expr = preg_replace_callback(
'/fired\s*\(\s*(\'|")(.*)\1\s*\)/Ui',
array($this, 'ruleExprEvaluate_var1'),
$expr
);
$expr = preg_replace_callback(
'/\b(\w+)\b/',
array($this, 'ruleExprEvaluate_var2'),
$expr
);
if ($ignoreUntil > 0) {
$expr = $exprIgnore . $expr;
}
$value = 0;
$err = 0;
ob_start();
eval('$value = '.$expr.';');
$err = ob_get_contents();
ob_end_clean();
if ($err) {
throw new Exception(
strip_tags($err) . '<br />Executed code: $value = ' . $expr . ';'
);
}
return $value;
}
// Reads the rule file into an array, throwing errors messages on syntax errors
function parseRulesFile()
{
$file = file('libraries/advisory_rules.txt');
$errors = array();
$rules = array();
$ruleSyntax = array('name', 'formula', 'test', 'issue', 'recommendation', 'justification');
$numRules = count($ruleSyntax);
$numLines = count($file);
$j = -1;
$ruleLine = -1;
for ($i = 0; $i<$numLines; $i++) {
$line = $file[$i];
if ($line[0] == '#' || $line[0] == "\n") {
continue;
}
// Reading new rule
if (substr($line, 0, 4) == 'rule') {
if ($ruleLine > 0) {
$errors[] = 'Invalid rule declaration on line ' . ($i+1)
. ', expected line ' . $ruleSyntax[$ruleLine++]
. ' of previous rule' ;
continue;
}
if (preg_match("/rule\s'(.*)'( \[(.*)\])?$/", $line, $match)) {
$ruleLine = 1;
$j++;
$rules[$j] = array( 'name' => $match[1]);
if (isset($match[3])) {
$rules[$j]['precondition'] = $match[3];
}
} else {
$errors[] = 'Invalid rule declaration on line '.($i+1);
}
continue;
} else {
if ($ruleLine == -1) {
$errors[] = 'Unexpected characters on line '.($i+1);
}
}
// Reading rule lines
if ($ruleLine > 0) {
if (!isset($line[0])) {
continue; // Empty lines are ok
}
// Non tabbed lines are not
if ($line[0] != "\t") {
$errors[] = 'Unexpected character on line '.($i+1).'
. Expected tab, but found \''.$line[0].'\'';
continue;
}
$rules[$j][$ruleSyntax[$ruleLine++]] = chop(substr($line, 1));
}
// Rule complete
if ($ruleLine == $numRules) {
$ruleLine = -1;
}
}
return array('rules' => $rules, 'errors' => $errors);
}
}
function PMA_bytime($num, $precision)
{
$per = '';
if ($num >= 1) { // per second
$per = __('per second');
} elseif ($num*60 >= 1) { // per minute
$num = $num*60;
$per = __('per minute');
} elseif ($num*60*60 >=1 ) { // per hour
$num = $num*60*60;
$per = __('per hour');
} else {
$num = $num*60*60*24;
$per = __('per day');
}
$num = round($num, $precision);
if ($num == 0) {
$num = '<' . pow(10, -$precision);
}
return "$num $per";
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,367 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds class PMA_Error
*
* @package PhpMyAdmin
*/
/**
* base class
*/
require_once './libraries/Message.class.php';
/**
* a single error
*
* @package PhpMyAdmin
*/
class PMA_Error extends PMA_Message
{
/**
* Error types
*
* @var array
*/
static public $errortype = array (
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice',
E_DEPRECATED => 'Deprecation Notice',
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
);
/**
* Error levels
*
* @var array
*/
static public $errorlevel = array (
E_ERROR => 'error',
E_WARNING => 'error',
E_PARSE => 'error',
E_NOTICE => 'notice',
E_CORE_ERROR => 'error',
E_CORE_WARNING => 'error',
E_COMPILE_ERROR => 'error',
E_COMPILE_WARNING => 'error',
E_USER_ERROR => 'error',
E_USER_WARNING => 'error',
E_USER_NOTICE => 'notice',
E_STRICT => 'notice',
E_DEPRECATED => 'notice',
E_RECOVERABLE_ERROR => 'error',
);
/**
* The file in which the error occured
*
* @var string
*/
protected $_file = '';
/**
* The line in which the error occured
*
* @var integer
*/
protected $_line = 0;
/**
* Holds the backtrace for this error
*
* @var array
*/
protected $_backtrace = array();
/**
* Unique id
*
* @var string
*/
protected $_hash = null;
/**
* Constructor
*
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
*/
public function __construct($errno, $errstr, $errfile, $errline)
{
$this->setNumber($errno);
$this->setMessage($errstr, false);
$this->setFile($errfile);
$this->setLine($errline);
$backtrace = debug_backtrace();
// remove last two calls: debug_backtrace() and handleError()
unset($backtrace[0]);
unset($backtrace[1]);
$this->setBacktrace($backtrace);
}
/**
* sets PMA_Error::$_backtrace
*
* @param array $backtrace
*/
public function setBacktrace($backtrace)
{
$this->_backtrace = $backtrace;
}
/**
* sets PMA_Error::$_line
*
* @param integer $line
*/
public function setLine($line)
{
$this->_line = $line;
}
/**
* sets PMA_Error::$_file
*
* @param string $file
*/
public function setFile($file)
{
$this->_file = PMA_Error::relPath($file);
}
/**
* returns unique PMA_Error::$_hash, if not exists it will be created
*
* @param string $file
* @return string PMA_Error::$_hash
*/
public function getHash()
{
try {
$backtrace = serialize($this->getBacktrace());
} catch(Exception $e){
$backtrace = '';
}
if (null === $this->_hash) {
$this->_hash = md5(
$this->getNumber() .
$this->getMessage() .
$this->getFile() .
$this->getLine() .
$backtrace
);
}
return $this->_hash;
}
/**
* returns PMA_Error::$_backtrace
*
* @return array PMA_Error::$_backtrace
*/
public function getBacktrace()
{
return $this->_backtrace;
}
/**
* returns PMA_Error::$_file
*
* @return string PMA_Error::$_file
*/
public function getFile()
{
return $this->_file;
}
/**
* returns PMA_Error::$_line
*
* @return integer PMA_Error::$_line
*/
public function getLine()
{
return $this->_line;
}
/**
* returns type of error
*
* @return string type of error
*/
public function getType()
{
return PMA_Error::$errortype[$this->getNumber()];
}
/**
* returns level of error
*
* @return string level of error
*/
public function getLevel()
{
return PMA_Error::$errorlevel[$this->getNumber()];
}
/**
* returns title prepared for HTML Title-Tag
*
* @return string HTML escaped and truncated title
*/
public function getHtmlTitle()
{
return htmlspecialchars(substr($this->getTitle(), 0, 100));
}
/**
* returns title for error
*
* @return string
*/
public function getTitle()
{
return $this->getType() . ': ' . $this->getMessage();
}
/**
* Display HTML backtrace
*
*/
public function displayBacktrace()
{
foreach ($this->getBacktrace() as $step) {
echo PMA_Error::relPath($step['file']) . '#' . $step['line'] . ': ';
if (isset($step['class'])) {
echo $step['class'] . $step['type'];
}
echo $step['function'] . '(';
if (isset($step['args']) && (count($step['args']) > 1)) {
echo "<br />\n";
foreach ($step['args'] as $arg) {
echo "\t";
$this->displayArg($arg, $step['function']);
echo ',' . "<br />\n";
}
} elseif (isset($step['args']) && (count($step['args']) > 0)) {
foreach ($step['args'] as $arg) {
$this->displayArg($arg, $step['function']);
}
}
echo ')' . "<br />\n";
}
}
/**
* Display a single function argument
* if $function is one of include/require the $arg is converted te relative path
*
* @param string $arg
* @param string $function
*/
protected function displayArg($arg, $function)
{
$include_functions = array(
'include',
'include_once',
'require',
'require_once',
);
if (in_array($function, $include_functions)) {
echo PMA_Error::relPath($arg);
} elseif (is_scalar($arg)) {
echo gettype($arg) . ' ' . htmlspecialchars($arg);
} else {
echo gettype($arg);
}
}
/**
* Displays the error in HTML
*
*/
public function display()
{
echo '<div class="' . $this->getLevel() . '">';
if (! $this->isUserError()) {
echo '<strong>' . $this->getType() . '</strong>';
echo ' in ' . $this->getFile() . '#' . $this->getLine();
echo "<br />\n";
}
echo $this->getMessage();
if (! $this->isUserError()) {
echo "<br />\n";
echo "<br />\n";
echo "<strong>Backtrace</strong><br />\n";
echo "<br />\n";
echo $this->displayBacktrace();
}
echo '</div>';
$this->isDisplayed(true);
}
/**
* whether this error is a user error
*
* @return boolean
*/
public function isUserError()
{
return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE);
}
/**
* return short relative path to phpMyAdmin basedir
*
* prevent path disclusore in error message,
* and make users feel save to submit error reports
*
* @static
* @param string $dest path to be shorten
* @return string shortened path
*/
static function relPath($dest)
{
$dest = realpath($dest);
if (substr(PHP_OS, 0, 3) == 'WIN') {
$path_separator = '\\';
} else {
$path_separator = '/';
}
$Ahere = explode($path_separator, realpath(dirname(__FILE__) . $path_separator . '..'));
$Adest = explode($path_separator, $dest);
$result = '.';
// && count ($Adest)>0 && count($Ahere)>0 )
while (implode($path_separator, $Adest) != implode($path_separator, $Ahere)) {
if (count($Ahere) > count($Adest)) {
array_pop($Ahere);
$result .= $path_separator . '..';
} else {
array_pop($Adest);
}
}
$path = $result . str_replace(implode($path_separator, $Adest), '', $dest);
return str_replace($path_separator . $path_separator, $path_separator, $path);
}
}
?>

View File

@ -0,0 +1,353 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds class PMA_Error_Handler
*
* @package PhpMyAdmin
*/
/**
*
*/
require_once './libraries/Error.class.php';
/**
* handling errors
*
* @package PhpMyAdmin
*/
class PMA_Error_Handler
{
/**
* holds errors to be displayed or reported later ...
*
* @var array of PMA_Error
*/
protected $_errors = array();
/**
* Constructor - set PHP error handler
*
*/
public function __construct()
{
set_error_handler(array($this, 'handleError'));
}
/**
* Destructor
*
* stores errors in session
*
*/
public function __destruct()
{
if (isset($_SESSION)) {
if (! isset($_SESSION['errors'])) {
$_SESSION['errors'] = array();
}
if ($GLOBALS['cfg']['Error_Handler']['gather']) {
// remember all errors
$_SESSION['errors'] = array_merge($_SESSION['errors'], $this->_errors);
} else {
// remember only not displayed errors
foreach ($this->_errors as $key => $error) {
/**
* We don't want to store all errors here as it would explode user
* session. In case you want them all set
* $GLOBALS['cfg']['Error_Handler']['gather'] to true
*/
if (count($_SESSION['errors']) >= 20) {
$error = new PMA_Error(0, __('Too many error messages, some are not displayed.'), __FILE__, __LINE__);
$_SESSION['errors'][$error->getHash()] = $error;
}
if (($error instanceof PMA_Error) && ! $error->isDisplayed()) {
$_SESSION['errors'][$key] = $error;
}
}
}
}
}
/**
* returns array with all errors
*
* @return array PMA_Error_Handler::$_errors
*/
protected function getErrors()
{
$this->_checkSavedErrors();
return $this->_errors;
}
/**
* Error handler - called when errors are triggered/occured
*
* The following error types cannot be handled with a user defined function:
* E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR,
* E_COMPILE_WARNING,
* and most of E_STRICT raised in the file where set_error_handler() is called.
*
* Do not use the context parameter as we want to avoid storing the
* complete $GLOBALS inside $_SESSION['errors']
*
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
*/
public function handleError($errno, $errstr, $errfile, $errline)
{
// create error object
$error = new PMA_Error($errno, htmlspecialchars($errstr), $errfile, $errline);
// do not repeat errors
$this->_errors[$error->getHash()] = $error;
switch ($error->getNumber()) {
case E_USER_NOTICE:
case E_USER_WARNING:
case E_STRICT:
case E_DEPRECATED:
case E_NOTICE:
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
// just collect the error
// display is called from outside
break;
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
default:
// FATAL error, dislay it and exit
$this->_dispFatalError($error);
exit;
break;
}
}
/**
* log error to configured log facility
*
* @todo finish!
* @param PMA_Error $error
* @return bool
*/
protected function _logError($error)
{
return error_log($error->getMessage());
}
/**
* trigger a custom error
*
* @param string $errorInfo
* @param integer $errorNumber
* @param string $file
* @param integer $line
*/
public function triggerError($errorInfo, $errorNumber = null, $file = null, $line = null)
{
// we could also extract file and line from backtrace and call handleError() directly
trigger_error($errorInfo, $errorNumber);
}
/**
* display fatal error and exit
*
* @param PMA_Error $error
*/
protected function _dispFatalError($error)
{
if (! headers_sent()) {
$this->_dispPageStart($error);
}
$error->display();
$this->_dispPageEnd();
exit;
}
/**
* display the whole error page with all errors
*
*/
public function dispErrorPage()
{
if (! headers_sent()) {
$this->_dispPageStart();
}
$this->dispAllErrors();
$this->_dispPageEnd();
}
/**
* display user errors not displayed
*
*/
public function dispUserErrors()
{
foreach ($this->getErrors() as $error) {
if ($error->isUserError() && ! $error->isDisplayed()) {
$error->display();
}
}
}
/**
* display HTML header
*
* @param PMA_error $error
*/
protected function _dispPageStart($error = null)
{
echo '<html><head><title>';
if ($error) {
echo $error->getTitle();
} else {
echo 'phpMyAdmin error reporting page';
}
echo '</title></head>';
}
/**
* display HTML footer
*
*/
protected function _dispPageEnd()
{
echo '</body></html>';
}
/**
* display all errors regardless already displayed or user errors
*
*/
public function dispAllErrors()
{
foreach ($this->getErrors() as $error) {
$error->display();
}
}
/**
* display errors not displayed
*
*/
public function dispErrors()
{
if ($GLOBALS['cfg']['Error_Handler']['display']) {
foreach ($this->getErrors() as $error) {
if ($error instanceof PMA_Error) {
if (! $error->isDisplayed()) {
$error->display();
}
} else {
var_dump($error);
}
}
} else {
$this->dispUserErrors();
}
}
/**
* look in session for saved errors
*
*/
protected function _checkSavedErrors()
{
if (isset($_SESSION['errors'])) {
// restore saved errors
foreach ($_SESSION['errors'] as $hash => $error) {
if ($error instanceof PMA_Error && ! isset($this->_errors[$hash])) {
$this->_errors[$hash] = $error;
}
}
//$this->_errors = array_merge($_SESSION['errors'], $this->_errors);
// delet stored errors
$_SESSION['errors'] = array();
unset($_SESSION['errors']);
}
}
/**
* return count of errors
*
* @return integer number of errors occoured
*/
public function countErrors()
{
return count($this->getErrors());
}
/**
* return count of user errors
*
* @return integer number of user errors occoured
*/
public function countUserErrors()
{
$count = 0;
if ($this->countErrors()) {
foreach ($this->getErrors() as $error) {
if ($error->isUserError()) {
$count++;
}
}
}
return $count;
}
/**
* whether use errors occured or not
*
* @return boolean
*/
public function hasUserErrors()
{
return (bool) $this->countUserErrors();
}
/**
* whether errors occured or not
*
* @return boolean
*/
public function hasErrors()
{
return (bool) $this->countErrors();
}
/**
* number of errors to be displayed
*
* @return integer number of errors to be displayed
*/
public function countDisplayErrors()
{
if ($GLOBALS['cfg']['Error_Handler']['display']) {
return $this->countErrors();
} else {
return $this->countUserErrors();
}
}
/**
* whether there are errors to display or not
*
* @return boolean
*/
public function hasDisplayErrors()
{
return (bool) $this->countDisplayErrors();
}
}
?>

View File

@ -0,0 +1,827 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* file upload functions
*
* @package PhpMyAdmin
*/
/**
*
* @todo when uploading a file into a blob field, should we also consider using
* chunks like in import? UPDATE `table` SET `field` = `field` + [chunk]
* @package PhpMyAdmin
*/
class PMA_File
{
/**
* @var string the temporary file name
* @access protected
*/
var $_name = null;
/**
* @var string the content
* @access protected
*/
var $_content = null;
/**
* @var string the error message
* @access protected
*/
var $_error_message = '';
/**
* @var bool whether the file is temporary or not
* @access protected
*/
var $_is_temp = false;
/**
* @var string type of compression
* @access protected
*/
var $_compression = null;
/**
* @var integer
*/
var $_offset = 0;
/**
* @var integer size of chunk to read with every step
*/
var $_chunk_size = 32768;
/**
* @var resource file handle
*/
var $_handle = null;
/**
* @var boolean whether to decompress content before returning
*/
var $_decompress = false;
/**
* @var string charset of file
*/
var $_charset = null;
/**
* @staticvar string most recent BLOB repository reference
*/
static $_recent_bs_reference = null;
/**
* constructor
*
* @access public
* @param string $name file name
*/
function __construct($name = false)
{
if ($name) {
$this->setName($name);
}
}
/**
* destructor
*
* @see PMA_File::cleanUp()
* @access public
*/
function __destruct()
{
$this->cleanUp();
}
/**
* deletes file if it is temporary, usally from a moved upload file
*
* @access public
* @return boolean success
*/
function cleanUp()
{
if ($this->isTemp()) {
return $this->delete();
}
return true;
}
/**
* deletes the file
*
* @access public
* @return boolean success
*/
function delete()
{
return unlink($this->getName());
}
/**
* checks or sets the temp flag for this file
* file objects with temp flags are deleted with object destruction
*
* @access public
* @param boolean sets the temp flag
* @return boolean PMA_File::$_is_temp
*/
function isTemp($is_temp = null)
{
if (null !== $is_temp) {
$this->_is_temp = (bool) $is_temp;
}
return $this->_is_temp;
}
/**
* accessor
*
* @access public
* @param string $name file name
*/
function setName($name)
{
$this->_name = trim($name);
}
/**
* @access public
* @return string binary file content
*/
function getContent($as_binary = true, $offset = 0, $length = null)
{
if (null === $this->_content) {
if ($this->isUploaded() && ! $this->checkUploadedFile()) {
return false;
}
if (! $this->isReadable()) {
return false;
}
if (function_exists('file_get_contents')) {
$this->_content = file_get_contents($this->getName());
} elseif ($size = filesize($this->getName())) {
$this->_content = fread(fopen($this->getName(), 'rb'), $size);
}
}
if (! empty($this->_content) && $as_binary) {
return '0x' . bin2hex($this->_content);
}
if (null !== $length) {
return substr($this->_content, $offset, $length);
} elseif ($offset > 0) {
return substr($this->_content, $offset);
}
return $this->_content;
}
/**
* @access public
* @return bool
*/
function isUploaded()
{
return is_uploaded_file($this->getName());
}
/**
* accessor
*
* @access public
* @return string PMA_File::$_name
*/
function getName()
{
return $this->_name;
}
/**
* @access public
* @param string name of file uploaded
* @return boolean success
*/
function setUploadedFile($name)
{
$this->setName($name);
if (! $this->isUploaded()) {
$this->setName(null);
$this->_error_message = __('File was not an uploaded file.');
return false;
}
return true;
}
/**
* @access public
* @param string $key the md5 hash of the column name
* @param string $rownumber
* @return boolean success
*/
function setUploadedFromTblChangeRequest($key, $rownumber)
{
if (! isset($_FILES['fields_upload']) || empty($_FILES['fields_upload']['name']['multi_edit'][$rownumber][$key])) {
return false;
}
$file = PMA_File::fetchUploadedFromTblChangeRequestMultiple($_FILES['fields_upload'], $rownumber, $key);
// for blobstreaming
$is_bs_upload = false;
// check if this field requires a repository upload
if (isset($_REQUEST['upload_blob_repo']['multi_edit'][$rownumber][$key])) {
$is_bs_upload = ($_REQUEST['upload_blob_repo']['multi_edit'][$rownumber][$key] == "on") ? true : false;
}
// if request is an upload to the BLOB repository
if ($is_bs_upload) {
$bs_db = $_REQUEST['db'];
$bs_table = $_REQUEST['table'];
$tmp_filename = $file['tmp_name'];
$tmp_file_type = $file['type'];
if (! $tmp_file_type) {
$tmp_file_type = null;
}
if (! $bs_db || ! $bs_table) {
$this->_error_message = __('Unknown error while uploading.');
return false;
}
$blob_url = PMA_BS_UpLoadFile($bs_db, $bs_table, $tmp_file_type, $tmp_filename);
PMA_File::setRecentBLOBReference($blob_url);
} // end if ($is_bs_upload)
// check for file upload errors
switch ($file['error']) {
// we do not use the PHP constants here cause not all constants
// are defined in all versions of PHP - but the correct constants names
// are given as comment
case 0: //UPLOAD_ERR_OK:
return $this->setUploadedFile($file['tmp_name']);
break;
case 4: //UPLOAD_ERR_NO_FILE:
break;
case 1: //UPLOAD_ERR_INI_SIZE:
$this->_error_message = __('The uploaded file exceeds the upload_max_filesize directive in php.ini.');
break;
case 2: //UPLOAD_ERR_FORM_SIZE:
$this->_error_message = __('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.');
break;
case 3: //UPLOAD_ERR_PARTIAL:
$this->_error_message = __('The uploaded file was only partially uploaded.');
break;
case 6: //UPLOAD_ERR_NO_TMP_DIR:
$this->_error_message = __('Missing a temporary folder.');
break;
case 7: //UPLOAD_ERR_CANT_WRITE:
$this->_error_message = __('Failed to write file to disk.');
break;
case 8: //UPLOAD_ERR_EXTENSION:
$this->_error_message = __('File upload stopped by extension.');
break;
default:
$this->_error_message = __('Unknown error in file upload.');
} // end switch
return false;
}
/**
* strips some dimension from the multi-dimensional array from $_FILES
*
* <code>
* $file['name']['multi_edit'][$rownumber][$key] = [value]
* $file['type']['multi_edit'][$rownumber][$key] = [value]
* $file['size']['multi_edit'][$rownumber][$key] = [value]
* $file['tmp_name']['multi_edit'][$rownumber][$key] = [value]
* $file['error']['multi_edit'][$rownumber][$key] = [value]
*
* // becomes:
*
* $file['name'] = [value]
* $file['type'] = [value]
* $file['size'] = [value]
* $file['tmp_name'] = [value]
* $file['error'] = [value]
* </code>
*
* @access public
* @static
* @param array $file the array
* @param string $rownumber
* @param string $key
* @return array
*/
function fetchUploadedFromTblChangeRequestMultiple($file, $rownumber, $key)
{
$new_file = array(
'name' => $file['name']['multi_edit'][$rownumber][$key],
'type' => $file['type']['multi_edit'][$rownumber][$key],
'size' => $file['size']['multi_edit'][$rownumber][$key],
'tmp_name' => $file['tmp_name']['multi_edit'][$rownumber][$key],
'error' => $file['error']['multi_edit'][$rownumber][$key],
);
return $new_file;
}
/**
* sets the name if the file to the one selected in the tbl_change form
*
* @access public
* @param string $key the md5 hash of the column name
* @param string $rownumber
* @return boolean success
*/
function setSelectedFromTblChangeRequest($key, $rownumber = null)
{
if (! empty($_REQUEST['fields_uploadlocal']['multi_edit'][$rownumber][$key])
&& is_string($_REQUEST['fields_uploadlocal']['multi_edit'][$rownumber][$key])) {
// ... whether with multiple rows ...
// for blobstreaming
$is_bs_upload = false;
// check if this field requires a repository upload
if (isset($_REQUEST['upload_blob_repo']['multi_edit'][$rownumber][$key])) {
$is_bs_upload = ($_REQUEST['upload_blob_repo']['multi_edit'][$rownumber][$key] == "on") ? true : false;
}
// is a request to upload file to BLOB repository using uploadDir mechanism
if ($is_bs_upload) {
$bs_db = $_REQUEST['db'];
$bs_table = $_REQUEST['table'];
$tmp_filename = $GLOBALS['cfg']['UploadDir'] . '/' . $_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$rownumber];
// check if fileinfo library exists
if ($PMA_Config->get('FILEINFO_EXISTS')) {
// attempt to init fileinfo
$finfo = finfo_open(FILEINFO_MIME);
// fileinfo exists
if ($finfo) {
// pass in filename to fileinfo and close fileinfo handle after
$tmp_file_type = finfo_file($finfo, $tmp_filename);
finfo_close($finfo);
}
} else {
// no fileinfo library exists, use file command
$tmp_file_type = exec("file -bi " . escapeshellarg($tmp_filename));
}
if (! $tmp_file_type) {
$tmp_file_type = null;
}
if (! $bs_db || !$bs_table) {
$this->_error_message = __('Unknown error while uploading.');
return false;
}
$blob_url = PMA_BS_UpLoadFile($bs_db, $bs_table, $tmp_file_type, $tmp_filename);
PMA_File::setRecentBLOBReference($blob_url);
} // end if ($is_bs_upload)
return $this->setLocalSelectedFile($_REQUEST['fields_uploadlocal']['multi_edit'][$rownumber][$key]);
} else {
return false;
}
}
/**
* @access public
* @return string error message
*/
function getError()
{
return $this->_error_message;
}
/**
* @access public
* @return boolean whether an error occured or not
*/
function isError()
{
return ! empty($this->_error_message);
}
/**
* checks the superglobals provided if the tbl_change form is submitted
* and uses the submitted/selected file
*
* @access public
* @param string $key the md5 hash of the column name
* @param string $rownumber
* @return boolean success
*/
function checkTblChangeForm($key, $rownumber)
{
if ($this->setUploadedFromTblChangeRequest($key, $rownumber)) {
// well done ...
$this->_error_message = '';
return true;
} elseif ($this->setSelectedFromTblChangeRequest($key, $rownumber)) {
// well done ...
$this->_error_message = '';
return true;
}
// all failed, whether just no file uploaded/selected or an error
return false;
}
/**
*
* @access public
* @param string $name
* @return boolean success
*/
function setLocalSelectedFile($name)
{
if (empty($GLOBALS['cfg']['UploadDir'])) return false;
$this->setName(PMA_userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name));
if (! $this->isReadable()) {
$this->_error_message = __('File could not be read');
$this->setName(null);
return false;
}
return true;
}
/**
* @access public
* @return boolean whether the file is readable or not
*/
function isReadable()
{
// suppress warnings from being displayed, but not from being logged
// any file access outside of open_basedir will issue a warning
ob_start();
$is_readable = is_readable($this->getName());
ob_end_clean();
return $is_readable;
}
/**
* If we are on a server with open_basedir, we must move the file
* before opening it. The FAQ 1.11 explains how to create the "./tmp"
* directory - if needed
*
* @todo move check of $cfg['TempDir'] into PMA_Config?
* @access public
* @return boolean whether uploaded fiel is fine or not
*/
function checkUploadedFile()
{
if ($this->isReadable()) {
return true;
}
if (empty($GLOBALS['cfg']['TempDir']) || ! is_writable($GLOBALS['cfg']['TempDir'])) {
// cannot create directory or access, point user to FAQ 1.11
$this->_error_message = __('Error moving the uploaded file, see [a@./Documentation.html#faq1_11@Documentation]FAQ 1.11[/a]');
return false;
}
$new_file_to_upload = tempnam(realpath($GLOBALS['cfg']['TempDir']), basename($this->getName()));
// suppress warnings from being displayed, but not from being logged
// any file access outside of open_basedir will issue a warning
ob_start();
$move_uploaded_file_result = move_uploaded_file($this->getName(), $new_file_to_upload);
ob_end_clean();
if (! $move_uploaded_file_result) {
$this->_error_message = __('Error while moving uploaded file.');
return false;
}
$this->setName($new_file_to_upload);
$this->isTemp(true);
if (! $this->isReadable()) {
$this->_error_message = __('Cannot read (moved) upload file.');
return false;
}
return true;
}
/**
* Detects what compression filse uses
*
* @todo move file read part into readChunk() or getChunk()
* @todo add support for compression plugins
* @access protected
* @return string MIME type of compression, none for none
*/
function _detectCompression()
{
// suppress warnings from being displayed, but not from being logged
// f.e. any file access outside of open_basedir will issue a warning
ob_start();
$file = fopen($this->getName(), 'rb');
ob_end_clean();
if (! $file) {
$this->_error_message = __('File could not be read');
return false;
}
/**
* @todo
* get registered plugins for file compression
foreach (PMA_getPlugins($type = 'compression') as $plugin) {
if (call_user_func_array(array($plugin['classname'], 'canHandle'), array($this->getName()))) {
$this->setCompressionPlugin($plugin);
break;
}
}
*/
$test = fread($file, 4);
$len = strlen($test);
fclose($file);
if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
$this->_compression = 'application/gzip';
} elseif ($len >= 3 && substr($test, 0, 3) == 'BZh') {
$this->_compression = 'application/bzip2';
} elseif ($len >= 4 && $test == "PK\003\004") {
$this->_compression = 'application/zip';
} else {
$this->_compression = 'none';
}
return $this->_compression;
}
/**
* whether the content should be decompressed before returned
*/
function setDecompressContent($decompress)
{
$this->_decompress = (bool) $decompress;
}
function getHandle()
{
if (null === $this->_handle) {
$this->open();
}
return $this->_handle;
}
function setHandle($handle)
{
$this->_handle = $handle;
}
/**
* @return bool
*/
function open()
{
if (! $this->_decompress) {
$this->_handle = @fopen($this->getName(), 'r');
}
switch ($this->getCompression()) {
case false:
return false;
case 'application/bzip2':
if ($GLOBALS['cfg']['BZipDump'] && @function_exists('bzopen')) {
$this->_handle = @bzopen($this->getName(), 'r');
} else {
$this->_error_message = sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
return false;
}
break;
case 'application/gzip':
if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzopen')) {
$this->_handle = @gzopen($this->getName(), 'r');
} else {
$this->_error_message = sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
return false;
}
break;
case 'application/zip':
if ($GLOBALS['cfg']['ZipDump'] && @function_exists('zip_open')) {
include_once './libraries/zip_extension.lib.php';
$result = PMA_getZipContents($this->getName());
if (! empty($result['error'])) {
$this->_error_message = PMA_Message::rawError($result['error']);
return false;
} else {
$this->content_uncompressed = $result['data'];
}
unset($result);
} else {
$this->_error_message = sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
return false;
}
break;
case 'none':
$this->_handle = @fopen($this->getName(), 'r');
break;
default:
$this->_error_message = sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
return false;
break;
}
return true;
}
function getCharset()
{
return $this->_charset;
}
function setCharset($charset)
{
$this->_charset = $charset;
}
/**
* @return string MIME type of compression, none for none
* @access public
*/
function getCompression()
{
if (null === $this->_compression) {
return $this->_detectCompression();
}
return $this->_compression;
}
/**
* advances the file pointer in the file handle by $length bytes/chars
*
* @param integer $length numbers of chars/bytes to skip
* @return boolean
* @todo this function is unused
*/
function advanceFilePointer($length)
{
while ($length > 0) {
$this->getNextChunk($length);
$length -= $this->getChunkSize();
}
}
/**
* http://bugs.php.net/bug.php?id=29532
* bzip reads a maximum of 8192 bytes on windows systems
* @todo this function is unused
* @param int $max_size
* @return bool|string
*/
function getNextChunk($max_size = null)
{
if (null !== $max_size) {
$size = min($max_size, $this->getChunkSize());
} else {
$size = $this->getChunkSize();
}
// $result = $this->handler->getNextChunk($size);
$result = '';
switch ($this->getCompression()) {
case 'application/bzip2':
$result = '';
while (strlen($result) < $size - 8192 && ! feof($this->getHandle())) {
$result .= bzread($this->getHandle(), $size);
}
break;
case 'application/gzip':
$result = gzread($this->getHandle(), $size);
break;
case 'application/zip':
/*
* if getNextChunk() is used some day,
* replace this code by code similar to the one
* in open()
*
include_once './libraries/unzip.lib.php';
$import_handle = new SimpleUnzip();
$import_handle->ReadFile($this->getName());
if ($import_handle->Count() == 0) {
$this->_error_message = __('No files found inside ZIP archive!');
return false;
} elseif ($import_handle->GetError(0) != 0) {
$this->_error_message = __('Error in ZIP archive:')
. ' ' . $import_handle->GetErrorMsg(0);
return false;
} else {
$result = $import_handle->GetData(0);
}
*/
break;
case 'none':
$result = fread($this->getHandle(), $size);
break;
default:
return false;
}
if ($GLOBALS['charset_conversion']) {
$result = PMA_convert_string($this->getCharset(), 'utf-8', $result);
} else {
/**
* Skip possible byte order marks (I do not think we need more
* charsets, but feel free to add more, you can use wikipedia for
* reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
*
* @todo BOM could be used for charset autodetection
*/
if ($this->getOffset() === 0) {
// UTF-8
if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
$result = substr($result, 3);
// UTF-16 BE, LE
} elseif (strncmp($result, "\xFE\xFF", 2) == 0
|| strncmp($result, "\xFF\xFE", 2) == 0) {
$result = substr($result, 2);
}
}
}
$this->_offset += $size;
if (0 === $result) {
return true;
}
return $result;
}
function getOffset()
{
return $this->_offset;
}
function getChunkSize()
{
return $this->_chunk_size;
}
function setChunkSize($chunk_size)
{
$this->_chunk_size = (int) $chunk_size;
}
function getContentLength()
{
return strlen($this->_content);
}
function eof()
{
if ($this->getHandle()) {
return feof($this->getHandle());
} else {
return ($this->getOffset() >= $this->getContentLength());
}
}
/**
* sets reference to most recent BLOB repository reference
*
* @access public
* @param string - BLOB repository reference
*/
static function setRecentBLOBReference($ref)
{
PMA_File::$_recent_bs_reference = $ref;
}
/**
* retrieves reference to most recent BLOB repository reference
*
* @access public
* @return string - most recent BLOB repository reference
*/
static function getRecentBLOBReference()
{
$ref = PMA_File::$_recent_bs_reference;
PMA_File::$_recent_bs_reference = null;
return $ref;
}
}
?>

View File

@ -0,0 +1,704 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* holds the database index class
*
* @package PhpMyAdmin
*/
/**
* @since phpMyAdmin 3.0.0
*
* @package PhpMyAdmin
*/
class PMA_Index
{
/**
* Class-wide storage container for indexes (caching, singleton)
*
* @var array
*/
protected static $_registry = array();
/**
* @var string The name of the schema
*/
protected $_schema = '';
/**
* @var string The name of the table
*/
protected $_table = '';
/**
* @var string The name of the index
*/
protected $_name = '';
/**
* Columns in index
*
* @var array
*/
protected $_columns = array();
/**
* The index method used (BTREE, SPATIAL, FULLTEXT, HASH, RTREE).
*
* @var string
*/
protected $_type = '';
/**
* The index choice (PRIMARY, UNIQUE, INDEX, SPATIAL, FULLTEXT)
*
* @var string
*/
protected $_choice = '';
/**
* Various remarks.
*
* @var string
*/
protected $_remarks = '';
/**
* Any comment provided for the index with a COMMENT attribute when the
* index was created.
*
* @var string
*/
protected $_comment = '';
/**
* @var integer 0 if the index cannot contain duplicates, 1 if it can.
*/
protected $_non_unique = 0;
/**
* Indicates how the key is packed. NULL if it is not.
*
* @var string
*/
protected $_packed = null;
/**
* Constructor
*
* @param array $params
*/
public function __construct($params = array())
{
$this->set($params);
}
static public function singleton($schema, $table, $index_name = '')
{
PMA_Index::_loadIndexes($table, $schema);
if (! isset(PMA_Index::$_registry[$schema][$table][$index_name])) {
$index = new PMA_Index;
if (strlen($index_name)) {
$index->setName($index_name);
PMA_Index::$_registry[$schema][$table][$index->getName()] = $index;
}
return $index;
} else {
return PMA_Index::$_registry[$schema][$table][$index_name];
}
}
/**
* returns an array with all indexes from the given table
*
* @param string $table
* @param string $schema
* @return array
*/
static public function getFromTable($table, $schema)
{
PMA_Index::_loadIndexes($table, $schema);
if (isset(PMA_Index::$_registry[$schema][$table])) {
return PMA_Index::$_registry[$schema][$table];
} else {
return array();
}
}
/**
* return primary if set, false otherwise
*
* @param string $table
* @param string $schema
* @return mixed primary index or false if no one exists
*/
static public function getPrimary($table, $schema)
{
PMA_Index::_loadIndexes($table, $schema);
if (isset(PMA_Index::$_registry[$schema][$table]['PRIMARY'])) {
return PMA_Index::$_registry[$schema][$table]['PRIMARY'];
} else {
return false;
}
}
/**
* Load index data for table
*
* @param string $table
* @param string $schema
* @return boolean
*/
static protected function _loadIndexes($table, $schema)
{
if (isset(PMA_Index::$_registry[$schema][$table])) {
return true;
}
$_raw_indexes = PMA_DBI_get_table_indexes($schema, $table);
foreach ($_raw_indexes as $_each_index) {
$_each_index['Schema'] = $schema;
if (! isset(PMA_Index::$_registry[$schema][$table][$_each_index['Key_name']])) {
$key = new PMA_Index($_each_index);
PMA_Index::$_registry[$schema][$table][$_each_index['Key_name']] = $key;
} else {
$key = PMA_Index::$_registry[$schema][$table][$_each_index['Key_name']];
}
$key->addColumn($_each_index);
}
return true;
}
/**
* Add column to index
*
* @param array $params column params
*/
public function addColumn($params)
{
if (strlen($params['Column_name'])) {
$this->_columns[$params['Column_name']] = new PMA_Index_Column($params);
}
}
public function addColumns($columns)
{
$_columns = array();
if (isset($columns['names'])) {
// coming from form
// $columns[names][]
// $columns[sub_parts][]
foreach ($columns['names'] as $key => $name) {
$sub_part = isset($columns['sub_parts'][$key]) ? $columns['sub_parts'][$key] : '';
$_columns[] = array(
'Column_name' => $name,
'Sub_part' => $sub_part,
);
}
} else {
// coming from SHOW INDEXES
// $columns[][name]
// $columns[][sub_part]
// ...
$_columns = $columns;
}
foreach ($_columns as $column) {
$this->addColumn($column);
}
}
/**
* Returns true if $column indexed in this index
*
* @param string $column
* @return boolean
*/
public function hasColumn($column)
{
return isset($this->_columns[$column]);
}
public function set($params)
{
if (isset($params['columns'])) {
$this->addColumns($params['columns']);
}
if (isset($params['Schema'])) {
$this->_schema = $params['Schema'];
}
if (isset($params['Table'])) {
$this->_table = $params['Table'];
}
if (isset($params['Key_name'])) {
$this->_name = $params['Key_name'];
}
if (isset($params['Index_type'])) {
$this->_type = $params['Index_type'];
}
if (isset($params['Comment'])) {
$this->_remarks = $params['Comment'];
}
if (isset($params['Index_comment'])) {
$this->_comment = $params['Index_comment'];
}
if (isset($params['Non_unique'])) {
$this->_non_unique = $params['Non_unique'];
}
if (isset($params['Packed'])) {
$this->_packed = $params['Packed'];
}
if ('PRIMARY' == $this->_name) {
$this->_choice = 'PRIMARY';
} elseif ('FULLTEXT' == $this->_type) {
$this->_choice = 'FULLTEXT';
} elseif ('SPATIAL' == $this->_type) {
$this->_choice = 'SPATIAL';
} elseif ('0' == $this->_non_unique) {
$this->_choice = 'UNIQUE';
} else {
$this->_choice = 'INDEX';
}
}
public function getColumnCount()
{
return count($this->_columns);
}
public function getComment()
{
return $this->_comment;
}
public function getRemarks()
{
return $this->_remarks;
}
public function getComments()
{
$comments = $this->getRemarks();
if (strlen($comments)) {
$comments .= "\n";
}
$comments .= $this->getComment();
return $comments;
}
public function getType()
{
return $this->_type;
}
public function getChoice()
{
return $this->_choice;
}
/**
* Return a list of all index choices
*
* @return array index choices
*/
static public function getIndexChoices()
{
return array(
'PRIMARY',
'INDEX',
'UNIQUE',
'SPATIAL',
'FULLTEXT',
);
}
public function generateIndexSelector()
{
$html_options = '';
foreach (PMA_Index::getIndexChoices() as $each_index_choice) {
if ($each_index_choice === 'PRIMARY'
&& $this->_choice !== 'PRIMARY'
&& PMA_Index::getPrimary($this->_table, $this->_schema)) {
// skip PRIMARY if there is already one in the table
continue;
}
$html_options .= '<option value="' . $each_index_choice . '"'
. (($this->_choice == $each_index_choice) ? ' selected="selected"' : '')
. '>'. $each_index_choice . '</option>' . "\n";
}
return $html_options;
}
public function getPacked()
{
return $this->_packed;
}
public function isPacked($as_text = false)
{
if ($as_text) {
$r = array(
'0' => __('No'),
'1' => __('Yes'),
);
} else {
$r = array(
'0' => false,
'1' => true,
);
}
if (null === $this->_packed) {
return $r[0];
}
return $this->_packed;
}
public function getNonUnique()
{
return $this->_non_unique;
}
public function isUnique($as_text = false)
{
if ($as_text) {
$r = array(
'0' => __('Yes'),
'1' => __('No'),
);
} else {
$r = array(
'0' => true,
'1' => false,
);
}
return $r[$this->_non_unique];
}
public function getName()
{
return $this->_name;
}
public function setName($name)
{
$this->_name = (string) $name;
}
public function getColumns()
{
return $this->_columns;
}
/**
* Show index data
*
* @param string $table The tablename
* @param array $indexes_info Referenced info array
* @param array $indexes_data Referenced data array
* @param boolean $print_mode
* @access public
* @return array Index collection array
*/
static public function getView($table, $schema, $print_mode = false)
{
$indexes = PMA_Index::getFromTable($table, $schema);
$no_indexes_class = count($indexes) > 0 ? ' hide' : '';
$no_indexes = "<div class='no_indexes_defined$no_indexes_class'>";
$no_indexes .= PMA_Message::notice(__('No index defined!'))->getDisplay();
$no_indexes .= '</div>';
$r = '<fieldset>';
$r .= '<legend id="index_header">' . __('Indexes');
$r .= PMA_showMySQLDocu('optimization', 'optimizing-database-structure');
$r .= '</legend>';
$r .= $no_indexes;
if (count($indexes) < 1) {
$r .= '</fieldset>';
return $r;
}
if (! $print_mode) {
$r .= PMA_Index::findDuplicates($table, $schema);
}
$r .= '<table id="table_index">';
$r .= '<thead>';
$r .= '<tr>';
if (! $print_mode) {
$r .= '<th colspan="2">' . __('Action') . '</th>';
}
$r .= '<th>' . __('Keyname') . '</th>';
$r .= '<th>' . __('Type') . '</th>';
$r .= '<th>' . __('Unique') . '</th>';
$r .= '<th>' . __('Packed') . '</th>';
$r .= '<th>' . __('Column') . '</th>';
$r .= '<th>' . __('Cardinality') . '</th>';
$r .= '<th>' . __('Collation') . '</th>';
$r .= '<th>' . __('Null') . '</th>';
$r .= '<th>' . __('Comment') . '</th>';
$r .= '</tr>';
$r .= '</thead>';
$r .= '<tbody>';
$odd_row = true;
foreach ($indexes as $index) {
$row_span = ' rowspan="' . $index->getColumnCount() . '" ';
$r .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
if (! $print_mode) {
$this_params = $GLOBALS['url_params'];
$this_params['index'] = $index->getName();
$r .= '<td class="edit_index ';
if ($GLOBALS['cfg']['AjaxEnable']) {
$r .= 'ajax" ';
}
$r .= '" ' . $row_span . '>'
. ' <a href="tbl_indexes.php' . PMA_generate_common_url($this_params)
. '">' . PMA_getIcon('b_edit.png', __('Edit')) . '</a>'
. '</td>' . "\n";
$this_params = $GLOBALS['url_params'];
if ($index->getName() == 'PRIMARY') {
$this_params['sql_query'] = 'ALTER TABLE ' . PMA_backquote($table) . ' DROP PRIMARY KEY';
$this_params['message_to_show'] = __('The primary key has been dropped');
$js_msg = PMA_jsFormat('ALTER TABLE ' . $table . ' DROP PRIMARY KEY');
} else {
$this_params['sql_query'] = 'ALTER TABLE ' . PMA_backquote($table) . ' DROP INDEX ' . PMA_backquote($index->getName());
$this_params['message_to_show'] = sprintf(__('Index %s has been dropped'), $index->getName());
$js_msg = PMA_jsFormat('ALTER TABLE ' . $table . ' DROP INDEX ' . $index->getName());
}
$r .= '<td ' . $row_span . '>';
$r .= '<input type="hidden" class="drop_primary_key_index_msg" value="' . $js_msg . '" />';
$r .= ' <a ';
if ($GLOBALS['cfg']['AjaxEnable']) {
$r .= 'class="drop_primary_key_index_anchor" ';
}
$r .= ' href="sql.php' . PMA_generate_common_url($this_params)
. '" >'
. PMA_getIcon('b_drop.png', __('Drop')) . '</a>'
. '</td>' . "\n";
}
$r .= '<th ' . $row_span . '>' . htmlspecialchars($index->getName()) . '</th>';
$r .= '<td ' . $row_span . '>' . htmlspecialchars($index->getType()) . '</td>';
$r .= '<td ' . $row_span . '>' . $index->isUnique(true) . '</td>';
$r .= '<td ' . $row_span . '>' . $index->isPacked(true) . '</td>';
foreach ($index->getColumns() as $column) {
if ($column->getSeqInIndex() > 1) {
$r .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
}
$r .= '<td>' . htmlspecialchars($column->getName());
if ($column->getSubPart()) {
$r .= ' (' . $column->getSubPart() . ')';
}
$r .= '</td>';
$r .= '<td>' . htmlspecialchars($column->getCardinality()) . '</td>';
$r .= '<td>' . htmlspecialchars($column->getCollation()) . '</td>';
$r .= '<td>' . htmlspecialchars($column->getNull(true)) . '</td>';
if ($column->getSeqInIndex() == 1) {
$r .= '<td ' . $row_span . '>'
. htmlspecialchars($index->getComments()) . '</td>';
}
$r .= '</tr>';
} // end foreach $index['Sequences']
$odd_row = ! $odd_row;
} // end while
$r .= '</tbody>';
$r .= '</table>';
$r .= '</fieldset>';
return $r;
}
public function getCompareData()
{
$data = array(
// 'Non_unique' => $this->_non_unique,
'Packed' => $this->_packed,
'Index_type' => $this->_type,
);
foreach ($this->_columns as $column) {
$data['columns'][] = $column->getCompareData();
}
return $data;
}
/**
* Function to check over array of indexes and look for common problems
*
* @access public
* @param string name of table
* @return string Output HTML
*/
static public function findDuplicates($table, $schema)
{
$indexes = PMA_Index::getFromTable($table, $schema);
$output = '';
// count($indexes) < 2:
// there is no need to check if there less than two indexes
if (count($indexes) < 2) {
return $output;
}
// remove last index from stack and ...
while ($while_index = array_pop($indexes)) {
// ... compare with every remaining index in stack
foreach ($indexes as $each_index) {
if ($each_index->getCompareData() !== $while_index->getCompareData()) {
continue;
}
// did not find any difference
// so it makes no sense to have this two equal indexes
$message = PMA_Message::notice(__('The indexes %1$s and %2$s seem to be equal and one of them could possibly be removed.'));
$message->addParam($each_index->getName());
$message->addParam($while_index->getName());
$output .= $message->getDisplay();
// there is no need to check any further indexes if we have already
// found that this one has a duplicate
continue 2;
}
}
return $output;
}
}
/**
* @package PhpMyAdmin
*/
class PMA_Index_Column
{
/**
* @var string The column name
*/
protected $_name = '';
/**
* @var integer The column sequence number in the index, starting with 1.
*/
protected $_seq_in_index = 1;
/**
* @var string How the column is sorted in the index. “A” (Ascending) or NULL (Not sorted)
*/
protected $_collation = null;
/**
* The number of indexed characters if the column is only partly indexed,
* NULL if the entire column is indexed.
*
* @var integer
*/
protected $_sub_part = null;
/**
* Contains YES if the column may contain NULL.
* If not, the column contains NO.
*
* @var string
*/
protected $_null = '';
/**
* An estimate of the number of unique values in the index. This is updated
* by running ANALYZE TABLE or myisamchk -a. Cardinality is counted based on
* statistics stored as integers, so the value is not necessarily exact even
* for small tables. The higher the cardinality, the greater the chance that
* MySQL uses the index when doing joins.
*
* @var integer
*/
protected $_cardinality = null;
public function __construct($params = array())
{
$this->set($params);
}
public function set($params)
{
if (isset($params['Column_name'])) {
$this->_name = $params['Column_name'];
}
if (isset($params['Seq_in_index'])) {
$this->_seq_in_index = $params['Seq_in_index'];
}
if (isset($params['Collation'])) {
$this->_collation = $params['Collation'];
}
if (isset($params['Cardinality'])) {
$this->_cardinality = $params['Cardinality'];
}
if (isset($params['Sub_part'])) {
$this->_sub_part = $params['Sub_part'];
}
if (isset($params['Null'])) {
$this->_null = $params['Null'];
}
}
public function getName()
{
return $this->_name;
}
public function getCollation()
{
return $this->_collation;
}
public function getCardinality()
{
return $this->_cardinality;
}
public function getNull($as_text = false)
{
return $as_text
? (!$this->_null || $this->_null == 'NO' ? __('No') : __('Yes'))
: $this->_null;
}
public function getSeqInIndex()
{
return $this->_seq_in_index;
}
public function getSubPart()
{
return $this->_sub_part;
}
public function getCompareData()
{
return array(
'Column_name' => $this->_name,
'Seq_in_index' => $this->_seq_in_index,
'Collation' => $this->_collation,
'Sub_part' => $this->_sub_part,
'Null' => $this->_null,
);
}
}
?>

View File

@ -0,0 +1,115 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* hold the PMA_List base class
*
* @package PhpMyAdmin
*/
/**
* @todo add caching
* @since phpMyAdmin 2.9.10
* @abstract
* @package PhpMyAdmin
*/
abstract class PMA_List extends ArrayObject
{
/**
* @var mixed empty item
*/
protected $item_empty = '';
public function __construct($array = array(), $flags = 0, $iterator_class = "ArrayIterator")
{
parent::__construct($array, $flags, $iterator_class);
}
/**
* returns item only if there is only one in the list
*
* @return single item
*/
public function getSingleItem()
{
if (count($this) === 1) {
return reset($this);
}
return $this->getEmpty();
}
/**
* defines what is an empty item (0, '', false or null)
*
* @return mixed an empty item
*/
public function getEmpty()
{
return $this->item_empty;
}
/**
* checks if the given db names exists in the current list, if there is
* missing at least one item it returns false otherwise true
*
* @param string $db_name,.. one or more mysql result resources
* @return boolean true if all items exists, otheriwse false
*/
public function exists()
{
$this_elements = $this->getArrayCopy();
foreach (func_get_args() as $result) {
if (! in_array($result, $this_elements)) {
return false;
}
}
return true;
}
/**
* returns HTML <option>-tags to be used inside <select></select>
*
* @param mixed $selected the selected db or true for selecting current db
* @param boolean $include_information_schema
* @return string HTML option tags
*/
public function getHtmlOptions($selected = '', $include_information_schema = true)
{
if (true === $selected) {
$selected = $this->getDefault();
}
$options = '';
foreach ($this as $each_item) {
if (false === $include_information_schema
&& PMA_is_system_schema($each_item)) {
continue;
}
$options .= '<option value="' . htmlspecialchars($each_item) . '"';
if ($selected === $each_item) {
$options .= ' selected="selected"';
}
$options .= '>' . htmlspecialchars($each_item) . '</option>' . "\n";
}
return $options;
}
/**
* returns default item
*
* @return string default item
*/
public function getDefault()
{
return $this->getEmpty();
}
/**
* builds up the list
*
*/
abstract public function build();
}
?>

View File

@ -0,0 +1,484 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* holds the PMA_List_Database class
*
* @package PhpMyAdmin
*/
/**
* the list base class
*/
require_once './libraries/List.class.php';
/**
* handles database lists
*
* <code>
* $PMA_List_Database = new PMA_List_Database($userlink, $controllink);
* </code>
*
* @todo this object should be attached to the PMA_Server object
* @todo ? make use of INFORMATION_SCHEMA
* @todo ? support --skip-showdatabases and user has only global rights
* @access public
* @since phpMyAdmin 2.9.10
* @package PhpMyAdmin
*/
/*public*/ class PMA_List_Database extends PMA_List
{
/**
* @var mixed database link resource|object to be used
*/
protected $_db_link = null;
/**
* @var mixed user database link resource|object
*/
protected $_db_link_user = null;
/**
* @var mixed controluser database link resource|object
*/
protected $_db_link_control = null;
/**
* @var boolean whether SHOW DATABASES is disabled or not
* @access protected
*/
protected $_show_databases_disabled = false;
/**
* @var string command to retrieve databases from server
*/
protected $_command = null;
/**
* Constructor
*
* @param mixed $db_link_user user database link resource|object
* @param mixed $db_link_control control database link resource|object
*/
public function __construct($db_link_user = null, $db_link_control = null)
{
$this->_db_link = $db_link_user;
$this->_db_link_user = $db_link_user;
$this->_db_link_control = $db_link_control;
parent::__construct();
$this->build();
}
/**
* checks if the configuration wants to hide some databases
*/
protected function _checkHideDatabase()
{
if (empty($GLOBALS['cfg']['Server']['hide_db'])) {
return;
}
foreach ($this->getArrayCopy() as $key => $db) {
if (preg_match('/' . $GLOBALS['cfg']['Server']['hide_db'] . '/', $db)) {
$this->offsetUnset($key);
}
}
}
/**
* retrieves database list from server
*
* @todo we could also search mysql tables if all fail?
* @param string $like_db_name usally a db_name containing wildcards
* @return array
*/
protected function _retrieve($like_db_name = null)
{
if ($this->_show_databases_disabled) {
return array();
}
if (null !== $like_db_name) {
$command = "SHOW DATABASES LIKE '" . $like_db_name . "'";
} elseif (null === $this->_command) {
$command = str_replace('#user#', $GLOBALS['cfg']['Server']['user'],
$GLOBALS['cfg']['Server']['ShowDatabasesCommand']);
$this->_command = $command;
} else {
$command = $this->_command;
}
$database_list = PMA_DBI_fetch_result($command, null, null, $this->_db_link);
PMA_DBI_getError();
if ($GLOBALS['errno'] !== 0) {
// failed to get database list, try the control user
// (hopefully there is one and he has SHOW DATABASES right)
$this->_db_link = $this->_db_link_control;
$database_list = PMA_DBI_fetch_result($command, null, null, $this->_db_link);
PMA_DBI_getError();
if ($GLOBALS['errno'] !== 0) {
// failed! we will display a warning that phpMyAdmin could not safely
// retrieve database list, the admin has to setup a control user or
// allow SHOW DATABASES
$GLOBALS['error_showdatabases'] = true;
$this->_show_databases_disabled = true;
}
}
if ($GLOBALS['cfg']['NaturalOrder']) {
natsort($database_list);
} else {
// need to sort anyway, otherwise information_schema
// goes at the top
sort($database_list);
}
return $database_list;
}
/**
* builds up the list
*
*/
public function build()
{
if (! $this->_checkOnlyDatabase()) {
$items = $this->_retrieve();
$this->exchangeArray($items);
}
$this->_checkHideDatabase();
}
/**
* checks the only_db configuration
*
* @return boolean false if there is no only_db, otherwise true
*/
protected function _checkOnlyDatabase()
{
if (is_string($GLOBALS['cfg']['Server']['only_db'])
&& strlen($GLOBALS['cfg']['Server']['only_db'])) {
$GLOBALS['cfg']['Server']['only_db'] = array(
$GLOBALS['cfg']['Server']['only_db']
);
}
if (! is_array($GLOBALS['cfg']['Server']['only_db'])) {
return false;
}
$items = array();
foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) {
if ($each_only_db === '*' && ! $this->_show_databases_disabled) {
// append all not already listed dbs to the list
$items = array_merge($items,
array_diff($this->_retrieve(), $items));
// there can only be one '*', and this can only be last
break;
}
// check if the db name contains wildcard,
// thus containing not escaped _ or %
if (! preg_match('/(^|[^\\\\])(_|%)/', $each_only_db)) {
// ... not contains wildcard
$items[] = PMA_unescape_mysql_wildcards($each_only_db);
continue;
}
if (! $this->_show_databases_disabled) {
$items = array_merge($items, $this->_retrieve($each_only_db));
continue;
}
// @todo induce error, about not using wildcards with SHOW DATABASE disabled?
}
$this->exchangeArray($items);
return true;
}
/**
* returns default item
*
* @return string default item
*/
public function getDefault()
{
if (strlen($GLOBALS['db'])) {
return $GLOBALS['db'];
}
return $this->getEmpty();
}
/**
* returns array with dbs grouped with extended infos
*
* @param integer $offset
* @param integer $count
* @return array db list
*/
public function getGroupedDetails($offset, $count)
{
$dbgroups = array();
if ($GLOBALS['cfg']['ShowTooltip']
&& $GLOBALS['cfgRelation']['commwork']) {
$db_tooltips = PMA_getDbComments();
}
if (!$GLOBALS['cfg']['LeftFrameDBTree']) {
$separators = array();
} elseif (is_array($GLOBALS['cfg']['LeftFrameDBSeparator'])) {
$separators = $GLOBALS['cfg']['LeftFrameDBSeparator'];
} elseif (!empty($GLOBALS['cfg']['LeftFrameDBSeparator'])) {
$separators = array($GLOBALS['cfg']['LeftFrameDBSeparator']);
} else {
$separators = array();
}
foreach ($this->getLimitedItems($offset, $count) as $db) {
// Get comments from PMA comments table
$db_tooltip = '';
if (isset($db_tooltips[$db])) {
$db_tooltip = $db_tooltips[$db];
}
$pos = false;
foreach ($separators as $separator) {
// use strpos instead of strrpos; it seems more common to
// have the db name, the separator, then the rest which
// might contain a separator
// like dbname_the_rest
$pos = strpos($db, $separator, 1);
if ($pos !== false) {
break;
}
}
if ($pos !== false) {
$group = substr($db, 0, $pos);
$disp_name_cut = substr($db, $pos);
} else {
$group = $db;
$disp_name_cut = $db;
}
$disp_name = $db;
if ($db_tooltip && $GLOBALS['cfg']['ShowTooltipAliasDB']) {
$disp_name = $db_tooltip;
$disp_name_cut = $db_tooltip;
$db_tooltip = $db;
}
$dbgroups[$group][$db] = array(
'name' => $db,
'disp_name_cut' => $disp_name_cut,
'disp_name' => $disp_name,
'comment' => $db_tooltip,
);
if ($GLOBALS['cfg']['Server']['CountTables']) {
$dbgroups[$group][$db]['num_tables'] = PMA_getTableCount($db);
}
} // end foreach ($GLOBALS['PMA_List_Database']->items as $db)
return $dbgroups;
}
/**
* returns a part of the items
*
* @param integer $offset
* @param integer $count
* @return array some items
*/
public function getLimitedItems($offset, $count)
{
return array_slice($this->getArrayCopy(), $offset, $count);
}
/**
* returns html code for list with dbs
*
* @return string html code list
*/
public function getHtmlListGrouped($selected = '', $offset, $count)
{
if (true === $selected) {
$selected = $this->getDefault();
}
$return = '<ul id="databaseList" xml:lang="en" dir="ltr">' . "\n";
foreach ($this->getGroupedDetails($offset, $count) as $group => $dbs) {
if (count($dbs) > 1) {
$return .= '<li class="group"><span>' . htmlspecialchars($group) . '</span><ul>' . "\n";
// whether display db_name cut by the group part
$cut = true;
} else {
// .. or full
$cut = false;
}
foreach ($dbs as $db) {
$return .= '<li';
if ($db['name'] == $selected) {
$return .= ' class="selected"';
}
$return .= '><a';
if (! empty($db['comment'])) {
$return .= ' title="' . htmlspecialchars($db['comment']) . '"';
}
$return .= ' href="index.php?' . PMA_generate_common_url($db['name'])
. '" target="_parent">';
if ($cut) {
$return .= htmlspecialchars($db['disp_name_cut']);
} else {
$return .= htmlspecialchars($db['disp_name']);
}
if (! empty($db['num_tables'])) {
$return .= ' (' . $db['num_tables'] . ')';
}
$return .= '</a></li>' . "\n";
}
if (count($dbs) > 1) {
$return .= '</ul></li>' . "\n";
}
}
$return .= '</ul>';
return $return;
}
/**
* returns html code for select form element with dbs
*
* @todo IE can not handle different text directions in select boxes so,
* as mostly names will be in english, we set the whole selectbox to LTR
* and EN
*
* @return string html code select
*/
public function getHtmlSelectGrouped($selected = '', $offset, $count)
{
if (true === $selected) {
$selected = $this->getDefault();
}
$return = '<select name="db" id="lightm_db" xml:lang="en" dir="ltr"'
. ' onchange="if (this.value != \'\') window.parent.openDb(this.value);">' . "\n"
. '<option value="" dir="' . $GLOBALS['text_dir'] . '">'
. '(' . __('Databases') . ') ...</option>' . "\n";
foreach ($this->getGroupedDetails($offset, $count) as $group => $dbs) {
if (count($dbs) > 1) {
$return .= '<optgroup label="' . htmlspecialchars($group)
. '">' . "\n";
// whether display db_name cuted by the group part
$cut = true;
} else {
// .. or full
$cut = false;
}
foreach ($dbs as $db) {
$return .= '<option value="' . htmlspecialchars($db['name']) . '"'
.' title="' . htmlspecialchars($db['comment']) . '"';
if ($db['name'] == $selected || (PMA_DRIZZLE && strtolower($db['name']) == strtolower($selected))) {
$return .= ' selected="selected"';
}
$return .= '>' . htmlspecialchars($cut ? $db['disp_name_cut'] : $db['disp_name']);
if (! empty($db['num_tables'])) {
$return .= ' (' . $db['num_tables'] . ')';
}
$return .= '</option>' . "\n";
}
if (count($dbs) > 1) {
$return .= '</optgroup>' . "\n";
}
}
$return .= '</select>';
return $return;
}
/**
* this is just a backup, if all is fine this can be deleted later
*
* @deprecated
*/
protected function _checkAgainstPrivTables()
{
// 1. get allowed dbs from the "mysql.db" table
// User can be blank (anonymous user)
$local_query = "
SELECT DISTINCT `Db` FROM `mysql`.`db`
WHERE `Select_priv` = 'Y'
AND `User`
IN ('" . PMA_sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "', '')";
$tmp_mydbs = PMA_DBI_fetch_result($local_query, null, null,
$GLOBALS['controllink']);
if ($tmp_mydbs) {
// Will use as associative array of the following 2 code
// lines:
// the 1st is the only line intact from before
// correction,
// the 2nd replaces $dblist[] = $row['Db'];
// Code following those 2 lines in correction continues
// populating $dblist[], as previous code did. But it is
// now populated with actual database names instead of
// with regular expressions.
$tmp_alldbs = PMA_DBI_query('SHOW DATABASES;', $GLOBALS['controllink']);
// all databases cases - part 2
if (isset($tmp_mydbs['%'])) {
while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
$dblist[] = $tmp_row[0];
} // end while
} else {
while ($tmp_row = PMA_DBI_fetch_row($tmp_alldbs)) {
$tmp_db = $tmp_row[0];
if (isset($tmp_mydbs[$tmp_db]) && $tmp_mydbs[$tmp_db] == 1) {
$dblist[] = $tmp_db;
$tmp_mydbs[$tmp_db] = 0;
} elseif (! isset($dblist[$tmp_db])) {
foreach ($tmp_mydbs as $tmp_matchpattern => $tmp_value) {
// fixed bad regexp
// TODO: db names may contain characters
// that are regexp instructions
$re = '(^|(\\\\\\\\)+|[^\])';
$tmp_regex = preg_replace('/' . addcslashes($re, '/') . '%/', '\\1.*', preg_replace('/' . addcslashes($re, '/') . '_/', '\\1.{1}', $tmp_matchpattern));
// Fixed db name matching
// 2000-08-28 -- Benjamin Gandon
if (preg_match('/^' . addcslashes($tmp_regex, '/') . '$/', $tmp_db)) {
$dblist[] = $tmp_db;
break;
}
} // end while
} // end if ... elseif ...
} // end while
} // end else
PMA_DBI_free_result($tmp_alldbs);
unset($tmp_mydbs);
} // end if
// 2. get allowed dbs from the "mysql.tables_priv" table
$local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . '\'';
$rs = PMA_DBI_try_query($local_query, $GLOBALS['controllink']);
if ($rs && @PMA_DBI_num_rows($rs)) {
while ($row = PMA_DBI_fetch_assoc($rs)) {
if (!in_array($row['Db'], $dblist)) {
$dblist[] = $row['Db'];
}
} // end while
PMA_DBI_free_result($rs);
} // end if
}
}
?>

View File

@ -0,0 +1,677 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds class PMA_Message
*
* @package PhpMyAdmin
*/
/**
* a single message
*
* simple usage examples:
* <code>
* // display simple error message 'Error'
* PMA_Message::error()->display();
*
* // get simple success message 'Success'
* $message = PMA_Message::success();
*
* // get special notice 'Some locale notice'
* $message = PMA_Message::notice('strSomeLocaleNotice');
* </code>
*
* more advanced usage example:
* <code>
* // create a localized success message
* $message = PMA_Message::success('strSomeLocaleMessage');
*
* // create another message, a hint, with a localized string which expects
* // two parameters: $strSomeFootnote = 'Read the %smanual%s'
* $hint = PMA_Message::notice('strSomeFootnote');
* // replace %d with the following params
* $hint->addParam('[a@./Documentation.html#cfg_Example@_blank]');
* $hint->addParam('[/a]');
* // add this hint as a footnote
* $hint = PMA_showHint($hint);
*
* // add the retrieved footnote reference to the original message
* $message->addMessage($hint);
*
* // create another message ...
* $more = PMA_Message::notice('strSomeMoreLocale');
* $more->addString('strSomeEvenMoreLocale', '<br />');
* $more->addParam('parameter for strSomeMoreLocale');
* $more->addParam('more parameter for strSomeMoreLocale');
*
* // and add it also to the original message
* $message->addMessage($more);
* // finally add another raw message
* $message->addMessage('some final words', ' - ');
*
* // display() will now print all messages in the same order as they are added
* $message->display();
* // strSomeLocaleMessage <sup>1</sup> strSomeMoreLocale<br />
* // strSomeEvenMoreLocale - some final words
* </code>
* @package PhpMyAdmin
*/
class PMA_Message
{
const SUCCESS = 1; // 0001
const NOTICE = 2; // 0010
const ERROR = 8; // 1000
const SANITIZE_NONE = 0; // 0000 0000
const SANITIZE_STRING = 16; // 0001 0000
const SANITIZE_PARAMS = 32; // 0010 0000
const SANITIZE_BOOTH = 48; // 0011 0000
/**
* message levels
*
* @var array
*/
static public $level = array (
PMA_Message::SUCCESS => 'success',
PMA_Message::NOTICE => 'notice',
PMA_Message::ERROR => 'error',
);
/**
* The message number
*
* @access protected
* @var integer
*/
protected $_number = PMA_Message::NOTICE;
/**
* The locale string identifier
*
* @access protected
* @var string
*/
protected $_string = '';
/**
* The formatted message
*
* @access protected
* @var string
*/
protected $_message = '';
/**
* Whether the message was already displayed
*
* @access protected
* @var boolean
*/
protected $_is_displayed = false;
/**
* Unique id
*
* @access protected
* @var string
*/
protected $_hash = null;
/**
* holds parameters
*
* @access protected
* @var array
*/
protected $_params = array();
/**
* holds additional messages
*
* @access protected
* @var array
*/
protected $_added_messages = array();
/**
* Constructor
*
* @param string $string
* @param integer $number
* @param array $params
* @param integer $sanitize
*/
public function __construct($string = '', $number = PMA_Message::NOTICE,
$params = array(), $sanitize = PMA_Message::SANITIZE_NONE)
{
$this->setString($string, $sanitize & PMA_Message::SANITIZE_STRING);
$this->setNumber($number);
$this->setParams($params, $sanitize & PMA_Message::SANITIZE_PARAMS);
}
/**
* magic method: return string representation for this object
*
* @return string
*/
public function __toString()
{
return $this->getMessage();
}
/**
* get PMA_Message of type success
*
* shorthand for getting a simple success message
*
* @static
* @param string $string a localized string e.g. __('Your SQL query has been executed successfully')
* @return PMA_Message
*/
static public function success($string = '')
{
if (empty($string)) {
$string = __('Your SQL query has been executed successfully');
}
return new PMA_Message($string, PMA_Message::SUCCESS);
}
/**
* get PMA_Message of type error
*
* shorthand for getting a simple error message
*
* @static
* @param string $string a localized string e.g. __('Error')
* @return PMA_Message
*/
static public function error($string = '')
{
if (empty($string)) {
$string = __('Error');
}
return new PMA_Message($string, PMA_Message::ERROR);
}
/**
* get PMA_Message of type notice
*
* shorthand for getting a simple notice message
*
* @static
* @param string $string a localized string e.g. __('The additional features for working with linked tables have been deactivated. To find out why click %shere%s.')
* @return PMA_Message
*/
static public function notice($string)
{
return new PMA_Message($string, PMA_Message::NOTICE);
}
/**
* get PMA_Message with customized content
*
* shorthand for getting a customized message
*
* @static
* @param string $message
* @param integer $type
* @return PMA_Message
*/
static public function raw($message, $type = PMA_Message::NOTICE)
{
$r = new PMA_Message('', $type);
$r->setMessage($message);
return $r;
}
/**
* get PMA_Message for number of affected rows
*
* shorthand for getting a customized message
*
* @static
* @param integer $rows Number of rows
* @return PMA_Message
*/
static public function affected_rows($rows)
{
$message = PMA_Message::success(_ngettext('%1$d row affected.', '%1$d rows affected.', $rows));
$message->addParam($rows);
return $message;
}
/**
* get PMA_Message for number of deleted rows
*
* shorthand for getting a customized message
*
* @static
* @param integer $rows Number of rows
* @return PMA_Message
*/
static public function deleted_rows($rows)
{
$message = PMA_Message::success(_ngettext('%1$d row deleted.', '%1$d rows deleted.', $rows));
$message->addParam($rows);
return $message;
}
/**
* get PMA_Message for number of inserted rows
*
* shorthand for getting a customized message
*
* @static
* @param integer $rows Number of rows
* @return PMA_Message
*/
static public function inserted_rows($rows)
{
$message = PMA_Message::success(_ngettext('%1$d row inserted.', '%1$d rows inserted.', $rows));
$message->addParam($rows);
return $message;
}
/**
* get PMA_Message of type error with custom content
*
* shorthand for getting a customized error message
*
* @static
* @param string $message
* @return PMA_Message
*/
static public function rawError($message)
{
return PMA_Message::raw($message, PMA_Message::ERROR);
}
/**
* get PMA_Message of type notice with custom content
*
* shorthand for getting a customized notice message
*
* @static
* @param string $message
* @return PMA_Message
*/
static public function rawNotice($message)
{
return PMA_Message::raw($message, PMA_Message::NOTICE);
}
/**
* get PMA_Message of type success with custom content
*
* shorthand for getting a customized success message
*
* @static
* @param string $message
* @return PMA_Message
*/
static public function rawSuccess($message)
{
return PMA_Message::raw($message, PMA_Message::SUCCESS);
}
/**
* returns whether this message is a success message or not
* and optionaly makes this message a success message
*
* @param boolean $set
* @return boolean whether this is a success message or not
*/
public function isSuccess($set = false)
{
if ($set) {
$this->setNumber(PMA_Message::SUCCESS);
}
return $this->getNumber() === PMA_Message::SUCCESS;
}
/**
* returns whether this message is a notice message or not
* and optionally makes this message a notice message
*
* @param boolean $set
* @return boolean whether this is a notice message or not
*/
public function isNotice($set = false)
{
if ($set) {
$this->setNumber(PMA_Message::NOTICE);
}
return $this->getNumber() === PMA_Message::NOTICE;
}
/**
* returns whether this message is an error message or not
* and optionally makes this message an error message
*
* @param boolean $set
* @return boolean whether this is an error message or not
*/
public function isError($set = false)
{
if ($set) {
$this->setNumber(PMA_Message::ERROR);
}
return $this->getNumber() === PMA_Message::ERROR;
}
/**
* set raw message (overrides string)
*
* @param string $message
* @param boolean $sanitize whether to sanitize $message or not
*/
public function setMessage($message, $sanitize = false)
{
if ($sanitize) {
$message = PMA_Message::sanitize($message);
}
$this->_message = $message;
}
/**
* set string (does not take effect if raw message is set)
*
* @param string $_string
* @param boolean $sanitize whether to sanitize $string or not
*/
public function setString($_string, $sanitize = true)
{
if ($sanitize) {
$_string = PMA_Message::sanitize($_string);
}
$this->_string = $_string;
}
/**
* set message type number
*
* @param integer $number
*/
public function setNumber($number)
{
$this->_number = $number;
}
/**
* add parameter, usually in conjunction with strings
*
* usage
* <code>
* $message->addParam('strLocale', false);
* $message->addParam('[em]some string[/em]');
* $message->addParam('<img src="img" />', false);
* </code>
*
* @param mixed $param
* @param boolean $raw
*/
public function addParam($param, $raw = true)
{
if ($param instanceof PMA_Message) {
$this->_params[] = $param;
} elseif ($raw) {
$this->_params[] = htmlspecialchars($param);
} else {
$this->_params[] = PMA_Message::notice($param);
}
}
/**
* add another string to be concatenated on displaying
*
* @param string $string to be added
* @param string $separator to use between this and previous string/message
*/
public function addString($string, $separator = ' ')
{
$this->_added_messages[] = $separator;
$this->_added_messages[] = PMA_Message::notice($string);
}
/**
* add a bunch of messages at once
*
* @param array $messages to be added
* @param string $separator to use between this and previous string/message
*/
public function addMessages($messages, $separator = ' ')
{
foreach ($messages as $message) {
$this->addMessage($message, $separator);
}
}
/**
* add another raw message to be concatenated on displaying
*
* @param mixed $message to be added
* @param string $separator to use between this and previous string/message
*/
public function addMessage($message, $separator = ' ')
{
if (strlen($separator)) {
$this->_added_messages[] = $separator;
}
if ($message instanceof PMA_Message) {
$this->_added_messages[] = $message;
} else {
$this->_added_messages[] = PMA_Message::rawNotice($message);
}
}
/**
* set all params at once, usually used in conjunction with string
*
* @param array $params
* @param boolean $sanitize
*/
public function setParams($params, $sanitize = false)
{
if ($sanitize) {
$params = PMA_Message::sanitize($params);
}
$this->_params = $params;
}
/**
* return all parameters
*
* @return array
*/
public function getParams()
{
return $this->_params;
}
/**
* return all added messages
*
* @return array
*/
public function getAddedMessages()
{
return $this->_added_messages;
}
/**
* Sanitizes $message
*
* @static
* @param mixed $message the message(s)
* @return mixed the sanitized message(s)
* @access public
*/
static public function sanitize($message)
{
if (is_array($message)) {
foreach ($message as $key => $val) {
$message[$key] = PMA_Message::sanitize($val);
}
return $message;
}
return htmlspecialchars($message);
}
/**
* decode $message, taking into account our special codes
* for formatting
*
* @static
* @param string $message the message
* @return string the decoded message
* @access public
*/
static public function decodeBB($message)
{
return PMA_sanitize($message, false, true);
}
/**
* wrapper for sprintf()
*
* @return string formatted
*/
static public function format()
{
$params = func_get_args();
if (isset($params[1]) && is_array($params[1])) {
array_unshift($params[1], $params[0]);
$params = $params[1];
}
return call_user_func_array('sprintf', $params);
}
/**
* returns unique PMA_Message::$_hash, if not exists it will be created
*
* @return string PMA_Message::$_hash
*/
public function getHash()
{
if (null === $this->_hash) {
$this->_hash = md5(
$this->getNumber() .
$this->_string .
$this->_message
);
}
return $this->_hash;
}
/**
* returns compiled message
*
* @return string complete message
*/
public function getMessage()
{
$message = $this->_message;
if (0 === strlen($message)) {
$string = $this->getString();
if (isset($GLOBALS[$string])) {
$message = $GLOBALS[$string];
} elseif (0 === strlen($string)) {
$message = '';
} else {
$message = $string;
}
}
if (count($this->getParams()) > 0) {
$message = PMA_Message::format($message, $this->getParams());
}
$message = PMA_Message::decodeBB($message);
foreach ($this->getAddedMessages() as $add_message) {
$message .= $add_message;
}
return $message;
}
/**
* returns PMA_Message::$_string
*
* @return string PMA_Message::$_string
*/
public function getString()
{
return $this->_string;
}
/**
* returns PMA_Message::$_number
*
* @return integer PMA_Message::$_number
*/
public function getNumber()
{
return $this->_number;
}
/**
* returns level of message
*
* @return string level of message
*/
public function getLevel()
{
return PMA_Message::$level[$this->getNumber()];
}
/**
* Displays the message in HTML
*
*/
public function display()
{
echo $this->getDisplay();
$this->isDisplayed(true);
}
/**
* returns HTML code for displaying this message
*
*
* @return string whole message box
*/
public function getDisplay()
{
return '<div class="' . $this->getLevel() . '">'
. $this->getMessage() . '</div>';
}
/**
* sets and returns whether the message was displayed or not
*
* @param boolean $is_displayed
* @return boolean PMA_Message::$_is_displayed
*/
public function isDisplayed($is_displayed = false)
{
if ($is_displayed) {
$this->_is_displayed = true;
}
return $this->_is_displayed;
}
}
?>

View File

@ -0,0 +1,94 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* TCPDF wrapper class.
*/
require_once './libraries/tcpdf/tcpdf.php';
/**
* PDF font to use.
*/
define('PMA_PDF_FONT', 'DejaVuSans');
/**
* PDF export base class providing basic configuration.
*/
class PMA_PDF extends TCPDF
{
var $footerset;
var $Alias = array();
public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false)
{
parent::__construct();
$this->SetAuthor('phpMyAdmin ' . PMA_VERSION);
$this->AliasNbPages();
$this->AddFont('DejaVuSans', '', 'dejavusans.php');
$this->AddFont('DejaVuSans', 'B', 'dejavusansb.php');
$this->SetFont(PMA_PDF_FONT, '', 14);
$this->setFooterFont(array(PMA_PDF_FONT, '', 14));
}
/**
* This function must be named "Footer" to work with the TCPDF library
*/
function Footer()
{
// Check if footer for this page already exists
if (!isset($this->footerset[$this->page])) {
$this->SetY(-15);
$this->SetFont(PMA_PDF_FONT, '', 14);
$this->Cell(0, 6, __('Page number:') . ' ' . $this->getAliasNumPage() . '/' . $this->getAliasNbPages(), 'T', 0, 'C');
$this->Cell(0, 6, PMA_localisedDate(), 0, 1, 'R');
$this->SetY(20);
// set footerset
$this->footerset[$this->page] = 1;
}
}
/**
* Function to set alias which will be expanded on page rendering.
*/
function SetAlias($name, $value)
{
$this->Alias[$this->UTF8ToUTF16BE($name)] = $this->UTF8ToUTF16BE($value);
}
/**
* Improved with alias expading.
*/
function _putpages()
{
if (count($this->Alias) > 0) {
$nb = count($this->pages);
for ($n = 1;$n <= $nb;$n++) {
$this->pages[$n] = strtr($this->pages[$n], $this->Alias);
}
}
parent::_putpages();
}
/**
* Displays an error message
*
* @param string $error_message the error mesage
*/
function Error($error_message = '')
{
include './libraries/header.inc.php';
PMA_Message::error(__('Error while creating PDF:') . ' ' . $error_message)->display();
include './libraries/footer.inc.php';
}
/**
* Sends file as a download to user.
*/
function Download($filename)
{
$pdfData = $this->getPDFData();
PMA_download_header($filename, 'application/pdf', strlen($pdfData));
echo $pdfData;
}
}

View File

@ -0,0 +1,102 @@
<?php
/**
* Enter description here...
* @package PhpMyAdmin
*
*/
/**
* Database listing.
*/
require_once './libraries/List_Database.class.php';
/**
* phpMyAdmin main Controller
*
*
*
* @package PhpMyAdmin
*/
class PMA
{
/**
* Holds database list
*
* @var PMA_List_Database
*/
protected $databases = null;
/**
* DBMS user link
*
* @var resource
*/
protected $userlink = null;
/**
* DBMS control link
*
* @var resource
*/
protected $controllink = null;
/**
* magic access to protected/inaccessible members/properties
*
* @see http://php.net/language.oop5.overloading
*
* @param string $param
* @return mixed
*/
public function __get($param)
{
switch ($param) {
case 'databases' :
return $this->getDatabaseList();
break;
case 'userlink' :
return $this->userlink;
break;
case 'controllink' :
return $this->controllink;
break;
}
return null;
}
/**
* magic access to protected/inaccessible members/properties
*
* @see http://php.net/language.oop5.overloading
*
* @param string $param
* @param mixed $value
*/
public function __set($param, $value)
{
switch ($param) {
case 'userlink' :
$this->userlink = $value;
break;
case 'controllink' :
$this->controllink = $value;
break;
}
}
/**
* Accessor to PMA::$databases
*
* @return PMA_List_Databases
*/
public function getDatabaseList()
{
if (null === $this->databases) {
$this->databases = new PMA_List_Database($this->userlink, $this->controllink);
}
return $this->databases;
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Library for extracting information about the partitions
*
* @package PhpMyAdmin
*/
/**
* base Partition Class
* @package PhpMyAdmin
*/
class PMA_Partition
{
/**
* returns array of partition names for a specific db/table
*
* @access public
* @return array of partition names
*/
static public function getPartitionNames($db, $table)
{
if (PMA_Partition::havePartitioning()) {
return PMA_DBI_fetch_result("select `PARTITION_NAME` from `information_schema`.`PARTITIONS` where `TABLE_SCHEMA` = '" . $db . "' and `TABLE_NAME` = '" . $table . "'");
} else {
return array();
}
}
/**
* checks if MySQL server supports partitioning
*
* @static
* @staticvar boolean $have_partitioning
* @staticvar boolean $already_checked
* @access public
* @return boolean
*/
static public function havePartitioning()
{
static $have_partitioning = false;
static $already_checked = false;
if (! $already_checked) {
$have_partitioning = PMA_MYSQL_INT_VERSION >= 50100 && PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'have_partitioning';");
$already_checked = true;
}
return $have_partitioning;
}
}
?>

View File

@ -0,0 +1,197 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
require_once './libraries/Message.class.php';
/**
* Handles the recently used tables.
*
* @TODO Change the release version in table pma_recent (#recent in Documentation.html)
*
* @package PhpMyAdmin
*/
class PMA_RecentTable
{
/**
* Defines the internal PMA table which contains recent tables.
*
* @access private
* @var string
*/
private $pma_table;
/**
* Reference to session variable containing recently used tables.
*
* @access public
* @var array
*/
public $tables;
/**
* PMA_RecentTable instance.
*
* @var PMA_RecentTable
*/
private static $_instance;
public function __construct()
{
if (strlen($GLOBALS['cfg']['Server']['pmadb']) &&
strlen($GLOBALS['cfg']['Server']['recent'])) {
$this->pma_table = PMA_backquote($GLOBALS['cfg']['Server']['pmadb']) .".".
PMA_backquote($GLOBALS['cfg']['Server']['recent']);
}
$server_id = $GLOBALS['server'];
if (! isset($_SESSION['tmp_user_values']['recent_tables'][$server_id])) {
$_SESSION['tmp_user_values']['recent_tables'][$server_id] =
isset($this->pma_table) ? $this->getFromDb() : array();
}
$this->tables =& $_SESSION['tmp_user_values']['recent_tables'][$server_id];
}
/**
* Returns class instance.
*
* @return PMA_RecentTable
*/
public static function getInstance()
{
if (is_null(self::$_instance)) {
self::$_instance = new PMA_RecentTable();
}
return self::$_instance;
}
/**
* Returns recently used tables from phpMyAdmin database.
*
*
* @return array
*/
public function getFromDb()
{
// Read from phpMyAdmin database, if recent tables is not in session
$sql_query
= " SELECT `tables` FROM " . $this->pma_table .
" WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
$row = PMA_DBI_fetch_array(PMA_query_as_controluser($sql_query));
if (isset($row[0])) {
return json_decode($row[0], true);
} else {
return array();
}
}
/**
* Save recent tables into phpMyAdmin database.
*
*
* @return true|PMA_Message
*/
public function saveToDb()
{
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query
= " REPLACE INTO " . $this->pma_table . " (`username`, `tables`)" .
" VALUES ('" . $username . "', '" . PMA_sqlAddSlashes(json_encode($this->tables)) . "')";
$success = PMA_DBI_try_query($sql_query, $GLOBALS['controllink']);
if (!$success) {
$message = PMA_Message::error(__('Could not save recent table'));
$message->addMessage('<br /><br />');
$message->addMessage(PMA_Message::rawError(PMA_DBI_getError($GLOBALS['controllink'])));
return $message;
}
return true;
}
/**
* Trim recent table according to the LeftRecentTable configuration.
*
* @return boolean True if trimming occurred
*/
public function trim()
{
$max = max($GLOBALS['cfg']['LeftRecentTable'], 0);
$trimming_occured = count($this->tables) > $max;
while (count($this->tables) > $max) {
array_pop($this->tables);
}
return $trimming_occured;
}
/**
* Return options for HTML select.
*
* @return string
*/
public function getHtmlSelectOption()
{
// trim and save, in case where the configuration is changed
if ($this->trim() && isset($this->pma_table)) {
$this->saveToDb();
}
$html = '<option value="">(' . __('Recent tables') . ') ...</option>';
if (count($this->tables)) {
foreach ($this->tables as $table) {
$html .= '<option value="' . htmlspecialchars(json_encode($table)) . '">' .
htmlspecialchars('`' . $table['db'] . '`.`' . $table['table'] . '`') . '</option>';
}
} else {
$html .= '<option value="">' . __('There are no recent tables') . '</option>';
}
return $html;
}
/**
* Return HTML select.
*
* @return string
*/
public function getHtmlSelect()
{
$html = '<input type="hidden" name="goto" id="LeftDefaultTabTable" value="' .
htmlspecialchars($GLOBALS['cfg']['LeftDefaultTabTable']) . '" />';
$html .= '<select name="selected_recent_table" id="recentTable">';
$html .= $this->getHtmlSelectOption();
$html .= '</select>';
return $html;
}
/**
* Add recently used tables.
*
* @param string $db Database name where the table is located
* @param string $table Table name
*
* @return true|PMA_Message True if success, PMA_Message if not
*/
public function add($db, $table)
{
$table_arr = array();
$table_arr['db'] = $db;
$table_arr['table'] = $table;
// add only if this is new table
if (! isset($this->tables[0]) || $this->tables[0] != $table_arr) {
array_unshift($this->tables, $table_arr);
$this->tables = array_merge(array_unique($this->tables, SORT_REGULAR));
$this->trim();
if (isset($this->pma_table)) {
return $this->saveToDb();
}
}
return true;
}
}
?>

View File

@ -0,0 +1,420 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Library for extracting information about the available storage engines
*
* @package PhpMyAdmin
*/
/**
* defines
*/
define('PMA_ENGINE_SUPPORT_NO', 0);
define('PMA_ENGINE_SUPPORT_DISABLED', 1);
define('PMA_ENGINE_SUPPORT_YES', 2);
define('PMA_ENGINE_SUPPORT_DEFAULT', 3);
define('PMA_ENGINE_DETAILS_TYPE_PLAINTEXT', 0);
define('PMA_ENGINE_DETAILS_TYPE_SIZE', 1);
define('PMA_ENGINE_DETAILS_TYPE_NUMERIC', 2); //Has no effect yet...
define('PMA_ENGINE_DETAILS_TYPE_BOOLEAN', 3); // 'ON' or 'OFF'
/**
* base Storage Engine Class
* @package PhpMyAdmin
*/
class PMA_StorageEngine
{
/**
* @var string engine name
*/
var $engine = 'dummy';
/**
* @var string engine title/description
*/
var $title = 'PMA Dummy Engine Class';
/**
* @var string engine lang description
*/
var $comment = 'If you read this text inside phpMyAdmin, something went wrong...';
/**
* @var integer engine supported by current server
*/
var $support = PMA_ENGINE_SUPPORT_NO;
/**
* returns array of storage engines
*
* @static
* @staticvar array $storage_engines storage engines
* @access public
* @return array of storage engines
*/
static public function getStorageEngines()
{
static $storage_engines = null;
if (null == $storage_engines) {
if (PMA_DRIZZLE) {
$sql = "SELECT
p.plugin_name AS Engine,
(CASE
WHEN p.plugin_name = @@storage_engine THEN 'DEFAULT'
WHEN p.is_active THEN 'YES'
ELSE 'DISABLED' END) AS Support,
m.module_description AS Comment
FROM data_dictionary.plugins p
JOIN data_dictionary.modules m USING (module_name)
WHERE p.plugin_type = 'StorageEngine'
AND p.plugin_name NOT IN ('FunctionEngine', 'schema')";
$storage_engines = PMA_DBI_fetch_result($sql, 'Engine');
} else {
$storage_engines = PMA_DBI_fetch_result('SHOW STORAGE ENGINES', 'Engine');
}
}
return $storage_engines;
}
/**
* returns HTML code for storage engine select box
*
* @param string $name The name of the select form element
* @param string $id The ID of the form field
* @param string $selected The selected engine
* @param boolean $offerUnavailableEngines Should unavailable storage engines be offered?
*
* @static
* @return string html selectbox
*/
static public function getHtmlSelect($name = 'engine', $id = null,
$selected = null, $offerUnavailableEngines = false)
{
$selected = strtolower($selected);
$output = '<select name="' . $name . '"'
. (empty($id) ? '' : ' id="' . $id . '"') . '>' . "\n";
foreach (PMA_StorageEngine::getStorageEngines() as $key => $details) {
// Don't show PERFORMANCE_SCHEMA engine (MySQL 5.5)
// Don't show MyISAM for Drizzle (allowed only for temporary tables)
if (! $offerUnavailableEngines
&& ($details['Support'] == 'NO'
|| $details['Support'] == 'DISABLED'
|| $details['Engine'] == 'PERFORMANCE_SCHEMA')
|| (PMA_DRIZZLE && $details['Engine'] == 'MyISAM')
) {
continue;
}
$output .= ' <option value="' . htmlspecialchars($key). '"'
. (empty($details['Comment'])
? '' : ' title="' . htmlspecialchars($details['Comment']) . '"')
. (strtolower($key) == $selected || (empty($selected) && $details['Support'] == 'DEFAULT')
? ' selected="selected"' : '') . '>' . "\n"
. ' ' . htmlspecialchars($details['Engine']) . "\n"
. ' </option>' . "\n";
}
$output .= '</select>' . "\n";
return $output;
}
/**
* public static final PMA_StorageEngine getEngine()
*
* Loads the corresponding engine plugin, if available.
*
* @param string $engine The engine ID
*
* @return object The engine plugin
*/
static public function getEngine($engine)
{
$engine = str_replace('/', '', str_replace('.', '', $engine));
$engine_lowercase_filename = strtolower($engine);
if (file_exists('./libraries/engines/' . $engine_lowercase_filename . '.lib.php')
&& include_once './libraries/engines/' . $engine_lowercase_filename . '.lib.php'
) {
$class_name = 'PMA_StorageEngine_' . $engine;
$engine_object = new $class_name($engine);
} else {
$engine_object = new PMA_StorageEngine($engine);
}
return $engine_object;
}
/**
* return true if given engine name is supported/valid, otherwise false
*
* @param string $engine name of engine
*
* @static
* @return boolean whether $engine is valid or not
*/
static public function isValid($engine)
{
if ($engine == "PBMS") {
return true;
}
$storage_engines = PMA_StorageEngine::getStorageEngines();
return isset($storage_engines[$engine]);
}
/**
* returns as HTML table of the engine's server variables
*
* @return string The table that was generated based on the retrieved information
*/
function getHtmlVariables()
{
$odd_row = false;
$ret = '';
foreach ($this->getVariablesStatus() as $details) {
$ret .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">' . "\n"
. ' <td>' . "\n";
if (! empty($details['desc'])) {
$ret .= ' ' . PMA_showHint($details['desc']) . "\n";
}
$ret .= ' </td>' . "\n"
. ' <th>' . htmlspecialchars($details['title']) . '</th>' . "\n"
. ' <td class="value">';
switch ($details['type']) {
case PMA_ENGINE_DETAILS_TYPE_SIZE:
$parsed_size = $this->resolveTypeSize($details['value']);
$ret .= $parsed_size[0] . '&nbsp;' . $parsed_size[1];
unset($parsed_size);
break;
case PMA_ENGINE_DETAILS_TYPE_NUMERIC:
$ret .= PMA_formatNumber($details['value']) . ' ';
break;
default:
$ret .= htmlspecialchars($details['value']) . ' ';
}
$ret .= '</td>' . "\n"
. '</tr>' . "\n";
$odd_row = ! $odd_row;
}
if (! $ret) {
$ret = '<p>' . "\n"
. ' ' . __('There is no detailed status information available for this storage engine.') . "\n"
. '</p>' . "\n";
} else {
$ret = '<table class="data">' . "\n" . $ret . '</table>' . "\n";
}
return $ret;
}
/**
* returns the engine specific handling for
* PMA_ENGINE_DETAILS_TYPE_SIZE type variables.
*
* This function should be overridden when
* PMA_ENGINE_DETAILS_TYPE_SIZE type needs to be
* handled differently for a particular engine.
*
* @return string the formatted value and its unit
*/
function resolveTypeSize($value)
{
return PMA_formatByteDown($value);
}
/**
* returns array with detailed info about engine specific server variables
*
* @return array with detailed info about specific engine server variables
*/
function getVariablesStatus()
{
$variables = $this->getVariables();
$like = $this->getVariablesLikePattern();
if ($like) {
$like = " LIKE '" . $like . "' ";
} else {
$like = '';
}
$mysql_vars = array();
$sql_query = 'SHOW GLOBAL VARIABLES ' . $like . ';';
$res = PMA_DBI_query($sql_query);
while ($row = PMA_DBI_fetch_assoc($res)) {
if (isset($variables[$row['Variable_name']])) {
$mysql_vars[$row['Variable_name']] = $variables[$row['Variable_name']];
} elseif (! $like
&& strpos(strtolower($row['Variable_name']), strtolower($this->engine)) !== 0) {
continue;
}
$mysql_vars[$row['Variable_name']]['value'] = $row['Value'];
if (empty($mysql_vars[$row['Variable_name']]['title'])) {
$mysql_vars[$row['Variable_name']]['title'] = $row['Variable_name'];
}
if (! isset($mysql_vars[$row['Variable_name']]['type'])) {
$mysql_vars[$row['Variable_name']]['type'] = PMA_ENGINE_DETAILS_TYPE_PLAINTEXT;
}
}
PMA_DBI_free_result($res);
return $mysql_vars;
}
function engine_init() {}
/**
* Constructor
*
* @param string $engine The engine ID
*/
function __construct($engine)
{
$storage_engines = PMA_StorageEngine::getStorageEngines();
if (! empty($storage_engines[$engine])) {
$this->engine = $engine;
$this->title = $storage_engines[$engine]['Engine'];
$this->comment
= (isset($storage_engines[$engine]['Comment'])
? $storage_engines[$engine]['Comment']
: '');
switch ($storage_engines[$engine]['Support']) {
case 'DEFAULT':
$this->support = PMA_ENGINE_SUPPORT_DEFAULT;
break;
case 'YES':
$this->support = PMA_ENGINE_SUPPORT_YES;
break;
case 'DISABLED':
$this->support = PMA_ENGINE_SUPPORT_DISABLED;
break;
case 'NO':
default:
$this->support = PMA_ENGINE_SUPPORT_NO;
}
} else {
$this->engine_init();
}
}
/**
* public String getTitle()
*
* Reveals the engine's title
*
* @return string The title
*/
function getTitle()
{
return $this->title;
}
/**
* public String getComment()
*
* Fetches the server's comment about this engine
*
* @return string The comment
*/
function getComment()
{
return $this->comment;
}
/**
* public String getSupportInformationMessage()
*
* @return string The localized message.
*/
function getSupportInformationMessage()
{
switch ($this->support) {
case PMA_ENGINE_SUPPORT_DEFAULT:
$message = __('%s is the default storage engine on this MySQL server.');
break;
case PMA_ENGINE_SUPPORT_YES:
$message = __('%s is available on this MySQL server.');
break;
case PMA_ENGINE_SUPPORT_DISABLED:
$message = __('%s has been disabled for this MySQL server.');
break;
case PMA_ENGINE_SUPPORT_NO:
default:
$message = __('This MySQL server does not support the %s storage engine.');
}
return sprintf($message, htmlspecialchars($this->title));
}
/**
* public string[][] getVariables()
*
* Generates a list of MySQL variables that provide information about this
* engine. This function should be overridden when extending this class
* for a particular engine.
*
* @abstract
* @return Array The list of variables.
*/
function getVariables()
{
return array();
}
/**
* returns string with filename for the MySQL helppage
* about this storage engne
*
* @return string mysql helppage filename
*/
function getMysqlHelpPage()
{
return $this->engine . '-storage-engine';
}
/**
* public string getVariablesLikePattern()
*
* @abstract
* @return string SQL query LIKE pattern
*/
function getVariablesLikePattern()
{
return false;
}
/**
* public String[] getInfoPages()
*
* Returns a list of available information pages with labels
*
* @abstract
* @return array The list
*/
function getInfoPages()
{
return array();
}
/**
* public String getPage()
*
* Generates the requested information page
*
* @param string $id The page ID
*
* @abstract
* @return string The page
* boolean or false on error.
*/
function getPage($id)
{
return false;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,445 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* hold PMA_Theme class
*
* @package PhpMyAdmin
*/
/**
* handles theme
*
* @todo add the possibility to make a theme depend on another theme and by default on original
* @todo make all components optional - get missing components from 'parent' theme
* @todo make css optionally replacing 'parent' css or extending it (by appending at the end)
* @todo add an optional global css file - which will be used for both frames
*
* @package PhpMyAdmin
*/
class PMA_Theme
{
/**
* @var string theme version
* @access protected
*/
var $version = '0.0.0.0';
/**
* @var string theme name
* @access protected
*/
var $name = '';
/**
* @var string theme id
* @access protected
*/
var $id = '';
/**
* @var string theme path
* @access protected
*/
var $path = '';
/**
* @var string image path
* @access protected
*/
var $img_path = '';
/**
* @var array valid css types
* @access protected
*/
var $types = array('left', 'right', 'print');
/**
* @var integer last modification time for info file
* @access protected
*/
var $mtime_info = 0;
/**
* needed because sometimes, the mtime for different themes
* is identical
* @var integer filesize for info file
* @access protected
*/
var $filesize_info = 0;
/**
* @access public
* @return boolean whether loading them info was successful or not
*/
function loadInfo()
{
if (! file_exists($this->getPath() . '/info.inc.php')) {
return false;
}
if ($this->mtime_info === filemtime($this->getPath() . '/info.inc.php')) {
return true;
}
@include $this->getPath() . '/info.inc.php';
// was it set correctly?
if (! isset($theme_name)) {
return false;
}
$this->mtime_info = filemtime($this->getPath() . '/info.inc.php');
$this->filesize_info = filesize($this->getPath() . '/info.inc.php');
if (isset($theme_full_version)) {
$this->setVersion($theme_full_version);
} elseif (isset($theme_generation, $theme_version)) {
$this->setVersion($theme_generation . '.' . $theme_version);
}
$this->setName($theme_name);
return true;
}
/**
* returns theme object loaded from given folder
* or false if theme is invalid
*
* @static
* @access public
* @param string $folder path to theme
* @return object PMA_Theme
*/
static public function load($folder)
{
$theme = new PMA_Theme();
$theme->setPath($folder);
if (! $theme->loadInfo()) {
return false;
}
$theme->checkImgPath();
return $theme;
}
/**
* checks image path for existance - if not found use img from original theme
*
* @access public
* @return bool
*/
function checkImgPath()
{
if (is_dir($this->getPath() . '/img/')) {
$this->setImgPath($this->getPath() . '/img/');
return true;
} elseif (is_dir($GLOBALS['cfg']['ThemePath'] . '/original/img/')) {
$this->setImgPath($GLOBALS['cfg']['ThemePath'] . '/original/img/');
return true;
} else {
trigger_error(
sprintf(__('No valid image path for theme %s found!'), $this->getName()),
E_USER_ERROR);
return false;
}
}
/**
* returns path to theme
*
* @access public
* @return string $path path to theme
*/
function getPath()
{
return $this->path;
}
/**
* returns layout file
*
* @access public
* @return string layout file
*/
function getLayoutFile()
{
return $this->getPath() . '/layout.inc.php';
}
/**
* set path to theme
*
* @access public
* @param string $path path to theme
*/
function setPath($path)
{
$this->path = trim($path);
}
/**
* sets version
*
* @access public
* @param string new version
*/
function setVersion($version)
{
$this->version = trim($version);
}
/**
* returns version
*
* @access public
* @return string version
*/
function getVersion()
{
return $this->version;
}
/**
* checks theme version agaisnt $version
* returns true if theme version is equal or higher to $version
*
* @access public
* @param string $version version to compare to
* @return boolean
*/
function checkVersion($version)
{
return version_compare($this->getVersion(), $version, 'lt');
}
/**
* sets name
*
* @access public
* @param string $name new name
*/
function setName($name)
{
$this->name = trim($name);
}
/**
* returns name
*
* @access public
* @return string name
*/
function getName()
{
return $this->name;
}
/**
* sets id
*
* @access public
* @param string $id new id
*/
function setId($id)
{
$this->id = trim($id);
}
/**
* returns id
*
* @access public
* @return string id
*/
function getId()
{
return $this->id;
}
/**
* @access public
* @param string path to images for this theme
*/
function setImgPath($path)
{
$this->img_path = $path;
}
/**
* @access public
* @return string image path for this theme
*/
function getImgPath()
{
return $this->img_path;
}
/**
* load css (send to stdout, normally the browser)
*
* @access public
* @param string $type left, right or print
* @return bool
*/
function loadCss(&$type)
{
if (empty($type) || ! in_array($type, $this->types)) {
$type = 'left';
}
if ($type == 'right') {
echo PMA_SQP_buildCssData();
}
$_css_file = $this->getPath()
. '/css/theme_' . $type . '.css.php';
if (! file_exists($_css_file)) {
return false;
}
if ($GLOBALS['text_dir'] === 'ltr') {
$right = 'right';
$left = 'left';
} else {
$right = 'left';
$left = 'right';
}
include $_css_file;
if ($type != 'print') {
$_sprites_data_file = $this->getPath() . '/sprites.lib.php';
$_sprites_css_file = './themes/sprites.css.php';
if ( (file_exists($_sprites_data_file) && is_readable($_sprites_data_file))
&& (file_exists($_sprites_css_file) && is_readable($_sprites_css_file))
) {
include $_sprites_data_file;
include $_sprites_css_file;
}
}
return true;
}
/**
* prints out the preview for this theme
*
* @access public
*/
function printPreview()
{
echo '<div class="theme_preview">';
echo '<h2>' . htmlspecialchars($this->getName())
.' (' . htmlspecialchars($this->getVersion()) . ')</h2>';
echo '<p>';
echo '<a target="_top" class="take_theme" '
.'name="' . htmlspecialchars($this->getId()) . '" '
. 'href="index.php'.PMA_generate_common_url(array(
'set_theme' => $this->getId()
)) . '">';
if (@file_exists($this->getPath() . '/screen.png')) {
// if screen exists then output
echo '<img src="' . $this->getPath() . '/screen.png" border="1"'
.' alt="' . htmlspecialchars($this->getName()) . '"'
.' title="' . htmlspecialchars($this->getName()) . '" /><br />';
} else {
echo __('No preview available.');
}
echo '[ <strong>' . __('take it') . '</strong> ]</a>'
.'</p>'
.'</div>';
}
/**
* Remove filter for IE.
*
* @return string CSS code.
*/
function getCssIEClearFilter() {
return PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER >= 6 && PMA_USR_BROWSER_VER <= 8
? 'filter: none'
: '';
}
/**
* Generates code for CSS gradient using various browser extensions.
*
* @param string $start_color Color of gradient start, hex value without #
* @param string $end_color Color of gradient end, hex value without #
*
* @return string CSS code.
*/
function getCssGradient($start_color, $end_color)
{
$result = array();
// Opera 9.5+, IE 9
$result[] = 'background-image: url(./themes/svg_gradient.php?from=' . $start_color . '&to=' . $end_color . ');';
$result[] = 'background-size: 100% 100%;';
// Safari 4-5, Chrome 1-9
$result[] = 'background: -webkit-gradient(linear, left top, left bottom, from(#' . $start_color . '), to(#' . $end_color . '));';
// Safari 5.1, Chrome 10+
$result[] = 'background: -webkit-linear-gradient(top, #' . $start_color . ', #' . $end_color . ');';
// Firefox 3.6+
$result[] = 'background: -moz-linear-gradient(top, #' . $start_color . ', #' . $end_color . ');';
// IE 10
$result[] = 'background: -ms-linear-gradient(top, #' . $start_color . ', #' . $end_color . ');';
// Opera 11.10
$result[] = 'background: -o-linear-gradient(top, #' . $start_color . ', #' . $end_color . ');';
// IE 6-8
if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER >= 6 && PMA_USR_BROWSER_VER <= 8) {
$result[] = 'filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#' . $start_color . '", endColorstr="#' . $end_color . '");';
}
return implode("\n", $result);
}
/**
* Returns CSS styles for CodeMirror editor based on query formatter colors.
*
* @return string CSS code.
*/
function getCssCodeMirror()
{
$result[] = 'span.cm-keyword, span.cm-statement-verb {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_reservedWord'] . ';';
$result[] = '}';
$result[] = 'span.cm-variable {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_identifier'] . ';';
$result[] = '}';
$result[] = 'span.cm-comment {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['comment'] . ';';
$result[] = '}';
$result[] = 'span.cm-mysql-string {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['quote'] . ';';
$result[] = '}';
$result[] = 'span.cm-operator {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['punct'] . ';';
$result[] = '}';
$result[] = 'span.cm-mysql-word {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_identifier'] . ';';
$result[] = '}';
$result[] = 'span.cm-builtin {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_functionName'] . ';';
$result[] = '}';
$result[] = 'span.cm-variable-2 {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_columnType'] . ';';
$result[] = '}';
$result[] = 'span.cm-variable-3 {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['alpha_columnAttrib'] . ';';
$result[] = '}';
$result[] = 'span.cm-separator {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['punct'] . ';';
$result[] = '}';
$result[] = 'span.cm-number {';
$result[] = ' color: ' . $GLOBALS['cfg']['SQP']['fmtColor']['digit_integer'] . ';';
$result[] = '}';
return implode("\n", $result);
}
}
?>

View File

@ -0,0 +1,380 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
*
* @package PhpMyAdmin
*/
class PMA_Theme_Manager
{
/**
* @var string path to theme folder
* @access protected
*/
var $_themes_path;
/**
* @var array available themes
*/
var $themes = array();
/**
* @var string cookie name
*/
var $cookie_name = 'pma_theme';
/**
* @var boolean
*/
var $per_server = false;
/**
* @var string name of active theme
*/
var $active_theme = '';
/**
* @var PMA_Theme PMA_Theme active theme
*/
var $theme = null;
/**
* @var string
*/
var $theme_default = 'original';
function __construct()
{
$this->init();
}
/**
* sets path to folder containing the themes
*
* @param string $path path to themes folder
* @return boolean success
*/
function setThemesPath($path)
{
if (! $this->_checkThemeFolder($path)) {
return false;
}
$this->_themes_path = trim($path);
return true;
}
/**
* @public
* @return string
*/
function getThemesPath()
{
return $this->_themes_path;
}
/**
* sets if there are different themes per server
*
* @param boolean $per_server
*/
function setThemePerServer($per_server)
{
$this->per_server = (bool) $per_server;
}
function init()
{
$this->themes = array();
$this->theme_default = 'original';
$this->active_theme = '';
if (! $this->setThemesPath($GLOBALS['cfg']['ThemePath'])) {
return false;
}
$this->setThemePerServer($GLOBALS['cfg']['ThemePerServer']);
$this->loadThemes();
$this->theme = new PMA_Theme;
if (! $this->checkTheme($GLOBALS['cfg']['ThemeDefault'])) {
trigger_error(
sprintf(
__('Default theme %s not found!'),
htmlspecialchars($GLOBALS['cfg']['ThemeDefault'])
),
E_USER_ERROR
);
$GLOBALS['cfg']['ThemeDefault'] = false;
}
$this->theme_default = $GLOBALS['cfg']['ThemeDefault'];
// check if user have a theme cookie
if (! $this->getThemeCookie()
|| ! $this->setActiveTheme($this->getThemeCookie())) {
// otherwise use default theme
if ($GLOBALS['cfg']['ThemeDefault']) {
$this->setActiveTheme($GLOBALS['cfg']['ThemeDefault']);
} else {
// or original theme
$this->setActiveTheme('original');
}
}
}
function checkConfig()
{
if ($this->_themes_path != trim($GLOBALS['cfg']['ThemePath'])
|| $this->theme_default != $GLOBALS['cfg']['ThemeDefault']) {
$this->init();
} else {
// at least the theme path needs to be checked every time for new
// themes, as there is no other way at the moment to keep track of
// new or removed themes
$this->loadThemes();
}
}
function setActiveTheme($theme = null)
{
if (! $this->checkTheme($theme)) {
trigger_error(
sprintf(
__('Theme %s not found!'),
htmlspecialchars($theme)
),
E_USER_ERROR);
return false;
}
$this->active_theme = $theme;
$this->theme = $this->themes[$theme];
// need to set later
//$this->setThemeCookie();
return true;
}
/**
* @return string cookie name
*/
function getThemeCookieName()
{
// Allow different theme per server
if (isset($GLOBALS['server']) && $this->per_server) {
return $this->cookie_name . '-' . $GLOBALS['server'];
} else {
return $this->cookie_name;
}
}
/**
* returns name of theme stored in the cookie
* @return string theme name from cookie
*/
function getThemeCookie()
{
if (isset($_COOKIE[$this->getThemeCookieName()])) {
return $_COOKIE[$this->getThemeCookieName()];
}
return false;
}
/**
* save theme in cookie
*
* @return bool true
*/
function setThemeCookie()
{
$GLOBALS['PMA_Config']->setCookie($this->getThemeCookieName(), $this->theme->id,
$this->theme_default);
// force a change of a dummy session variable to avoid problems
// with the caching of phpmyadmin.css.php
$GLOBALS['PMA_Config']->set('theme-update', $this->theme->id);
return true;
}
/**
* @private
* @param string $folder
* @return boolean
*/
private function _checkThemeFolder($folder)
{
if (! is_dir($folder)) {
trigger_error(
sprintf(__('Theme path not found for theme %s!'),
htmlspecialchars($folder)),
E_USER_ERROR);
return false;
}
return true;
}
/**
* read all themes
*
* @return bool true
*/
function loadThemes()
{
$this->themes = array();
if ($handleThemes = opendir($this->getThemesPath())) {
// check for themes directory
while (false !== ($PMA_Theme = readdir($handleThemes))) {
// Skip non dirs, . and ..
if ($PMA_Theme == '.' || $PMA_Theme == '..' || ! is_dir($this->getThemesPath() . '/' . $PMA_Theme)) {
continue;
}
if (array_key_exists($PMA_Theme, $this->themes)) {
continue;
}
$new_theme = PMA_Theme::load($this->getThemesPath() . '/' . $PMA_Theme);
if ($new_theme) {
$new_theme->setId($PMA_Theme);
$this->themes[$PMA_Theme] = $new_theme;
}
} // end get themes
closedir($handleThemes);
} else {
trigger_error(
'phpMyAdmin-ERROR: cannot open themes folder: ' . $this->getThemesPath(),
E_USER_WARNING);
return false;
} // end check for themes directory
ksort($this->themes);
return true;
}
/**
* checks if given theme name is a known theme
*
* @param string $theme name fo theme to check for
* @return bool
*/
function checkTheme($theme)
{
if (! array_key_exists($theme, $this->themes)) {
return false;
}
return true;
}
/**
* returns HTML selectbox, with or without form enclosed
*
* @param boolean $form whether enclosed by from tags or not
* @return string
*/
function getHtmlSelectBox($form = true)
{
$select_box = '';
if ($form) {
$select_box .= '<form name="setTheme" method="post" action="index.php"'
.' target="_parent">';
$select_box .= PMA_generate_common_hidden_inputs();
}
$theme_preview_path= './themes.php';
$theme_preview_href = '<a href="' . $theme_preview_path . '" target="themes" class="themeselect">';
$select_box .= $theme_preview_href . __('Theme') . '</a>:' . "\n";
$select_box .= '<select name="set_theme" xml:lang="en" dir="ltr" class="autosubmit">';
foreach ($this->themes as $each_theme_id => $each_theme) {
$select_box .= '<option value="' . $each_theme_id . '"';
if ($this->active_theme === $each_theme_id) {
$select_box .= ' selected="selected"';
}
$select_box .= '>' . htmlspecialchars($each_theme->getName()) . '</option>';
}
$select_box .= '</select>';
if ($form) {
$select_box .= '<noscript><input type="submit" value="' . __('Go') . '" /></noscript>';
$select_box .= '</form>';
}
return $select_box;
}
/**
* enables backward compatibility
*/
function makeBc()
{
$GLOBALS['theme'] = $this->theme->getId();
$GLOBALS['pmaThemePath'] = $this->theme->getPath();
$GLOBALS['pmaThemeImage'] = $this->theme->getImgPath();
/**
* load layout file if exists
*/
if (file_exists($this->theme->getLayoutFile())) {
include $this->theme->getLayoutFile();
}
}
/**
* prints out preview for every theme
*
*/
function printPreviews()
{
foreach ($this->themes as $each_theme) {
$each_theme->printPreview();
} // end 'open themes'
}
/**
* returns PMA_Theme object for fall back theme
* @return object PMA_Theme
*/
function getFallBackTheme()
{
if (isset($this->themes['original'])) {
return $this->themes['original'];
}
return false;
}
/**
* prints css data
*
* @param string $type
* @return bool
*/
function printCss($type)
{
if ($this->theme->loadCss($type)) {
return true;
}
// if loading css for this theme failed, try default theme css
$fallback_theme = $this->getFallBackTheme();
if ($fallback_theme && $fallback_theme->loadCss($type)) {
return true;
}
return false;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,447 @@
# phpMyAdmin Advisory rules file
# Use only UNIX style newlines
# This file is being parsed by Advisor.class.php, which should handle syntax errors correctly.
# However, PHP Warnings and the like are being consumed by the phpMyAdmin error handler, so those won't show up
# E.g.: Justification line is empty because you used an unescape percent sign, sprintf() returns an empty string and no warning/error is shown
#
# Rule Syntax:
# 'rule' identifier[the name of the rule] eexpr [an optional precondition]
# expr [variable or value calculation used for the test]
# expr [test, if evaluted to 'true' it fires the rule. Use 'value' to insert the calculated value (without quotes)]
# string [the issue (what is the problem?)]
# string [the recommendation (how do i fix it?)]
# formatted-string '|' comma-seperated-expr [the justification (result of the calculated value / why did this rule fire?)]
# comma-seperated-expr: expr(,expr)*
# eexpr: [expr] - expr enclosed in []
# expr: a php code literal with extras:
# - variable names are replaced with their respective values
# - fired('name of rule') is replaced with true/false when given rule has been fired. Note however that this is a very simple rules engine. Rules are only checked in sequential order as they are written down here. If given rule has not been checked yet, fired() will always evaluate to false
# - 'value' is replaced with the calculated value. If it is a string, it will be put within single quotes
# - other than that you may use any php function, initialized variable or constant
#
# identifier: A string enclosed in single quotes
# string: A quoteless string, may contain HTML. Variable names enclosed in curly braces are replaced with links to directly edit this variable. e.g. {tmp_table_size}
# formatted-string: You may use classic php sprintf() string formatting here, the arguments must be appended after a trailing pipe (|) as mentioned in above syntax
# percent signs (%) are automatically escaped (%%) in the following cases: When followed by a space, dot or comma and at the end of the line)
#
# Comments start with #
#
# Queries
rule 'Uptime below one day'
Uptime
value < 86400
Uptime is less than 1 day, performance tuning may not be accurate.
To have more accurate averages it is recommended to let the server run for longer than a day before running this analyzer
The uptime is only %s | PMA_timespanFormat(Uptime)
rule 'Questions below 1,000'
Questions
value < 1000
Fewer than 1,000 questions have been run against this server. The recommendations may not be accurate.
Let the server run for a longer time until it has executed a greater amount of queries.
Current amount of Questions: %s | Questions
rule 'Percentage of slow queries' [Questions > 0 && !PMA_DRIZZLE]
Slow_queries / Questions * 100
value >= 5
There is a lot of slow queries compared to the overall amount of Queries.
You might want to increase {long_query_time} or optimize the queries listed in the slow query log
The slow query rate should be below 5%, your value is %s%. | round(value,2)
rule 'Slow query rate' [Questions > 0]
(Slow_queries / Questions * 100) / Uptime
value * 60 * 60 > 1
There is a high percentage of slow queries compared to the server uptime.
You might want to increase {long_query_time} or optimize the queries listed in the slow query log
You have a slow query rate of %s per hour, you should have less than 1% per hour. | PMA_bytime(value,2)
rule 'Long query time' [!PMA_DRIZZLE]
long_query_time
value >= 10
long_query_time is set to 10 seconds or more, thus only slow queries that take above 10 seconds are logged.
It is suggested to set {long_query_time} to a lower value, depending on your environment. Usually a value of 1-5 seconds is suggested.
long_query_time is currently set to %ds. | value
rule 'Slow query logging' [!PMA_DRIZZLE]
log_slow_queries
value == 'OFF'
The slow query log is disabled.
Enable slow query logging by setting {log_slow_queries} to 'ON'. This will help troubleshooting badly performing queries.
log_slow_queries is set to 'OFF'
#
# versions
rule 'Release Series' [!PMA_DRIZZLE]
version
substr(value,0,1) <= 5 && substr(value,2,1) < 1
The MySQL server version less than 5.1.
You should upgrade, as MySQL 5.1 has improved performance, and MySQL 5.5 even more so.
Current version: %s | value
rule 'Minor Version' [! fired('Release Series')]
version
substr(value,0,1) <= 5 && substr(value,2,1) < 1 && substr(value,4,2) < 30
Version less than 5.1.30 (the first GA release of 5.1).
You should upgrade, as recent versions of MySQL 5.1 have improved performance and MySQL 5.5 even more so.
Current version: %s | value
rule 'Minor Version' [! fired('Release Series')]
version
substr(value,0,1) == 5 && substr(value,2,1) == 5 && substr(value,4,2) < 8
Version less than 5.5.8 (the first GA release of 5.5).
You should upgrade, to a stable version of MySQL 5.5
Current version: %s | value
rule 'Distribution'
version_comment
preg_match('/source/i',value)
Version is compiled from source, not a MySQL official binary.
If you did not compile from source, you may be using a package modified by a distribution. The MySQL manual only is accurate for official MySQL binaries, not any package distributions (such as RedHat, Debian/Ubuntu etc).
'source' found in version_comment
rule 'Distribution'
version_comment
preg_match('/percona/i',value)
The MySQL manual only is accurate for official MySQL binaries.
Percona documentation is at http://www.percona.com/docs/wiki/
'percona' found in version_comment
rule 'Distribution'
version
PMA_DRIZZLE
The MySQL manual only is accurate for official MySQL binaries.
Drizzle documentation is at http://docs.drizzle.org/
Version string (%s) matches Drizzle versioning scheme | value
rule 'MySQL Architecture'
system_memory
value > 3072*1024 && !preg_match('/64/',version_compile_machine) && !preg_match('/64/',version_compile_os)
MySQL is not compiled as a 64-bit package.
Your memory capacity is above 3 GiB (assuming the Server is on localhost), so MySQL might not be able to access all of your memory. You might want to consider installing the 64-bit version of MySQL.
Available memory on this host: %s | implode(' ',PMA_formatByteDown(value*1024, 2, 2))
#
# Query cache
# Lame: 'ON' == 0 is true, so you need to compare 'ON' == '0'
rule 'Query cache disabled' [!PMA_DRIZZLE]
query_cache_size
value == 0 || query_cache_type == 'OFF' || query_cache_type == '0'
The query cache is not enabled.
The query cache is known to greatly improve performance if configured correctly. Enable it by setting {query_cache_size} to a 2 digit MiB value and setting {query_cache_type} to 'ON'. <b>Note:</b> If you are using memcached, ignore this recommendation.
query_cache_size is set to 0 or query_cache_type is set to 'OFF'
rule 'Query caching method' [!fired('Query cache disabled')]
Questions / Uptime
value > 100
Suboptimal caching method.
You are using the MySQL Query cache with a fairly high traffic database. It might be worth considering to use <a href="http://dev.mysql.com/doc/refman/5.5/en/ha-memcached.html">memcached</a> instead of the MySQL Query cache, especially if you have multiple slaves.
The query cache is enabled and the server receives %d queries per second. This rule fires if there is more than 100 queries per second. | round(value,1)
rule 'Query cache efficiency (%)' [!PMA_DRIZZLE && Com_select + Qcache_hits > 0 && !fired('Query cache disabled')]
Qcache_hits / (Com_select + Qcache_hits) * 100
value < 20
Query cache not running efficiently, it has a low hit rate.
Consider increasing {query_cache_limit}.
The current query cache hit rate of %s% is below 20% | round(value,1)
rule 'Query Cache usage' [!fired('Query cache disabled') && !PMA_DRIZZLE]
100 - Qcache_free_memory / query_cache_size * 100
value < 80
Less than 80% of the query cache is being utilized.
This might be caused by {query_cache_limit} being too low. Flushing the query cache might help as well.
The current ratio of free query cache memory to total query cache size is %s%. It should be above 80% | round(value,1)
rule 'Query cache fragmentation' [!fired('Query cache disabled') && !PMA_DRIZZLE]
Qcache_free_blocks / (Qcache_total_blocks / 2) * 100
value > 20
The query cache is considerably fragmented.
Severe fragmentation is likely to (further) increase Qcache_lowmem_prunes. This might be caused by many Query cache low memory prunes due to {query_cache_size} being too small. For a immediate but short lived fix you can flush the query cache (might lock the query cache for a long time). Carefully adjusting {query_cache_min_res_unit} to a lower value might help too, e.g. you can set it to the average size of your queries in the cache using this formula: (query_cache_size - qcache_free_memory) / qcache_queries_in_cache
The cache is currently fragmented by %s% , with 100% fragmentation meaning that the query cache is an alternating pattern of free and used blocks. This value should be below 20%. | round(value,1)
rule 'Query cache low memory prunes' [!PMA_DRIZZLE && Qcache_inserts > 0 && !fired('Query cache disabled')]
Qcache_lowmem_prunes / Qcache_inserts * 100
value > 0.1
Cached queries are removed due to low query cache memory from the query cache.
You might want to increase {query_cache_size}, however keep in mind that the overhead of maintaining the cache is likely to increase with its size, so do this in small increments and monitor the results.
The ratio of removed queries to inserted queries is %s%. The lower this value is, the better (This rules firing limit: 0.1%) | round(value,1)
rule 'Query cache max size' [!fired('Query cache disabled')]
query_cache_size
value > 1024 * 128
The query cache size is above 128 MiB. Big query caches may cause significant overhead that is required to maintain the cache.
Depending on your environment, it might be performance increasing to reduce this value.
Current query cache size: %s | implode(' ',PMA_formatByteDown(value, 2, 2))
rule 'Query cache min result size' [!fired('Query cache disabled')]
value == 1024*1024
query_cache_limit
The max size of the result set in the query cache is the default of 1 MiB.
Changing {query_cache_limit} (usually by increasing) may increase efficiency. This variable determines the maximum size a query result may have to be inserted into the query cache. If there are many query results above 1 MiB that are well cacheable (many reads, little writes) then increasing {query_cache_limit} will increase efficiency. Whereas in the case of many query results being above 1 MiB that are not very well cacheable (often invalidated due to table updates) increasing {query_cache_limit} might reduce efficiency.
query_cache_limit is set to 1 MiB
#
# Sorts
rule 'Percentage of sorts that cause temporary tables' [Sort_scan + Sort_range > 0]
Sort_merge_passes / (Sort_scan + Sort_range) * 100
value > 10
Too many sorts are causing temporary tables.
Consider increasing sort_buffer_size and/or read_rnd_buffer_size, depending on your system memory limits
%s% of all sorts cause temporary tables, this value should be lower than 10%. | round(value,1)
rule 'Rate of sorts that cause temporary tables'
Sort_merge_passes / Uptime
value * 60 * 60 > 1
Too many sorts are causing temporary tables.
Consider increasing sort_buffer_size and/or read_rnd_buffer_size, depending on your system memory limits
Temporary tables average: %s, this value should be less than 1 per hour. | PMA_bytime(value,2)
rule 'Sort rows'
Sort_rows / Uptime
value * 60 >= 1
There are lots of rows being sorted.
While there is nothing wrong with a high amount of row sorting, you might want to make sure that the queries which require a lot of sorting use indexed columns in the ORDER BY clause, as this will result in much faster sorting
Sorted rows average: %s | PMA_bytime(value,2)
# Joins, scans
rule 'Rate of joins without indexes'
(Select_range_check + Select_scan + Select_full_join) / Uptime
value * 60 * 60 > 1
There are too many joins without indexes.
This means that joins are doing full table scans. Adding indexes for the columns being used in the join conditions will greatly speed up table joins
Table joins average: %s, this value should be less than 1 per hour | PMA_bytime(value,2)
rule 'Rate of reading first index entry'
Handler_read_first / Uptime
value * 60 * 60 > 1
The rate of reading the first index entry is high.
This usually indicates frequent full index scans. Full index scans are faster than table scans but require lots of CPU cycles in big tables, if those tables that have or had high volumes of UPDATEs and DELETEs, running 'OPTIMIZE TABLE' might reduce the amount of and/or speed up full index scans. Other than that full index scans can only be reduced by rewriting queries.
Index scans average: %s, this value should be less than 1 per hour | PMA_bytime(value,2)
rule 'Rate of reading fixed position'
Handler_read_rnd / Uptime
value * 60 * 60 > 1
The rate of reading data from a fixed position is high.
This indicates that many queries need to sort results and/or do a full table scan, including join queries that do not use indexes. Add indexes where applicable.
Rate of reading fixed position average: %s, this value should be less than 1 per hour | PMA_bytime(value,2)
rule 'Rate of reading next table row'
Handler_read_rnd_next / Uptime
value * 60 * 60 > 1
The rate of reading the next table row is high.
This indicates that many queries are doing full table scans. Add indexes where applicable.
Rate of reading next table row: %s, this value should be less than 1 per hour | PMA_bytime(value,2)
# temp tables
rule 'tmp_table_size vs. max_heap_table_size'
tmp_table_size - max_heap_table_size
value !=0
tmp_table_size and max_heap_table_size are not the same.
If you have deliberately changed one of either: The server uses the lower value of either to determine the maximum size of in-memory tables. So if you wish to increase the in-memory table limit you will have to increase the other value as well.
Current values are tmp_table_size: %s, max_heap_table_size: %s | implode(' ',PMA_formatByteDown(tmp_table_size, 2, 2)), implode(' ',PMA_formatByteDown(max_heap_table_size, 2, 2))
rule 'Percentage of temp tables on disk' [Created_tmp_tables + Created_tmp_disk_tables > 0]
Created_tmp_disk_tables / (Created_tmp_tables + Created_tmp_disk_tables) * 100
value > 25
Many temporary tables are being written to disk instead of being kept in memory.
Increasing {max_heap_table_size} and {tmp_table_size} might help. However some temporary tables are always being written to disk, independent of the value of these variables. To eliminate these you will have to rewrite your queries to avoid those conditions (Within a temporary table: Presence of a BLOB or TEXT column or presence of a column bigger than 512 bytes) as mentioned in the beginning of an <a href="http://www.facebook.com/note.php?note_id=10150111255065841&comments">Article by the Pythian Group</a>
%s% of all temporary tables are being written to disk, this value should be below 25% | round(value,1)
rule 'Temp disk rate'
Created_tmp_disk_tables / Uptime
value * 60 * 60 > 1
Many temporary tables are being written to disk instead of being kept in memory.
Increasing {max_heap_table_size} and {tmp_table_size} might help. However some temporary tables are always being written to disk, independent of the value of these variables. To eliminate these you will have to rewrite your queries to avoid those conditions (Within a temporary table: Presence of a BLOB or TEXT column or presence of a column bigger than 512 bytes) as mentioned in the <a href="http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html">MySQL Documentation</a>
Rate of temporary tables being written to disk: %s, this value should be less than 1 per hour | PMA_bytime(value,2)
# I couldn't find any source on the internet that suggests a direct relation between high counts of temporary tables and any of these variables.
# Several independent Blog entries suggest (http://ronaldbradford.com/blog/more-on-understanding-sort_buffer_size-2010-05-10/ and http://www.xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size/)
# that sort_buffer_size should be left as it is. And increasing read_buffer_size is only suggested when there are a lot of
# table scans (http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_read_buffer_size and other sources) though
# setting it too high is bad too (http://www.mysqlperformanceblog.com/2007/09/17/mysql-what-read_buffer_size-value-is-optimal/).
#rule 'Temp table rate'
# Created_tmp_tables / Uptime
# value * 60 * 60 > 1
# Many intermediate temporary tables are being created.
# This may be caused by queries under certain conditions as mentioned in the <a href="http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html">MySQL Documentation</a>. Consider increasing {sort_buffer_size} (sorting), {read_rnd_buffer_size} (random read buffer, ie, post-sort), {read_buffer_size} (sequential scan).
#
# MyISAM index cache
rule 'MyISAM key buffer size' [!PMA_DRIZZLE]
key_buffer_size
value == 0
Key buffer is not initialized. No MyISAM indexes will be cached.
Set {key_buffer_size} depending on the size of your MyISAM indexes. 64M is a good start.
key_buffer_size is 0
rule 'Max % MyISAM key buffer ever used' [!PMA_DRIZZLE && key_buffer_size > 0]
Key_blocks_used * key_cache_block_size / key_buffer_size * 100
value < 95
MyISAM key buffer (index cache) % used is low.
You may need to decrease the size of {key_buffer_size}, re-examine your tables to see if indexes have been removed, or examine queries and expectations about what indexes are being used.
max % MyISAM key buffer ever used: %s%, this value should be above 95% | round(value,1)
# Don't fire if above rule fired - we don't need the same advice twice
rule 'Percentage of MyISAM key buffer used' [!PMA_DRIZZLE && key_buffer_size > 0 && !fired('max % MyISAM key buffer ever used')]
( 1 - Key_blocks_unused * key_cache_block_size / key_buffer_size) * 100
value < 95
MyISAM key buffer (index cache) % used is low.
You may need to decrease the size of {key_buffer_size}, re-examine your tables to see if indexes have been removed, or examine queries and expectations about what indexes are being used.
% MyISAM key buffer used: %s%, this value should be above 95% | round(value,1)
rule 'Percentage of index reads from memory' [!PMA_DRIZZLE && Key_read_requests > 0]
100 - (Key_reads / Key_read_requests * 100)
value < 95
The % of indexes that use the MyISAM key buffer is low.
You may need to increase {key_buffer_size}.
Index reads from memory: %s%, this value should be above 95% | round(value,1)
#
# other caches
rule 'Rate of table open' [!PMA_DRIZZLE]
Opened_tables / Uptime
value*60*60 > 10
The rate of opening tables is high.
Opening tables requires disk I/O which is costly. Increasing {table_open_cache} might avoid this.
Opened table rate: %s, this value should be less than 10 per hour | PMA_bytime(value,2)
rule 'Percentage of used open files limit' [!PMA_DRIZZLE]
Open_files / open_files_limit * 100
value > 85
The number of open files is approaching the max number of open files. You may get a "Too many open files" error.
Consider increasing {open_files_limit}, and check the error log when restarting after changing open_files_limit.
The number of opened files is at %s% of the limit. It should be below 85% | round(value,1)
rule 'Rate of open files' [!PMA_DRIZZLE]
Open_files / Uptime
value * 60 * 60 > 5
The rate of opening files is high.
Consider increasing {open_files_limit}, and check the error log when restarting after changing open_files_limit.
Opened files rate: %s, this value should be less than 5 per hour | PMA_bytime(value,2)
rule 'Immediate table locks %' [Table_locks_waited + Table_locks_immediate > 0]
Table_locks_immediate / (Table_locks_waited + Table_locks_immediate) * 100
value < 95
Too many table locks were not granted immediately.
Optimize queries and/or use InnoDB to reduce lock wait.
Immediate table locks: %s%, this value should be above 95% | round(value,1)
rule 'Table lock wait rate'
Table_locks_waited / Uptime
value * 60 * 60 > 1
Too many table locks were not granted immediately.
Optimize queries and/or use InnoDB to reduce lock wait.
Table lock wait rate: %s, this value should be less than 1 per hour | PMA_bytime(value,2)
rule 'Thread cache' [!PMA_DRIZZLE]
thread_cache_size
value < 1
Thread cache is disabled, resulting in more overhead from new connections to MySQL.
Enable the thread cache by setting {thread_cache_size} > 0.
The thread cache is set to 0
rule 'Thread cache hit rate %' [!PMA_DRIZZLE && thread_cache_size > 0]
100 - Threads_created / Connections
value < 80
Thread cache is not efficient.
Increase {thread_cache_size}.
Thread cache hitrate: %s%, this value should be above 80% | round(value,1)
rule 'Threads that are slow to launch' [!PMA_DRIZZLE && slow_launch_time > 0]
Slow_launch_threads
value > 0
There are too many threads that are slow to launch.
This generally happens in case of general system overload as it is pretty simple operations. You might want to monitor your system load carefully.
%s thread(s) took longer than %s seconds to start, it should be 0 | value, slow_launch_time
rule 'Slow launch time' [!PMA_DRIZZLE]
slow_launch_time
value > 2
Slow_launch_threads is above 2s
Set slow_launch_time to 1s or 2s to correctly count threads that are slow to launch
slow_launch_time is set to %s | value
#
#Connections
rule 'Percentage of used connections' [!PMA_DRIZZLE]
Max_used_connections / max_connections * 100
value > 80
The maximum amount of used connections is getting close to the value of max_connections.
Increase max_connections, or decrease wait_timeout so that connections that do not close database handlers properly get killed sooner. Make sure the code closes database handlers properly.
Max_used_connections is at %s% of max_connections, it should be below 80% | round(value,1)
rule 'Percentage of aborted connections'
Aborted_connects / Connections * 100
value > 1
Too many connections are aborted.
Connections are usually aborted when they cannot be authorized. <a href="http://www.mysqlperformanceblog.com/2008/08/23/how-to-track-down-the-source-of-aborted_connects/">This article</a> might help you track down the source.
%s% of all connections are aborted. This value should be below 1% | round(value,1)
rule 'Rate of aborted connections'
Aborted_connects / Uptime
value * 60 * 60 > 1
Too many connections are aborted.
Connections are usually aborted when they cannot be authorized. <a href="http://www.mysqlperformanceblog.com/2008/08/23/how-to-track-down-the-source-of-aborted_connects/">This article</a> might help you track down the source.
Aborted connections rate is at %s, this value should be less than 1 per hour | PMA_bytime(value,2)
rule 'Percentage of aborted clients'
Aborted_clients / Connections * 100
value > 2
Too many clients are aborted.
Clients are usually aborted when they did not close their connection to MySQL properly. This can be due to network issues or code not closing a database handler properly. Check your network and code.
%s% of all clients are aborted. This value should be below 2% | round(value,1)
rule 'Rate of aborted clients'
Aborted_clients / Uptime
value * 60 * 60 > 1
Too many clients are aborted.
Clients are usually aborted when they did not close their connection to MySQL properly. This can be due to network issues or code not closing a database handler properly. Check your network and code.
Aborted client rate is at %s, this value should be less than 1 per hour | PMA_bytime(value,2)
#
# InnoDB
rule 'Is InnoDB disabled?' [!PMA_DRIZZLE]
have_innodb
value != "YES"
You do not have InnoDB enabled.
InnoDB is usually the better choice for table engines.
have_innodb is set to 'value'
rule 'InnoDB log size' [innodb_buffer_pool_size > 0]
innodb_log_file_size / innodb_buffer_pool_size * 100
value < 20
The InnoDB log file size is not an appropriate size, in relation to the InnoDB buffer pool.
Especially on a system with a lot of writes to InnoDB tables you should set innodb_log_file_size to 25% of {innodb_buffer_pool_size}. However the bigger this value, the longer the recovery time will be when database crashes, so this value should not be set much higher than 256 MiB. Please note however that you cannot simply change the value of this variable. You need to shutdown the server, remove the InnoDB log files, set the new value in my.cnf, start the server, then check the error logs if everything went fine. See also <a href="http://mysqldatabaseadministration.blogspot.com/2007/01/increase-innodblogfilesize-proper-way.html">this blog entry</a>
Your InnoDB log size is at %s% in relation to the InnoDB buffer pool size, it should not be below 20% | round(value,1)
rule 'Max InnoDB log size' [innodb_buffer_pool_size > 0 && innodb_log_file_size / innodb_buffer_pool_size * 100 < 30]
innodb_log_file_size / (1024 * 1024)
value >= 128
The InnoDB log file size is inadequately large.
It is usually sufficient to set innodb_log_file_size to 25% of the size of {innodb_buffer_pool_size}. A very big innodb_log_file_size slows down the recovery time after a database crash considerably. See also <a href="http://www.mysqlperformanceblog.com/2006/07/03/choosing-proper-innodb_log_file_size/">this Article</a>. You need to shutdown the server, remove the InnoDB log files, set the new value in my.cnf, start the server, then check the error logs if everything went fine. See also <a href="http://mysqldatabaseadministration.blogspot.com/2007/01/increase-innodblogfilesize-proper-way.html">this blog entry</a>
Your absolute InnoDB log size is %s MiB | round(value,1)
rule 'InnoDB buffer pool size' [system_memory > 0]
innodb_buffer_pool_size / system_memory * 100
value < 60
Your InnoDB buffer pool is fairly small.
The InnoDB buffer pool has a profound impact on performance for InnoDB tables. Assign all your remaining memory to this buffer. For database servers that use solely InnoDB as storage engine and have no other services (e.g. a web server) running, you may set this as high as 80% of your available memory. If that is not the case, you need to carefully assess the memory consumption of your other services and non-InnoDB-Tables and set this variable accordingly. If it is set too high, your system will start swapping, which decreases performance significantly. See also <a href="http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/">this article</a>
You are currently using %s% of your memory for the InnoDB buffer pool. This rule fires if you are assigning less than 60%, however this might be perfectly adequate for your system if you don't have much InnoDB tables or other services running on the same machine. | value
#
# other
rule 'MyISAM concurrent inserts' [!PMA_DRIZZLE]
concurrent_insert
value === 0 || value === 'NEVER'
Enable concurrent_insert by setting it to 1
Setting {concurrent_insert} to 1 reduces contention between readers and writers for a given table. See also <a href="http://dev.mysql.com/doc/refman/5.5/en/concurrent-inserts.html">MySQL Documentation</a>
concurrent_insert is set to 0
# INSERT DELAYED USAGE
#Delayed_errors 0
#Delayed_insert_threads 0
#Delayed_writes 0
#Not_flushed_delayed_rows

View File

@ -0,0 +1,134 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to run config authentication (ie no authentication).
*
* @package PhpMyAdmin-Auth-Config
*/
/**
* Displays authentication form
*
* @return boolean always true
*
* @access public
*/
function PMA_auth()
{
return true;
} // end of the 'PMA_auth()' function
/**
* Gets advanced authentication settings
*
* @return boolean always true
*
* @access public
*/
function PMA_auth_check()
{
return true;
} // end of the 'PMA_auth_check()' function
/**
* Set the user and password after last checkings if required
*
* @return boolean always true
*
* @access public
*/
function PMA_auth_set_user()
{
return true;
} // end of the 'PMA_auth_set_user()' function
/**
* User is not allowed to login to MySQL -> authentication failed
*
* @global string the MySQL error message PHP returns
* @global string the connection type (persistent or not)
* @global string the MySQL server port to use
* @global string the MySQL socket port to use
* @global array the current server settings
* @global string the font face to use in case of failure
* @global string the default font size to use in case of failure
* @global string the big font size to use in case of failure
* @global boolean tell the "PMA_mysqlDie()" function headers have been
* sent
*
* @return boolean always true (no return indeed)
*
* @access public
*/
function PMA_auth_fails()
{
$conn_error = PMA_DBI_getError();
if (!$conn_error) {
$conn_error = __('Cannot connect: invalid settings.');
}
// Defines the charset to be used
header('Content-Type: text/html; charset=utf-8');
/* HTML header */
$page_title = __('Access denied');
include './libraries/header_meta_style.inc.php';
include './libraries/header_scripts.inc.php';
?>
</head>
<body>
<br /><br />
<center>
<h1><?php echo sprintf(__('Welcome to %s'), ' phpMyAdmin '); ?></h1>
</center>
<br />
<table border="0" cellpadding="0" cellspacing="3" align="center" width="80%">
<tr>
<td>
<?php
$GLOBALS['is_header_sent'] = true;
if (isset($GLOBALS['allowDeny_forbidden']) && $GLOBALS['allowDeny_forbidden']) {
trigger_error(__('Access denied'), E_USER_NOTICE);
} else {
// Check whether user has configured something
if ($GLOBALS['PMA_Config']->source_mtime == 0) {
echo '<p>' . sprintf(__('You probably did not create a configuration file. You might want to use the %1$ssetup script%2$s to create one.'), '<a href="setup/">', '</a>') . '</p>' . "\n";
} elseif (!isset($GLOBALS['errno']) || (isset($GLOBALS['errno']) && $GLOBALS['errno'] != 2002) && $GLOBALS['errno'] != 2003) {
// if we display the "Server not responding" error, do not confuse users
// by telling them they have a settings problem
// (note: it's true that they could have a badly typed host name, but
// anyway the current message tells that the server
// rejected the connection, which is not really what happened)
// 2002 is the error given by mysqli
// 2003 is the error given by mysql
trigger_error(__('phpMyAdmin tried to connect to the MySQL server, and the server rejected the connection. You should check the host, username and password in your configuration and make sure that they correspond to the information given by the administrator of the MySQL server.'), E_USER_WARNING);
}
PMA_mysqlDie($conn_error, '', true, '', false);
}
$GLOBALS['error_handler']->dispUserErrors();
?>
</td>
</tr>
<?php
if (count($GLOBALS['cfg']['Servers']) > 1) {
// offer a chance to login to other servers if the current one failed
include_once './libraries/select_server.lib.php';
echo '<tr>' . "\n";
echo ' <td>' . "\n";
PMA_select_server(true, true);
echo ' </td>' . "\n";
echo '</tr>' . "\n";
}
echo '</table>' . "\n";
include './libraries/footer.inc.php';
return true;
} // end of the 'PMA_auth_fails()' function
?>

View File

@ -0,0 +1,594 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to run cookie based authentication.
*
* @package PhpMyAdmin-Auth-Cookie
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Swekey authentication functions.
*/
require './libraries/auth/swekey/swekey.auth.lib.php';
if (function_exists('mcrypt_encrypt')) {
/**
* Uses faster mcrypt library if available
* (as this is not called from anywhere else, put the code in-line
* for faster execution)
*/
/**
* Initialization
* Store the initialization vector because it will be needed for
* further decryption. I don't think necessary to have one iv
* per server so I don't put the server number in the cookie name.
*/
if (empty($_COOKIE['pma_mcrypt_iv']) || false === ($iv = base64_decode($_COOKIE['pma_mcrypt_iv'], true))) {
srand((double) microtime() * 1000000);
$td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');
if ($td === false) {
die(__('Failed to use Blowfish from mcrypt!'));
}
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$GLOBALS['PMA_Config']->setCookie('pma_mcrypt_iv', base64_encode($iv));
}
/**
* Encryption using blowfish algorithm (mcrypt)
*
* @param string original data
* @param string the secret
*
* @return string the encrypted result
*
* @access public
*
*/
function PMA_blowfish_encrypt($data, $secret)
{
global $iv;
return base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, $secret, $data, MCRYPT_MODE_CBC, $iv));
}
/**
* Decryption using blowfish algorithm (mcrypt)
*
* @param string encrypted data
* @param string the secret
*
* @return string original data
*
* @access public
*
*/
function PMA_blowfish_decrypt($encdata, $secret)
{
global $iv;
return trim(mcrypt_decrypt(MCRYPT_BLOWFISH, $secret, base64_decode($encdata), MCRYPT_MODE_CBC, $iv));
}
} else {
include_once './libraries/blowfish.php';
}
/**
* Returns blowfish secret or generates one if needed.
*
* @access public
* @return string
*/
function PMA_get_blowfish_secret()
{
if (empty($GLOBALS['cfg']['blowfish_secret'])) {
if (empty($_SESSION['auto_blowfish_secret'])) {
// this returns 23 characters
$_SESSION['auto_blowfish_secret'] = uniqid('', true);
}
return $_SESSION['auto_blowfish_secret'];
} else {
// apply md5() to work around too long secrets (returns 32 characters)
return md5($GLOBALS['cfg']['blowfish_secret']);
}
}
/**
* Displays authentication form
*
* this function MUST exit/quit the application
*
* @global string the last connection error
*
* @access public
*/
function PMA_auth()
{
global $conn_error;
/* Perform logout to custom URL */
if (! empty($_REQUEST['old_usr'])
&& ! empty($GLOBALS['cfg']['Server']['LogoutURL'])) {
PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
exit;
}
/* No recall if blowfish secret is not configured as it would produce garbage */
if ($GLOBALS['cfg']['LoginCookieRecall'] && !empty($GLOBALS['cfg']['blowfish_secret'])) {
$default_user = $GLOBALS['PHP_AUTH_USER'];
$default_server = $GLOBALS['pma_auth_server'];
$autocomplete = '';
} else {
$default_user = '';
$default_server = '';
// skip the IE autocomplete feature.
$autocomplete = ' autocomplete="off"';
}
$cell_align = ($GLOBALS['text_dir'] == 'ltr') ? 'left' : 'right';
// Defines the charset to be used
header('Content-Type: text/html; charset=utf-8');
/* HTML header; do not show here the PMA version to improve security */
$page_title = 'phpMyAdmin ';
include './libraries/header_meta_style.inc.php';
// if $page_title is set, this script uses it as the title:
include './libraries/header_scripts.inc.php';
?>
<script type="text/javascript">
//<![CDATA[
// show login form in top frame
if (top != self) {
window.top.location.href=location;
}
//]]>
</script>
</head>
<body class="loginform">
<?php
if (file_exists(CUSTOM_HEADER_FILE)) {
include CUSTOM_HEADER_FILE;
}
?>
<div class="container">
<a href="<?php echo PMA_linkURL('http://www.phpmyadmin.net/'); ?>" target="_blank" class="logo"><?php
$logo_image = $GLOBALS['pmaThemeImage'] . 'logo_right.png';
if (@file_exists($logo_image)) {
echo '<img src="' . $logo_image . '" id="imLogo" name="imLogo" alt="phpMyAdmin" border="0" />';
} else {
echo '<img name="imLogo" id="imLogo" src="' . $GLOBALS['pmaThemeImage'] . 'pma_logo.png' . '" '
. 'border="0" width="88" height="31" alt="phpMyAdmin" />';
}
?></a>
<h1>
<?php
echo sprintf(__('Welcome to %s'),
'<bdo dir="ltr" xml:lang="en">' . $page_title . '</bdo>');
?>
</h1>
<?php
// Show error message
if (! empty($conn_error)) {
PMA_Message::rawError($conn_error)->display();
}
// Displays the languages form
if (empty($GLOBALS['cfg']['Lang'])) {
include_once './libraries/display_select_lang.lib.php';
// use fieldset, don't show doc link
PMA_select_language(true, false);
}
?>
<br />
<!-- Login form -->
<form method="post" action="index.php" name="login_form"<?php echo $autocomplete; ?> target="_top" class="login">
<fieldset>
<legend>
<?php
echo __('Log in');
echo '<a href="./Documentation.html" target="documentation" ' .
'title="' . __('phpMyAdmin documentation') . '"> ';
if ($GLOBALS['cfg']['ReplaceHelpImg']) {
echo PMA_getImage('b_help.png', __('phpMyAdmin documentation'));
} else {
echo '(*)';
}
echo '</a>';
?>
</legend>
<?php if ($GLOBALS['cfg']['AllowArbitraryServer']) { ?>
<div class="item">
<label for="input_servername" title="<?php echo __('You can enter hostname/IP address and port separated by space.'); ?>"><?php echo __('Server:'); ?></label>
<input type="text" name="pma_servername" id="input_servername" value="<?php echo htmlspecialchars($default_server); ?>" size="24" class="textfield" title="<?php echo __('You can enter hostname/IP address and port separated by space.'); ?>" />
</div>
<?php } ?>
<div class="item">
<label for="input_username"><?php echo __('Username:'); ?></label>
<input type="text" name="pma_username" id="input_username" value="<?php echo htmlspecialchars($default_user); ?>" size="24" class="textfield"/>
</div>
<div class="item">
<label for="input_password"><?php echo __('Password:'); ?></label>
<input type="password" name="pma_password" id="input_password" value="" size="24" class="textfield" />
</div>
<?php
if (count($GLOBALS['cfg']['Servers']) > 1) {
?>
<div class="item">
<label for="select_server"><?php echo __('Server Choice'); ?>:</label>
<select name="server" id="select_server"
<?php
if ($GLOBALS['cfg']['AllowArbitraryServer']) {
echo ' onchange="document.forms[\'login_form\'].elements[\'pma_servername\'].value = \'\'" ';
}
echo '>';
include_once './libraries/select_server.lib.php';
PMA_select_server(false, false);
echo '</select></div>';
} else {
echo ' <input type="hidden" name="server" value="' . $GLOBALS['server'] . '" />';
} // end if (server choice)
?>
</fieldset>
<fieldset class="tblFooters">
<input value="<?php echo __('Go'); ?>" type="submit" id="input_go" />
<?php
$_form_params = array();
if (! empty($GLOBALS['target'])) {
$_form_params['target'] = $GLOBALS['target'];
}
if (! empty($GLOBALS['db'])) {
$_form_params['db'] = $GLOBALS['db'];
}
if (! empty($GLOBALS['table'])) {
$_form_params['table'] = $GLOBALS['table'];
}
// do not generate a "server" hidden field as we want the "server"
// drop-down to have priority
echo PMA_generate_common_hidden_inputs($_form_params, '', 0, 'server');
?>
</fieldset>
</form>
<?php
// BEGIN Swekey Integration
Swekey_login('input_username', 'input_go');
// END Swekey Integration
// show the "Cookies required" message only if cookies are disabled
// (we previously tried to set some cookies)
if (empty($_COOKIE)) {
trigger_error(__('Cookies must be enabled past this point.'), E_USER_NOTICE);
}
if ($GLOBALS['error_handler']->hasDisplayErrors()) {
echo '<div>';
$GLOBALS['error_handler']->dispErrors();
echo '</div>';
}
?>
</div>
<?php
if (file_exists(CUSTOM_FOOTER_FILE)) {
include CUSTOM_FOOTER_FILE;
}
?>
</body>
</html>
<?php
exit;
} // end of the 'PMA_auth()' function
/**
* Gets advanced authentication settings
*
* this function DOES NOT check authentication - it just checks/provides
* authentication credentials required to connect to the MySQL server
* usually with PMA_DBI_connect()
*
* it returns false if something is missing - which usually leads to
* PMA_auth() which displays login form
*
* it returns true if all seems ok which usually leads to PMA_auth_set_user()
*
* it directly switches to PMA_auth_fails() if user inactivity timout is reached
*
* @todo AllowArbitraryServer on does not imply that the user wants an
* arbitrary server, or? so we should also check if this is filled and
* not only if allowed
*
* @return boolean whether we get authentication settings or not
*
* @access public
*/
function PMA_auth_check()
{
// Initialization
/**
* @global $GLOBALS['pma_auth_server'] the user provided server to connect to
*/
$GLOBALS['pma_auth_server'] = '';
$GLOBALS['PHP_AUTH_USER'] = $GLOBALS['PHP_AUTH_PW'] = '';
$GLOBALS['from_cookie'] = false;
// BEGIN Swekey Integration
if (! Swekey_auth_check()) {
return false;
}
// END Swekey Integration
if (defined('PMA_CLEAR_COOKIES')) {
foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
$GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $key);
$GLOBALS['PMA_Config']->removeCookie('pmaUser-' . $key);
}
return false;
}
if (! empty($_REQUEST['old_usr'])) {
// The user wants to be logged out
// -> delete his choices that were stored in session
// according to the PHP manual we should do this before the destroy:
//$_SESSION = array();
// but we still need some parts of the session information
// in libraries/header_meta_style.inc.php
session_destroy();
// -> delete password cookie(s)
if ($GLOBALS['cfg']['LoginCookieDeleteAll']) {
foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
if (isset($_COOKIE['pmaPass-' . $key])) {
unset($_COOKIE['pmaPass-' . $key]);
}
}
} else {
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
unset($_COOKIE['pmaPass-' . $GLOBALS['server']]);
}
}
}
if (! empty($_REQUEST['pma_username'])) {
// The user just logged in
$GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
$GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password']) ? '' : $_REQUEST['pma_password'];
if ($GLOBALS['cfg']['AllowArbitraryServer'] && isset($_REQUEST['pma_servername'])) {
$GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername'];
}
return true;
}
// At the end, try to set the $GLOBALS['PHP_AUTH_USER']
// and $GLOBALS['PHP_AUTH_PW'] variables from cookies
// servername
if ($GLOBALS['cfg']['AllowArbitraryServer']
&& ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']])) {
$GLOBALS['pma_auth_server'] = $_COOKIE['pmaServer-' . $GLOBALS['server']];
}
// username
if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) {
return false;
}
$GLOBALS['PHP_AUTH_USER'] = PMA_blowfish_decrypt(
$_COOKIE['pmaUser-' . $GLOBALS['server']],
PMA_get_blowfish_secret());
// user was never logged in since session start
if (empty($_SESSION['last_access_time'])) {
return false;
}
// User inactive too long
if ($_SESSION['last_access_time'] < time() - $GLOBALS['cfg']['LoginCookieValidity']) {
PMA_cacheUnset('is_create_db_priv', true);
PMA_cacheUnset('is_process_priv', true);
PMA_cacheUnset('is_reload_priv', true);
PMA_cacheUnset('db_to_create', true);
PMA_cacheUnset('dbs_where_create_table_allowed', true);
$GLOBALS['no_activity'] = true;
PMA_auth_fails();
exit;
}
// password
if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
return false;
}
$GLOBALS['PHP_AUTH_PW'] = PMA_blowfish_decrypt(
$_COOKIE['pmaPass-' . $GLOBALS['server']],
PMA_get_blowfish_secret());
if ($GLOBALS['PHP_AUTH_PW'] == "\xff(blank)") {
$GLOBALS['PHP_AUTH_PW'] = '';
}
$GLOBALS['from_cookie'] = true;
return true;
} // end of the 'PMA_auth_check()' function
/**
* Set the user and password after last checkings if required
*
* @return boolean always true
*
* @access public
*/
function PMA_auth_set_user()
{
global $cfg;
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
foreach ($cfg['Servers'] as $idx => $current) {
if ($current['host'] == $cfg['Server']['host']
&& $current['port'] == $cfg['Server']['port']
&& $current['socket'] == $cfg['Server']['socket']
&& $current['ssl'] == $cfg['Server']['ssl']
&& $current['connect_type'] == $cfg['Server']['connect_type']
&& $current['user'] == $GLOBALS['PHP_AUTH_USER']) {
$GLOBALS['server'] = $idx;
$cfg['Server'] = $current;
break;
}
} // end foreach
} // end if
if ($GLOBALS['cfg']['AllowArbitraryServer']
&& ! empty($GLOBALS['pma_auth_server'])) {
/* Allow to specify 'host port' */
$parts = explode(' ', $GLOBALS['pma_auth_server']);
if (count($parts) == 2) {
$tmp_host = $parts[0];
$tmp_port = $parts[1];
} else {
$tmp_host = $GLOBALS['pma_auth_server'];
$tmp_port = '';
}
if ($cfg['Server']['host'] != $GLOBALS['pma_auth_server']) {
$cfg['Server']['host'] = $tmp_host;
if (!empty($tmp_port)) {
$cfg['Server']['port'] = $tmp_port;
}
}
unset($tmp_host, $tmp_port, $parts);
}
$cfg['Server']['user'] = $GLOBALS['PHP_AUTH_USER'];
$cfg['Server']['password'] = $GLOBALS['PHP_AUTH_PW'];
// Avoid showing the password in phpinfo()'s output
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
$_SESSION['last_access_time'] = time();
// Name and password cookies need to be refreshed each time
// Duration = one month for username
$GLOBALS['PMA_Config']->setCookie('pmaUser-' . $GLOBALS['server'],
PMA_blowfish_encrypt($cfg['Server']['user'],
PMA_get_blowfish_secret()));
// Duration = as configured
$GLOBALS['PMA_Config']->setCookie('pmaPass-' . $GLOBALS['server'],
PMA_blowfish_encrypt(!empty($cfg['Server']['password']) ? $cfg['Server']['password'] : "\xff(blank)",
PMA_get_blowfish_secret()),
null,
$GLOBALS['cfg']['LoginCookieStore']);
// Set server cookies if required (once per session) and, in this case, force
// reload to ensure the client accepts cookies
if (! $GLOBALS['from_cookie']) {
if ($GLOBALS['cfg']['AllowArbitraryServer']) {
if (! empty($GLOBALS['pma_auth_server'])) {
// Duration = one month for servername
$GLOBALS['PMA_Config']->setCookie('pmaServer-' . $GLOBALS['server'], $cfg['Server']['host']);
} else {
// Delete servername cookie
$GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $GLOBALS['server']);
}
}
// URL where to go:
$redirect_url = $cfg['PmaAbsoluteUri'] . 'index.php';
// any parameters to pass?
$url_params = array();
if (strlen($GLOBALS['db'])) {
$url_params['db'] = $GLOBALS['db'];
}
if (strlen($GLOBALS['table'])) {
$url_params['table'] = $GLOBALS['table'];
}
// any target to pass?
if (! empty($GLOBALS['target']) && $GLOBALS['target'] != 'index.php') {
$url_params['target'] = $GLOBALS['target'];
}
/**
* whether we come from a fresh cookie login
*/
define('PMA_COMING_FROM_COOKIE_LOGIN', true);
/**
* Clear user cache.
*/
PMA_clearUserCache();
PMA_sendHeaderLocation($redirect_url . PMA_generate_common_url($url_params, '&'));
exit();
} // end if
return true;
} // end of the 'PMA_auth_set_user()' function
/**
* User is not allowed to login to MySQL -> authentication failed
*
* prepares error message and switches to PMA_auth() which display the error
* and the login form
*
* this function MUST exit/quit the application,
* currently doen by call to PMA_auth()
*
* @access public
*/
function PMA_auth_fails()
{
global $conn_error;
// Deletes password cookie and displays the login form
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
if (! empty($GLOBALS['login_without_password_is_forbidden'])) {
$conn_error = __('Login without a password is forbidden by configuration (see AllowNoPassword)');
} elseif (! empty($GLOBALS['allowDeny_forbidden'])) {
$conn_error = __('Access denied');
} elseif (! empty($GLOBALS['no_activity'])) {
$conn_error = sprintf(__('No activity within %s seconds; please log in again'), $GLOBALS['cfg']['LoginCookieValidity']);
// Remember where we got timeout to return on same place
if (PMA_getenv('SCRIPT_NAME')) {
$GLOBALS['target'] = basename(PMA_getenv('SCRIPT_NAME'));
// avoid "missing parameter: field" on re-entry
if ('tbl_alter.php' == $GLOBALS['target']) {
$GLOBALS['target'] = 'tbl_structure.php';
}
}
} elseif (PMA_DBI_getError()) {
$conn_error = '#' . $GLOBALS['errno'] . ' ' . __('Cannot log in to the MySQL server');
} else {
$conn_error = __('Cannot log in to the MySQL server');
}
// needed for PHP-CGI (not need for FastCGI or mod-php)
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
PMA_auth();
} // end of the 'PMA_auth_fails()' function
?>

View File

@ -0,0 +1,237 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to run http authentication.
* NOTE: Requires PHP loaded as a Apache module.
*
* @package PhpMyAdmin-Auth-HTTP
*/
/**
* Displays authentication form
*
* @global string the font face to use in case of failure
* @global string the default font size to use in case of failure
* @global string the big font size to use in case of failure
*
* @return boolean always true (no return indeed)
*
* @access public
*/
function PMA_auth()
{
/* Perform logout to custom URL */
if (!empty($_REQUEST['old_usr']) && !empty($GLOBALS['cfg']['Server']['LogoutURL'])) {
PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
exit;
}
if (empty($GLOBALS['cfg']['Server']['auth_http_realm'])) {
if (empty($GLOBALS['cfg']['Server']['verbose'])) {
$server_message = $GLOBALS['cfg']['Server']['host'];
} else {
$server_message = $GLOBALS['cfg']['Server']['verbose'];
}
$realm_message = 'phpMyAdmin ' . $server_message;
} else {
$realm_message = $GLOBALS['cfg']['Server']['auth_http_realm'];
}
// remove non US-ASCII to respect RFC2616
$realm_message = preg_replace('/[^\x20-\x7e]/i', '', $realm_message);
header('WWW-Authenticate: Basic realm="' . $realm_message . '"');
header('HTTP/1.0 401 Unauthorized');
if (php_sapi_name() !== 'cgi-fcgi') {
header('status: 401 Unauthorized');
}
// Defines the charset to be used
header('Content-Type: text/html; charset=utf-8');
/* HTML header */
$page_title = __('Access denied');
include './libraries/header_meta_style.inc.php';
?>
</head>
<body>
<?php
if (file_exists(CUSTOM_HEADER_FILE)) {
include CUSTOM_HEADER_FILE;
}
?>
<br /><br />
<center>
<h1><?php echo sprintf(__('Welcome to %s'), ' phpMyAdmin'); ?></h1>
</center>
<br />
<?php
PMA_Message::error(__('Wrong username/password. Access denied.'))->display();
if (file_exists(CUSTOM_FOOTER_FILE)) {
include CUSTOM_FOOTER_FILE;
}
?>
</body>
</html>
<?php
exit();
} // end of the 'PMA_auth()' function
/**
* Gets advanced authentication settings
*
* @global string the username if register_globals is on
* @global string the password if register_globals is on
* @global array the array of server variables if register_globals is
* off
* @global array the array of environment variables if register_globals
* is off
* @global string the username for the ? server
* @global string the password for the ? server
* @global string the username for the WebSite Professional server
* @global string the password for the WebSite Professional server
* @global string the username of the user who logs out
*
* @return boolean whether we get authentication settings or not
*
* @access public
*/
function PMA_auth_check()
{
global $PHP_AUTH_USER, $PHP_AUTH_PW;
global $old_usr;
// Grabs the $PHP_AUTH_USER variable whatever are the values of the
// 'register_globals' and the 'variables_order' directives
if (empty($PHP_AUTH_USER)) {
if (PMA_getenv('PHP_AUTH_USER')) {
$PHP_AUTH_USER = PMA_getenv('PHP_AUTH_USER');
} elseif (PMA_getenv('REMOTE_USER')) {
// CGI, might be encoded, see below
$PHP_AUTH_USER = PMA_getenv('REMOTE_USER');
} elseif (PMA_getenv('REDIRECT_REMOTE_USER')) {
// CGI, might be encoded, see below
$PHP_AUTH_USER = PMA_getenv('REDIRECT_REMOTE_USER');
} elseif (PMA_getenv('AUTH_USER')) {
// WebSite Professional
$PHP_AUTH_USER = PMA_getenv('AUTH_USER');
} elseif (PMA_getenv('HTTP_AUTHORIZATION')) {
// IIS, might be encoded, see below
$PHP_AUTH_USER = PMA_getenv('HTTP_AUTHORIZATION');
} elseif (PMA_getenv('Authorization')) {
// FastCGI, might be encoded, see below
$PHP_AUTH_USER = PMA_getenv('Authorization');
}
}
// Grabs the $PHP_AUTH_PW variable whatever are the values of the
// 'register_globals' and the 'variables_order' directives
if (empty($PHP_AUTH_PW)) {
if (PMA_getenv('PHP_AUTH_PW')) {
$PHP_AUTH_PW = PMA_getenv('PHP_AUTH_PW');
} elseif (PMA_getenv('REMOTE_PASSWORD')) {
// Apache/CGI
$PHP_AUTH_PW = PMA_getenv('REMOTE_PASSWORD');
} elseif (PMA_getenv('AUTH_PASSWORD')) {
// WebSite Professional
$PHP_AUTH_PW = PMA_getenv('AUTH_PASSWORD');
}
}
// Decode possibly encoded information (used by IIS/CGI/FastCGI)
// (do not use explode() because a user might have a colon in his password
if (strcmp(substr($PHP_AUTH_USER, 0, 6), 'Basic ') == 0) {
$usr_pass = base64_decode(substr($PHP_AUTH_USER, 6));
if (! empty($usr_pass)) {
$colon = strpos($usr_pass, ':');
if ($colon) {
$PHP_AUTH_USER = substr($usr_pass, 0, $colon);
$PHP_AUTH_PW = substr($usr_pass, $colon + 1);
}
unset($colon);
}
unset($usr_pass);
}
// User logged out -> ensure the new username is not the same
if (!empty($old_usr)
&& (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER)) {
$PHP_AUTH_USER = '';
// -> delete user's choices that were stored in session
session_destroy();
}
// Returns whether we get authentication settings or not
if (empty($PHP_AUTH_USER)) {
return false;
} else {
return true;
}
} // end of the 'PMA_auth_check()' function
/**
* Set the user and password after last checkings if required
*
* @global array the valid servers settings
* @global integer the id of the current server
* @global array the current server settings
* @global string the current username
* @global string the current password
*
* @return boolean always true
*
* @access public
*/
function PMA_auth_set_user()
{
global $cfg, $server;
global $PHP_AUTH_USER, $PHP_AUTH_PW;
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $PHP_AUTH_USER) {
$servers_cnt = count($cfg['Servers']);
for ($i = 1; $i <= $servers_cnt; $i++) {
if (isset($cfg['Servers'][$i])
&& ($cfg['Servers'][$i]['host'] == $cfg['Server']['host'] && $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER)) {
$server = $i;
$cfg['Server'] = $cfg['Servers'][$i];
break;
}
} // end for
} // end if
$cfg['Server']['user'] = $PHP_AUTH_USER;
$cfg['Server']['password'] = $PHP_AUTH_PW;
// Avoid showing the password in phpinfo()'s output
unset($GLOBALS['PHP_AUTH_PW']);
unset($_SERVER['PHP_AUTH_PW']);
return true;
} // end of the 'PMA_auth_set_user()' function
/**
* User is not allowed to login to MySQL -> authentication failed
*
* @return boolean always true (no return indeed)
*
* @access public
*/
function PMA_auth_fails()
{
$error = PMA_DBI_getError();
if ($error && $GLOBALS['errno'] != 1045) {
PMA_fatalError($error);
} else {
PMA_auth();
return true;
}
} // end of the 'PMA_auth_fails()' function
?>

View File

@ -0,0 +1,249 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to run single signon authentication.
*
* @package PhpMyAdmin-Auth-Signon
*/
/**
* Displays authentication form
*
* @global string the font face to use in case of failure
* @global string the default font size to use in case of failure
* @global string the big font size to use in case of failure
*
* @return boolean always true (no return indeed)
*
* @access public
*/
function PMA_auth()
{
unset($_SESSION['LAST_SIGNON_URL']);
if (empty($GLOBALS['cfg']['Server']['SignonURL'])) {
PMA_fatalError('You must set SignonURL!');
} elseif (!empty($_REQUEST['old_usr']) && !empty($GLOBALS['cfg']['Server']['LogoutURL'])) {
/* Perform logout to custom URL */
PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
} else {
PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['SignonURL']);
}
exit();
} // end of the 'PMA_auth()' function
/**
* Gets advanced authentication settings
*
* @global string the username if register_globals is on
* @global string the password if register_globals is on
* @global array the array of server variables if register_globals is
* off
* @global array the array of environment variables if register_globals
* is off
* @global string the username for the ? server
* @global string the password for the ? server
* @global string the username for the WebSite Professional server
* @global string the password for the WebSite Professional server
* @global string the username of the user who logs out
*
* @return boolean whether we get authentication settings or not
*
* @access public
*/
function PMA_auth_check()
{
global $PHP_AUTH_USER, $PHP_AUTH_PW;
/* Check if we're using same sigon server */
if (isset($_SESSION['LAST_SIGNON_URL']) && $_SESSION['LAST_SIGNON_URL'] != $GLOBALS['cfg']['Server']['SignonURL']) {
return false;
}
/* Script name */
$script_name = $GLOBALS['cfg']['Server']['SignonScript'];
/* Session name */
$session_name = $GLOBALS['cfg']['Server']['SignonSession'];
/* Login URL */
$signon_url = $GLOBALS['cfg']['Server']['SignonURL'];
/* Current host */
$single_signon_host = $GLOBALS['cfg']['Server']['host'];
/* Current port */
$single_signon_port = $GLOBALS['cfg']['Server']['port'];
/* No configuration updates */
$single_signon_cfgupdate = array();
/* Are we requested to do logout? */
$do_logout = !empty($_REQUEST['old_usr']);
/* Handle script based auth */
if (!empty($script_name)) {
if (! file_exists($script_name)) {
PMA_fatalError(__('Can not find signon authentication script:') . ' ' . $script_name);
}
include $script_name;
list ($PHP_AUTH_USER, $PHP_AUTH_PW) = get_login_credentials($cfg['Server']['user']);
/* Does session exist? */
} elseif (isset($_COOKIE[$session_name])) {
/* End current session */
$old_session = session_name();
$old_id = session_id();
session_write_close();
/* Load single signon session */
session_name($session_name);
session_id($_COOKIE[$session_name]);
session_start();
/* Clear error message */
unset($_SESSION['PMA_single_signon_error_message']);
/* Grab credentials if they exist */
if (isset($_SESSION['PMA_single_signon_user'])) {
if ($do_logout) {
$PHP_AUTH_USER = '';
} else {
$PHP_AUTH_USER = $_SESSION['PMA_single_signon_user'];
}
}
if (isset($_SESSION['PMA_single_signon_password'])) {
if ($do_logout) {
$PHP_AUTH_PW = '';
} else {
$PHP_AUTH_PW = $_SESSION['PMA_single_signon_password'];
}
}
if (isset($_SESSION['PMA_single_signon_host'])) {
$single_signon_host = $_SESSION['PMA_single_signon_host'];
}
if (isset($_SESSION['PMA_single_signon_port'])) {
$single_signon_port = $_SESSION['PMA_single_signon_port'];
}
if (isset($_SESSION['PMA_single_signon_cfgupdate'])) {
$single_signon_cfgupdate = $_SESSION['PMA_single_signon_cfgupdate'];
}
/* Also get token as it is needed to access subpages */
if (isset($_SESSION['PMA_single_signon_token'])) {
/* No need to care about token on logout */
$pma_token = $_SESSION['PMA_single_signon_token'];
}
/* End single signon session */
session_write_close();
/* Restart phpMyAdmin session */
session_name($old_session);
if (!empty($old_id)) {
session_id($old_id);
}
session_start();
/* Set the single signon host */
$GLOBALS['cfg']['Server']['host'] = $single_signon_host;
/* Set the single signon port */
$GLOBALS['cfg']['Server']['port'] = $single_signon_port;
/* Configuration update */
$GLOBALS['cfg']['Server'] = array_merge($GLOBALS['cfg']['Server'], $single_signon_cfgupdate);
/* Restore our token */
if (!empty($pma_token)) {
$_SESSION[' PMA_token '] = $pma_token;
}
/**
* Clear user cache.
*/
PMA_clearUserCache();
}
// Returns whether we get authentication settings or not
if (empty($PHP_AUTH_USER)) {
unset($_SESSION['LAST_SIGNON_URL']);
return false;
} else {
$_SESSION['LAST_SIGNON_URL'] = $GLOBALS['cfg']['Server']['SignonURL'];
return true;
}
} // end of the 'PMA_auth_check()' function
/**
* Set the user and password after last checkings if required
*
* @global array the valid servers settings
* @global integer the id of the current server
* @global array the current server settings
* @global string the current username
* @global string the current password
*
* @return boolean always true
*
* @access public
*/
function PMA_auth_set_user()
{
global $cfg;
global $PHP_AUTH_USER, $PHP_AUTH_PW;
$cfg['Server']['user'] = $PHP_AUTH_USER;
$cfg['Server']['password'] = $PHP_AUTH_PW;
return true;
} // end of the 'PMA_auth_set_user()' function
/**
* User is not allowed to login to MySQL -> authentication failed
*
* @return boolean always true (no return indeed)
*
* @access public
*/
function PMA_auth_fails()
{
/* Session name */
$session_name = $GLOBALS['cfg']['Server']['SignonSession'];
/* Does session exist? */
if (isset($_COOKIE[$session_name])) {
/* End current session */
$old_session = session_name();
$old_id = session_id();
session_write_close();
/* Load single signon session */
session_name($session_name);
session_id($_COOKIE[$session_name]);
session_start();
/* Set error message */
if (! empty($GLOBALS['login_without_password_is_forbidden'])) {
$_SESSION['PMA_single_signon_error_message'] = __('Login without a password is forbidden by configuration (see AllowNoPassword)');
} elseif (! empty($GLOBALS['allowDeny_forbidden'])) {
$_SESSION['PMA_single_signon_error_message'] = __('Access denied');
} elseif (! empty($GLOBALS['no_activity'])) {
$_SESSION['PMA_single_signon_error_message'] = sprintf(__('No activity within %s seconds; please log in again'), $GLOBALS['cfg']['LoginCookieValidity']);
} elseif (PMA_DBI_getError()) {
$_SESSION['PMA_single_signon_error_message'] = PMA_sanitize(PMA_DBI_getError());
} else {
$_SESSION['PMA_single_signon_error_message'] = __('Cannot log in to the MySQL server');
}
}
PMA_auth();
} // end of the 'PMA_auth_fails()' function
?>

View File

@ -0,0 +1,172 @@
<?php
/**
* @package Swekey
*/
?>
<script>
var g_SwekeyPlugin = null;
// -------------------------------------------------------------------
// Create the swekey plugin if it does not exists
function Swekey_Plugin()
{
try
{
if (g_SwekeyPlugin != null)
return g_SwekeyPlugin;
if (window.ActiveXObject)
{
g_SwekeyPlugin = document.getElementById("swekey_activex");
if (g_SwekeyPlugin == null)
{
// we must create the activex that way instead of new ActiveXObject("FbAuthAx.FbAuthCtl");
// ortherwise SetClientSite is not called and we can not get the url
var div = document.createElement('div');
div.innerHTML='<object id="swekey_activex" style="display:none" CLASSID="CLSID:8E02E3F9-57AA-4EE1-AA68-A42DD7B0FADE"></object>';
// Never append to the body because it may still loading and it breaks IE
document.body.insertBefore(div, document.body.firstChild);
g_SwekeyPlugin = document.getElementById("swekey_activex");
}
return g_SwekeyPlugin;
}
g_SwekeyPlugin = document.getElementById("swekey_plugin");
if (g_SwekeyPlugin != null)
return g_SwekeyPlugin;
for (i = 0; i < navigator.plugins.length; i ++)
{
try
{
if (navigator.plugins[i] == null)
{
navigator.plugins.refresh();
}
else if (navigator.plugins[i][0] != null && navigator.plugins[i][0].type == "application/fbauth-plugin")
{
var x = document.createElement('embed');
x.setAttribute('type', 'application/fbauth-plugin');
x.setAttribute('id', 'swekey_plugin');
x.setAttribute('width', '0');
x.setAttribute('height', '0');
x.style.dislay='none';
//document.body.appendChild(x);
document.body.insertBefore(x, document.body.firstChild);
g_SwekeyPlugin = document.getElementById("swekey_plugin");
return g_SwekeyPlugin;
}
}
catch (e)
{
navigator.plugins.refresh();
//alert ('Failed to create plugin: ' + e);
}
}
}
catch (e)
{
//alert("Swekey_Plugin " + e);
g_SwekeyPlugin = null;
}
return null;
}
// -------------------------------------------------------------------
// Returns true if the swekey plugin is installed
function Swekey_Installed()
{
return (Swekey_Plugin() != null);
}
// -------------------------------------------------------------------
// List the id of the Swekey connected to the PC
// Returns a string containing comma separated Swekey Ids
// A Swekey is a 32 char hexadecimal value.
function Swekey_ListKeyIds()
{
try
{
return Swekey_Plugin().list();
}
catch (e)
{
// alert("Swekey_ListKeyIds " + e);
}
return "";
}
// -------------------------------------------------------------------
// Ask the Connected Swekey to generate an OTP
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// rt: A random token
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
function Swekey_GetOtp(id, rt)
{
try
{
return Swekey_Plugin().getotp(id, rt);
}
catch (e)
{
// alert("Swekey_GetOtp " + e);
}
return "";
}
// -------------------------------------------------------------------
// Ask the Connected Swekey to generate a OTP linked to the current https host
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// rt: A random token
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
// or "" if the current url does not start with https
function Swekey_GetLinkedOtp(id, rt)
{
try
{
return Swekey_Plugin().getlinkedotp(id, rt);
}
catch (e)
{
// alert("Swekey_GetSOtp " + e);
}
return "";
}
// -------------------------------------------------------------------
// Calls Swekey_GetOtp or Swekey_GetLinkedOtp depending if we are in
// an https page or not.
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// rt: A random token
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
function Swekey_GetSmartOtp(id, rt)
{
var res = Swekey_GetLinkedOtp(id, rt);
if (res == "")
res = Swekey_GetOtp(id, rt);
return res;
}
// -------------------------------------------------------------------
// Set a unplug handler (url) to the specified connected feebee
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// key: The key that index that url, (aplhanumeric values only)
// url: The url that will be launched ("" deletes the url)
function Swekey_SetUnplugUrl(id, key, url)
{
try
{
return Swekey_Plugin().setunplugurl(id, key, url);
}
catch (e)
{
// alert("Swekey_SetUnplugUrl " + e);
}
}
</script>

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIJAMjw7QcLWCd6MA0GCSqGSIb3DQEBBQUAMGsxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5j
LjESMBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2Jl
LmNvbTAeFw0wODA5MDQxNDE2MTNaFw0zNzEyMjExNDE2MTNaMGsxCzAJBgNVBAYT
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBhOljxVzQfK4gted2I
d3BemcjW4abAUOzn3KYWXpPO5xIfVeXNDGkDbyH+X+7fo94sX25/ewuKNFDSOcvo
tXHq7uQenTHB35r+a+LY81KceUHgW90a3XsqPAkwAjyYcgo3zmM2DtLvw+5Yod8T
wAHk9m3qavnQ1uk99jBTwL7RZ9jIZHh9pFCL93uJc2obtd8O96Iycbn2q0w/AWbb
+eUVWIHzvLtfPvROeL3lJzr/Uz5LjKapxJ3qyqASflfHpnj9pU8l6g2TQ6Hg5KT5
tLFkRe7uGhOfRtOQ/+NjaWrEuNCFnpyN4Q5Fv+5qA1Ip1IpH0200sWbAf/k2u0Qp
Sx0CAwEAAaOB0DCBzTAdBgNVHQ4EFgQUczJrQ7hCvtsnzcqiDIZ/GSn/CiwwgZ0G
A1UdIwSBlTCBkoAUczJrQ7hCvtsnzcqiDIZ/GSn/Ciyhb6RtMGsxCzAJBgNVBAYT
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
bYIJAMjw7QcLWCd6MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGxk
8xzIljeBDQWWVRr0NEALVSv3i09V4jAKkyEOfmZ8lKMKJi0atwbtjrXTzLnNYj+Q
pyUbyY/8ItWvV7pnVxMiF9qcer7e9X4vw358GZuMVE/da1nWxz+CwzTm5oO30RzA
antM9bISFFr9lJq69bDWOnCUi1IG8DSL3TxtlABso7S4vqiZ+sB33l6k1K4a/Njb
QkU9UejKhKkVVZTsOrumfnOJ4MCmPfX8Y/AY2o670y5HnzpxerIYziCVzApPVrW7
sKH0tuVGturMfQOKgstYe4/m9glBTeTLMkjD+6MJC2ONBD7GAiOO95gNl5M1fzJQ
FEe5CJ7DCYl0GdmLXXw=
-----END CERTIFICATE-----

View File

@ -0,0 +1,274 @@
<?php
/**
* @package Swekey
*/
/**
* Checks Swekey authentication.
*/
function Swekey_auth_check()
{
global $cfg;
$confFile = $cfg['Server']['auth_swekey_config'];
if (! isset($_SESSION['SWEKEY'])) {
$_SESSION['SWEKEY'] = array();
}
$_SESSION['SWEKEY']['ENABLED'] = (! empty($confFile) && file_exists($confFile));
// Load the swekey.conf file the first time
if ($_SESSION['SWEKEY']['ENABLED'] && empty($_SESSION['SWEKEY']['CONF_LOADED'])) {
$_SESSION['SWEKEY']['CONF_LOADED'] = true;
$_SESSION['SWEKEY']['VALID_SWEKEYS'] = array();
$valid_swekeys = explode("\n", @file_get_contents($confFile));
foreach ($valid_swekeys as $line) {
if (preg_match("/^[0-9A-F]{32}:.+$/", $line) != false) {
$items = explode(":", $line);
if (count($items) == 2)
$_SESSION['SWEKEY']['VALID_SWEKEYS'][$items[0]] = trim($items[1]);
} elseif (preg_match("/^[A-Z_]+=.*$/", $line) != false) {
$items = explode("=", $line);
$_SESSION['SWEKEY']['CONF_'.trim($items[0])] = trim($items[1]);
}
}
// Set default values for settings
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_CHECK']))
$_SESSION['SWEKEY']['CONF_SERVER_CHECK'] = "";
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN']))
$_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN'] = "";
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_STATUS']))
$_SESSION['SWEKEY']['CONF_SERVER_STATUS'] = "";
if (! isset($_SESSION['SWEKEY']['CONF_CA_FILE']))
$_SESSION['SWEKEY']['CONF_CA_FILE'] = "";
if (! isset($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE']))
$_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE'] = true;
if (! isset($_SESSION['SWEKEY']['CONF_DEBUG']))
$_SESSION['SWEKEY']['CONF_DEBUG'] = false;
}
// check if a web key has been authenticated
if ($_SESSION['SWEKEY']['ENABLED']) {
if (empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY']))
return false;
}
return true;
}
/**
* Handle Swekey authentication error.
*/
function Swekey_auth_error()
{
if (! isset($_SESSION['SWEKEY']))
return null;
if (! $_SESSION['SWEKEY']['ENABLED'])
return null;
include_once './libraries/auth/swekey/authentication.inc.php';
?>
<script>
function Swekey_GetValidKey()
{
var valids = "<?php
foreach ($_SESSION['SWEKEY']['VALID_SWEKEYS'] as $key => $value)
echo $key.',';
?>";
var connected_keys = Swekey_ListKeyIds().split(",");
for (i in connected_keys)
if (connected_keys[i] != null && connected_keys[i].length == 32)
if (valids.indexOf(connected_keys[i]) >= 0)
return connected_keys[i];
if (connected_keys.length > 0)
if (connected_keys[0].length == 32)
return "unknown_key_" + connected_keys[0];
return "none";
}
var key = Swekey_GetValidKey();
function timedCheck()
{
if (key != Swekey_GetValidKey())
{
window.location.search = "?swekey_reset";
}
else
setTimeout("timedCheck()",1000);
}
setTimeout("timedCheck()",1000);
</script>
<?php
if (! empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY']))
return null;
if (count($_SESSION['SWEKEY']['VALID_SWEKEYS']) == 0)
return sprintf(__('File %s does not contain any key id'), $GLOBALS['cfg']['Server']['auth_swekey_config']);
include_once "./libraries/auth/swekey/swekey.php";
Swekey_SetCheckServer($_SESSION['SWEKEY']['CONF_SERVER_CHECK']);
Swekey_SetRndTokenServer($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN']);
Swekey_SetStatusServer($_SESSION['SWEKEY']['CONF_SERVER_STATUS']);
Swekey_EnableTokenCache($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE']);
$caFile = $_SESSION['SWEKEY']['CONF_CA_FILE'];
if (empty($caFile)) {
$caFile = __FILE__;
$pos = strrpos($caFile, '/');
if ($pos === false)
$pos = strrpos($caFile, '\\'); // windows
$caFile = substr($caFile, 0, $pos + 1).'musbe-ca.crt';
// echo "\n<!-- $caFile -->\n";
// if (file_exists($caFile))
// echo "<!-- exists -->\n";
}
if (file_exists($caFile)) {
Swekey_SetCAFile($caFile);
} elseif (! empty($caFile) && (substr($_SESSION['SWEKEY']['CONF_SERVER_CHECK'], 0, 8) == "https://")) {
return "Internal Error: CA File $caFile not found";
}
$result = null;
$swekey_id = $_GET['swekey_id'];
$swekey_otp = $_GET['swekey_otp'];
if (isset($swekey_id)) {
unset($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY']);
if (! isset($_SESSION['SWEKEY']['RND_TOKEN'])) {
unset($swekey_id);
} else {
if (strlen($swekey_id) == 32) {
$res = Swekey_CheckOtp($swekey_id, $_SESSION['SWEKEY']['RND_TOKEN'], $swekey_otp);
unset($_SESSION['SWEKEY']['RND_TOKEN']);
if (! $res) {
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
} else {
$_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'] = $swekey_id;
$_SESSION['SWEKEY']['FORCE_USER'] = $_SESSION['SWEKEY']['VALID_SWEKEYS'][$swekey_id];
return null;
}
} else {
$result = __('No valid authentication key plugged');
if ($_SESSION['SWEKEY']['CONF_DEBUG']) {
$result .= "<br>" . htmlspecialchars($swekey_id);
}
unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
}
}
} else {
unset($_SESSION['SWEKEY']);
}
$_SESSION['SWEKEY']['RND_TOKEN'] = Swekey_GetFastRndToken();
if (strlen($_SESSION['SWEKEY']['RND_TOKEN']) != 64) {
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
}
if (! isset($swekey_id)) {
?>
<script>
if (key.length != 32) {
window.location.search="?swekey_id=" + key + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
} else {
var url = "" + window.location;
if (url.indexOf("?") > 0)
url = url.substr(0, url.indexOf("?"));
Swekey_SetUnplugUrl(key, "pma_login", url + "?session_to_unset=<?php echo session_id();?>&token=<?php echo $_SESSION[' PMA_token ']; ?>");
var otp = Swekey_GetOtp(key, <?php echo '"'.$_SESSION['SWEKEY']['RND_TOKEN'].'"';?>);
window.location.search="?swekey_id=" + key + "&swekey_otp=" + otp + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
}
</script>
<?php
return __('Authenticating...');
}
return $result;
}
/**
* Perform login using Swekey.
*/
function Swekey_login($input_name, $input_go)
{
$swekeyErr = Swekey_auth_error();
if ($swekeyErr != null) {
PMA_Message::error($swekeyErr)->display();
if ($GLOBALS['error_handler']->hasDisplayErrors()) {
echo '<div>';
$GLOBALS['error_handler']->dispErrors();
echo '</div>';
}
}
if (isset($_SESSION['SWEKEY']) && $_SESSION['SWEKEY']['ENABLED']) {
echo '<script type="text/javascript">';
if (empty($_SESSION['SWEKEY']['FORCE_USER'])) {
echo 'var user = null;';
} else {
echo 'var user = "'.$_SESSION['SWEKEY']['FORCE_USER'].'";';
}
?>
function open_swekey_site()
{
window.open("<?php echo PMA_linkURL('http://phpmyadmin.net/auth_key'); ?>");
}
var input_username = document.getElementById("<?php echo $input_name; ?>");
var input_go = document.getElementById("<?php echo $input_go; ?>");
var swekey_status = document.createElement('img');
swekey_status.setAttribute('onclick', 'open_swekey_site()');
swekey_status.setAttribute('style', 'width:8px; height:16px; border:0px; vspace:0px; hspace:0px; frameborder:no');
if (user == null)
{
swekey_status.setAttribute('src', 'http://artwork.swekey.com/unplugged-8x16.png');
//swekey_status.setAttribute('title', 'No swekey plugged');
input_go.disabled = true;
}
else
{
swekey_status.setAttribute('src', 'http://artwork.swekey.com/plugged-8x16.png');
//swekey_status.setAttribute('title', 'swekey plugged');
input_username.value = user;
}
input_username.readOnly = true;
if (input_username.nextSibling == null)
input_username.parentNode.appendChild(swekey_status);
else
input_username.parentNode.insertBefore(swekey_status, input_username.nextSibling);
<?php
echo '</script>';
}
}
if (!empty($_GET['session_to_unset'])) {
session_write_close();
session_id($_GET['session_to_unset']);
session_start();
$_SESSION = array();
session_write_close();
session_destroy();
exit;
}
if (isset($_GET['swekey_reset'])) {
unset($_SESSION['SWEKEY']);
}
?>

View File

@ -0,0 +1,495 @@
<?php
/**
* Library that provides common functions that are used to help integrating Swekey Authentication in a PHP web site
* Version 1.0
*
* History:
* 1.2 Use curl (widely installed) to query the server
* Fixed a possible tempfile race attack
* Random token cache can now be disabled
* 1.1 Added Swekey_HttpGet function that support faulty servers
* Support for custom servers
* 1.0 First release
*
* @package Swekey
*/
/**
* Errors codes
*/
define ("SWEKEY_ERR_INVALID_DEV_STATUS", 901); // The satus of the device is not SWEKEY_STATUS_OK
define ("SWEKEY_ERR_INTERNAL", 902); // Should never occurd
define ("SWEKEY_ERR_OUTDATED_RND_TOKEN", 910); // You random token is too old
define ("SWEKEY_ERR_INVALID_OTP", 911); // The otp was not correct
/**
* Those errors are considered as an attack and your site will be blacklisted during one minute
* if you receive one of those errors
*/
define ("SWEKEY_ERR_BADLY_ENCODED_REQUEST", 920);
define ("SWEKEY_ERR_INVALID_RND_TOKEN", 921);
define ("SWEKEY_ERR_DEV_NOT_FOUND", 922);
/**
* Default values for configuration.
*/
define ('SWEKEY_DEFAULT_CHECK_SERVER', 'https://auth-check.musbe.net');
define ('SWEKEY_DEFAULT_RND_SERVER', 'https://auth-rnd-gen.musbe.net');
define ('SWEKEY_DEFAULT_STATUS_SERVER', 'https://auth-status.musbe.net');
/**
* The last error of an operation is alway put in this global var
*/
global $gSwekeyLastError;
$gSwekeyLastError = 0;
global $gSwekeyLastResult;
$gSwekeyLastResult = "<not set>";
/**
* Servers addresses
* Use the Swekey_SetXxxServer($server) functions to set them
*/
global $gSwekeyCheckServer;
if (! isset($gSwekeyCheckServer))
$gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
global $gSwekeyRndTokenServer;
if (! isset($gSwekeyRndTokenServer))
$gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
global $gSwekeyStatusServer;
if (! isset($gSwekeyStatusServer))
$gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
global $gSwekeyCA;
global $gSwekeyTokenCacheEnabled;
if (! isset($gSwekeyTokenCacheEnabled))
$gSwekeyTokenCacheEnabled = true;
/**
* Change the address of the Check server.
* If $server is empty the default value 'http://auth-check.musbe.net' will be used
*
* @param server The protocol and hostname to use
* @access public
*/
function Swekey_SetCheckServer($server)
{
global $gSwekeyCheckServer;
if (empty($server))
$gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
else
$gSwekeyCheckServer = $server;
}
/**
* Change the address of the Random Token Generator server.
* If $server is empty the default value 'http://auth-rnd-gen.musbe.net' will be used
*
* @param server The protocol and hostname to use
* @access public
*/
function Swekey_SetRndTokenServer($server)
{
global $gSwekeyRndTokenServer;
if (empty($server))
$gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
else
$gSwekeyRndTokenServer = $server;
}
/**
* Change the address of the Satus server.
* If $server is empty the default value 'http://auth-status.musbe.net' will be used
*
* @param server The protocol and hostname to use
* @access public
*/
function Swekey_SetStatusServer($server)
{
global $gSwekeyStatusServer;
if (empty($server))
$gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
else
$gSwekeyStatusServer = $server;
}
/**
* Change the certificat file in case of the the severs use https instead of http
*
* @param cafile The path of the crt file to use
* @access public
*/
function Swekey_SetCAFile($cafile)
{
global $gSwekeyCA;
$gSwekeyCA = $cafile;
}
/**
* Enable or disable the random token caching
* Because everybody has full access to the cache file, it can be a DOS vulnerability
* So disable it if you are running in a non secure enviromnement
*
* @param $enable
* @access public
*/
function Swekey_EnableTokenCache($enable)
{
global $gSwekeyTokenCacheEnabled;
$gSwekeyTokenCacheEnabled = ! empty($enable);
}
/**
* Return the last error.
*
* @return The Last Error
* @access public
*/
function Swekey_GetLastError()
{
global $gSwekeyLastError;
return $gSwekeyLastError;
}
/**
* Return the last result.
*
* @return The Last Error
* @access public
*/
function Swekey_GetLastResult()
{
global $gSwekeyLastResult;
return $gSwekeyLastResult;
}
/**
* Send a synchronous request to the server.
* This function manages timeout then will not block if one of the server is down
*
* @param url The url to get
* @param response_code The response code
* @return The body of the response or "" in case of error
* @access private
*/
function Swekey_HttpGet($url, &$response_code)
{
global $gSwekeyLastError;
$gSwekeyLastError = 0;
global $gSwekeyLastResult;
$gSwekeyLastResult = "<not set>";
// use curl if available
if (function_exists('curl_init')) {
$sess = curl_init($url);
if (substr($url, 0, 8) == "https://") {
global $gSwekeyCA;
if (! empty($gSwekeyCA)) {
if (file_exists($gSwekeyCA)) {
if (! curl_setopt($sess, CURLOPT_CAINFO, $gSwekeyCA)) {
error_log("SWEKEY_ERROR:Could not set CA file : ".curl_error($sess));
} else {
$caFileOk = true;
}
} else {
error_log("SWEKEY_ERROR:Could not find CA file $gSwekeyCA getting $url");
}
}
curl_setopt($sess, CURLOPT_SSL_VERIFYHOST, '2');
curl_setopt($sess, CURLOPT_SSL_VERIFYPEER, '2');
curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '20');
curl_setopt($sess, CURLOPT_TIMEOUT, '20');
} else {
curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '3');
curl_setopt($sess, CURLOPT_TIMEOUT, '5');
}
curl_setopt($sess, CURLOPT_RETURNTRANSFER, '1');
$res=curl_exec($sess);
$response_code = curl_getinfo($sess, CURLINFO_HTTP_CODE);
$curlerr = curl_error($sess);
curl_close($sess);
if ($response_code == 200) {
$gSwekeyLastResult = $res;
return $res;
}
if (! empty($response_code)) {
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error $gSwekeyLastError ($curlerr) getting $url");
return "";
}
$response_code = 408; // Request Timeout
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error $curlerr getting $url");
return "";
}
// use pecl_http if available
if (class_exists('HttpRequest')) {
// retry if one of the server is down
for ($num=1; $num <= 3; $num++ ) {
$r = new HttpRequest($url);
$options = array('timeout' => '3');
if (substr($url, 0, 6) == "https:") {
$sslOptions = array();
$sslOptions['verifypeer'] = true;
$sslOptions['verifyhost'] = true;
$capath = __FILE__;
$name = strrchr($capath, '/');
// windows
if (empty($name)) {
$name = strrchr($capath, '\\');
}
$capath = substr($capath, 0, strlen($capath) - strlen($name) + 1).'musbe-ca.crt';
if (! empty($gSwekeyCA)) {
$sslOptions['cainfo'] = $gSwekeyCA;
}
$options['ssl'] = $sslOptions;
}
$r->setOptions($options);
// try
{
$reply = $r->send();
$res = $reply->getBody();
$info = $r->getResponseInfo();
$response_code = $info['response_code'];
if ($response_code != 200)
{
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
return "";
}
$gSwekeyLastResult = $res;
return $res;
}
// catch (HttpException $e)
// {
// error_log("SWEKEY_WARNING:HttpException ".$e." getting ".$url);
// }
}
$response_code = 408; // Request Timeout
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
return "";
}
global $http_response_header;
$res = @file_get_contents($url);
$response_code = substr($http_response_header[0], 9, 3); //HTTP/1.0
if ($response_code == 200) {
$gSwekeyLastResult = $res;
return $res;
}
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error ".$response_code." getting ".$url);
return "";
}
/**
* Get a Random Token from a Token Server
* The RT is a 64 vhars hexadecimal value
* You should better use Swekey_GetFastRndToken() for performance
* @access public
*/
function Swekey_GetRndToken()
{
global $gSwekeyRndTokenServer;
return Swekey_HttpGet($gSwekeyRndTokenServer.'/FULL-RND-TOKEN', $response_code);
}
/**
* Get a Half Random Token from a Token Server
* The RT is a 64 vhars hexadecimal value
* Use this value if you want to make your own Swekey_GetFastRndToken()
* @access public
*/
function Swekey_GetHalfRndToken()
{
global $gSwekeyRndTokenServer;
return Swekey_HttpGet($gSwekeyRndTokenServer.'/HALF-RND-TOKEN', $response_code);
}
/**
* Get a Half Random Token
* The RT is a 64 vhars hexadecimal value
* This function get a new random token and reuse it.
* Token are refetched from the server only once every 30 seconds.
* You should always use this function to get half random token.
* @access public
*/
function Swekey_GetFastHalfRndToken()
{
global $gSwekeyTokenCacheEnabled;
$res = "";
$cachefile = "";
// We check if we have a valid RT is the session
if (isset($_SESSION['rnd-token-date'])) {
if (time() - $_SESSION['rnd-token-date'] < 30) {
$res = $_SESSION['rnd-token'];
}
}
// If not we try to get it from a temp file (PHP >= 5.2.1 only)
if (strlen($res) != 32 && $gSwekeyTokenCacheEnabled) {
if (function_exists('sys_get_temp_dir')) {
$tempdir = sys_get_temp_dir();
$cachefile = $tempdir."/swekey-rnd-token-".get_current_user();
$modif = filemtime($cachefile);
if ($modif != false) {
if (time() - $modif < 30) {
$res = @file_get_contents($cachefile);
if (strlen($res) != 32) {
$res = "";
} else {
$_SESSION['rnd-token'] = $res;
$_SESSION['rnd-token-date'] = $modif;
}
}
}
}
}
// If we don't have a valid RT here we have to get it from the server
if (strlen($res) != 32) {
$res = substr(Swekey_GetHalfRndToken(), 0, 32);
$_SESSION['rnd-token'] = $res;
$_SESSION['rnd-token-date'] = time();
if (! empty($cachefile)) {
// we unlink the file so no possible tempfile race attack
unlink($cachefile);
$file = fopen($cachefile, "x");
if ($file != false) {
@fwrite($file, $res);
@fclose($file);
}
}
}
return $res."00000000000000000000000000000000";
}
/**
* Get a Random Token
* The RT is a 64 vhars hexadecimal value
* This function generates a unique random token for each call but call the
* server only once every 30 seconds.
* You should always use this function to get random token.
* @access public
*/
function Swekey_GetFastRndToken()
{
$res = Swekey_GetFastHalfRndToken();
if (strlen($res) == 64)
return substr($res, 0, 32).strtoupper(md5("Musbe Authentication Key" + mt_rand() + date(DATE_ATOM)));
return "";
}
/**
* Checks that an OTP generated by a Swekey is valid
*
* @param id The id of the swekey
* @param rt The random token used to generate the otp
* @param otp The otp generated by the swekey
* @return true or false
* @access public
*/
function Swekey_CheckOtp($id, $rt, $otp)
{
global $gSwekeyCheckServer;
$res = Swekey_HttpGet($gSwekeyCheckServer.'/CHECK-OTP/'.$id.'/'.$rt.'/'.$otp, $response_code);
return $response_code == 200 && $res == "OK";
}
/**
* Values that are associated with a key.
* The following values can be returned by the Swekey_GetStatus() function
*/
define ("SWEKEY_STATUS_OK", 0);
define ("SWEKEY_STATUS_NOT_FOUND", 1); // The key does not exist in the db
define ("SWEKEY_STATUS_INACTIVE", 2); // The key has never been activated
define ("SWEKEY_STATUS_LOST", 3); // The user has lost his key
define ("SWEKEY_STATUS_STOLEN", 4); // The key was stolen
define ("SWEKEY_STATUS_FEE_DUE", 5); // The annual fee was not paid
define ("SWEKEY_STATUS_OBSOLETE", 6); // The hardware is no longer supported
define ("SWEKEY_STATUS_UNKOWN", 201); // We could not connect to the authentication server
/**
* Values that are associated with a key.
* The Javascript Api can also return the following values
*/
define ("SWEKEY_STATUS_REPLACED", 100); // This key has been replaced by a backup key
define ("SWEKEY_STATUS_BACKUP_KEY", 101); // This key is a backup key that is not activated yet
define ("SWEKEY_STATUS_NOTPLUGGED", 200); // This key is not plugged in the computer
/**
* Return the text corresponding to the integer status of a key
*
* @param status The status
* @return The text corresponding to the status
* @access public
*/
function Swekey_GetStatusStr($status)
{
switch($status)
{
case SWEKEY_STATUS_OK : return 'OK';
case SWEKEY_STATUS_NOT_FOUND : return 'Key does not exist in the db';
case SWEKEY_STATUS_INACTIVE : return 'Key not activated';
case SWEKEY_STATUS_LOST : return 'Key was lost';
case SWEKEY_STATUS_STOLEN : return 'Key was stolen';
case SWEKEY_STATUS_FEE_DUE : return 'The annual fee was not paid';
case SWEKEY_STATUS_OBSOLETE : return 'Key no longer supported';
case SWEKEY_STATUS_REPLACED : return 'This key has been replaced by a backup key';
case SWEKEY_STATUS_BACKUP_KEY : return 'This key is a backup key that is not activated yet';
case SWEKEY_STATUS_NOTPLUGGED : return 'This key is not plugged in the computer';
case SWEKEY_STATUS_UNKOWN : return 'Unknow Status, could not connect to the authentication server';
}
return 'unknown status '.$status;
}
/**
* If your web site requires a key to login you should check that the key
* is still valid (has not been lost or stolen) before requiring it.
* A key can be authenticated only if its status is SWEKEY_STATUS_OK
* @param id The id of the swekey
* @return The status of the swekey
* @access public
*/
function Swekey_GetStatus($id)
{
global $gSwekeyStatusServer;
$res = Swekey_HttpGet($gSwekeyStatusServer.'/GET-STATUS/'.$id, $response_code);
if ($response_code == 200)
return intval($res);
return SWEKEY_STATUS_UNKOWN;
}
?>

View File

@ -0,0 +1,649 @@
<?php
function loadData($type, $data) {
if (!$data) return $data;
$tmp = unpack($type, $data);
return current($tmp);
}
function swap($binValue) {
$result = $binValue{strlen($binValue) - 1};
for($i = strlen($binValue) - 2; $i >= 0 ; $i--) {
$result .= $binValue{$i};
}
return $result;
}
function packDouble($value, $mode = 'LE') {
$value = (double)$value;
$bin = pack("d", $value);
//We test if the conversion of an integer (1) is done as LE or BE by default
switch (pack ('L', 1)) {
case pack ('V', 1): //Little Endian
$result = ($mode == 'LE') ? $bin : swap($bin);
break;
case pack ('N', 1): //Big Endian
$result = ($mode == 'BE') ? $bin : swap($bin);
break;
default: //Some other thing, we just return false
$result = FALSE;
}
return $result;
}
class ShapeFile {
var $FileName;
var $SHPFile;
var $SHXFile;
var $DBFFile;
var $DBFHeader;
var $lastError = "";
var $boundingBox = array("xmin" => 0.0, "ymin" => 0.0, "xmax" => 0.0, "ymax" => 0.0);
var $fileLength = 0;
var $shapeType = 0;
var $records;
function ShapeFile($shapeType, $boundingBox = array("xmin" => 0.0, "ymin" => 0.0, "xmax" => 0.0, "ymax" => 0.0), $FileName = NULL) {
$this->shapeType = $shapeType;
$this->boundingBox = $boundingBox;
$this->FileName = $FileName;
$this->fileLength = 50;
}
function loadFromFile($FileName) {
$this->FileName = $FileName;
if (($this->_openSHPFile()) && ($this->_openDBFFile())) {
$this->_loadHeaders();
$this->_loadRecords();
$this->_closeSHPFile();
$this->_closeDBFFile();
} else {
return false;
}
}
function saveToFile($FileName = NULL) {
if ($FileName != NULL) $this->FileName = $FileName;
if (($this->_openSHPFile(TRUE)) && ($this->_openSHXFile(TRUE)) && ($this->_openDBFFile(TRUE))) {
$this->_saveHeaders();
$this->_saveRecords();
$this->_closeSHPFile();
$this->_closeSHXFile();
$this->_closeDBFFile();
} else {
return false;
}
}
function addRecord($record) {
if ((isset($this->DBFHeader)) && (is_array($this->DBFHeader))) {
$record->updateDBFInfo($this->DBFHeader);
}
$this->fileLength += ($record->getContentLength() + 4);
$this->records[] = $record;
$this->records[count($this->records) - 1]->recordNumber = count($this->records);
return (count($this->records) - 1);
}
function deleteRecord($index) {
if (isset($this->records[$index])) {
$this->fileLength -= ($this->records[$index]->getContentLength() + 4);
for ($i = $index; $i < (count($this->records) - 1); $i++) {
$this->records[$i] = $this->records[$i + 1];
}
unset($this->records[count($this->records) - 1]);
$this->_deleteRecordFromDBF($index);
}
}
function getDBFHeader() {
return $this->DBFHeader;
}
function setDBFHeader($header) {
$this->DBFHeader = $header;
for ($i = 0; $i < count($this->records); $i++) {
$this->records[$i]->updateDBFInfo($header);
}
}
function getIndexFromDBFData($field, $value) {
$result = -1;
for ($i = 0; $i < (count($this->records) - 1); $i++) {
if (isset($this->records[$i]->DBFData[$field]) && (strtoupper($this->records[$i]->DBFData[$field]) == strtoupper($value))) {
$result = $i;
}
}
return $result;
}
function _loadDBFHeader() {
$DBFFile = fopen(str_replace('.*', '.dbf', $this->FileName), 'r');
$result = array();
$buff32 = array();
$i = 1;
$inHeader = true;
while ($inHeader) {
if (!feof($DBFFile)) {
$buff32 = fread($DBFFile, 32);
if ($i > 1) {
if (substr($buff32, 0, 1) == chr(13)) {
$inHeader = false;
} else {
$pos = strpos(substr($buff32, 0, 10), chr(0));
$pos = ($pos == 0 ? 10 : $pos);
$fieldName = substr($buff32, 0, $pos);
$fieldType = substr($buff32, 11, 1);
$fieldLen = ord(substr($buff32, 16, 1));
$fieldDec = ord(substr($buff32, 17, 1));
array_push($result, array($fieldName, $fieldType, $fieldLen, $fieldDec));
}
}
$i++;
} else {
$inHeader = false;
}
}
fclose($DBFFile);
return($result);
}
function _deleteRecordFromDBF($index) {
if (@dbase_delete_record($this->DBFFile, $index)) {
@dbase_pack($this->DBFFile);
}
}
function _loadHeaders() {
fseek($this->SHPFile, 24, SEEK_SET);
$this->fileLength = loadData("N", fread($this->SHPFile, 4));
fseek($this->SHPFile, 32, SEEK_SET);
$this->shapeType = loadData("V", fread($this->SHPFile, 4));
$this->boundingBox = array();
$this->boundingBox["xmin"] = loadData("d", fread($this->SHPFile, 8));
$this->boundingBox["ymin"] = loadData("d", fread($this->SHPFile, 8));
$this->boundingBox["xmax"] = loadData("d", fread($this->SHPFile, 8));
$this->boundingBox["ymax"] = loadData("d", fread($this->SHPFile, 8));
$this->DBFHeader = $this->_loadDBFHeader();
}
function _saveHeaders() {
fwrite($this->SHPFile, pack("NNNNNN", 9994, 0, 0, 0, 0, 0));
fwrite($this->SHPFile, pack("N", $this->fileLength));
fwrite($this->SHPFile, pack("V", 1000));
fwrite($this->SHPFile, pack("V", $this->shapeType));
fwrite($this->SHPFile, packDouble($this->boundingBox['xmin']));
fwrite($this->SHPFile, packDouble($this->boundingBox['ymin']));
fwrite($this->SHPFile, packDouble($this->boundingBox['xmax']));
fwrite($this->SHPFile, packDouble($this->boundingBox['ymax']));
fwrite($this->SHPFile, pack("dddd", 0, 0, 0, 0));
fwrite($this->SHXFile, pack("NNNNNN", 9994, 0, 0, 0, 0, 0));
fwrite($this->SHXFile, pack("N", 50 + 4*count($this->records)));
fwrite($this->SHXFile, pack("V", 1000));
fwrite($this->SHXFile, pack("V", $this->shapeType));
fwrite($this->SHXFile, packDouble($this->boundingBox['xmin']));
fwrite($this->SHXFile, packDouble($this->boundingBox['ymin']));
fwrite($this->SHXFile, packDouble($this->boundingBox['xmax']));
fwrite($this->SHXFile, packDouble($this->boundingBox['ymax']));
fwrite($this->SHXFile, pack("dddd", 0, 0, 0, 0));
}
function _loadRecords() {
fseek($this->SHPFile, 100);
while (!feof($this->SHPFile)) {
$bByte = ftell($this->SHPFile);
$record = new ShapeRecord(-1);
$record->loadFromFile($this->SHPFile, $this->DBFFile);
$eByte = ftell($this->SHPFile);
if (($eByte <= $bByte) || ($record->lastError != "")) {
return false;
}
$this->records[] = $record;
}
}
function _saveRecords() {
if (file_exists(str_replace('.*', '.dbf', $this->FileName))) {
@unlink(str_replace('.*', '.dbf', $this->FileName));
}
if (!($this->DBFFile = @dbase_create(str_replace('.*', '.dbf', $this->FileName), $this->DBFHeader))) {
return $this->setError(sprintf("It wasn't possible to create the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
$offset = 50;
if (is_array($this->records) && (count($this->records) > 0)) {
reset($this->records);
while (list($index, $record) = each($this->records)) {
//Save the record to the .shp file
$record->saveToFile($this->SHPFile, $this->DBFFile, $index + 1);
//Save the record to the .shx file
fwrite($this->SHXFile, pack("N", $offset));
fwrite($this->SHXFile, pack("N", $record->getContentLength()));
$offset += (4 + $record->getContentLength());
}
}
@dbase_pack($this->DBFFile);
}
function _openSHPFile($toWrite = false) {
$this->SHPFile = @fopen(str_replace('.*', '.shp', $this->FileName), ($toWrite ? "wb+" : "rb"));
if (!$this->SHPFile) {
return $this->setError(sprintf("It wasn't possible to open the Shape file '%s'", str_replace('.*', '.shp', $this->FileName)));
}
return TRUE;
}
function _closeSHPFile() {
if ($this->SHPFile) {
fclose($this->SHPFile);
$this->SHPFile = NULL;
}
}
function _openSHXFile($toWrite = false) {
$this->SHXFile = @fopen(str_replace('.*', '.shx', $this->FileName), ($toWrite ? "wb+" : "rb"));
if (!$this->SHXFile) {
return $this->setError(sprintf("It wasn't possible to open the Index file '%s'", str_replace('.*', '.shx', $this->FileName)));
}
return TRUE;
}
function _closeSHXFile() {
if ($this->SHXFile) {
fclose($this->SHXFile);
$this->SHXFile = NULL;
}
}
function _openDBFFile($toWrite = false) {
$checkFunction = $toWrite ? "is_writable" : "is_readable";
if (($toWrite) && (!file_exists(str_replace('.*', '.dbf', $this->FileName)))) {
if (!@dbase_create(str_replace('.*', '.dbf', $this->FileName), $this->DBFHeader)) {
return $this->setError(sprintf("It wasn't possible to create the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
}
if ($checkFunction(str_replace('.*', '.dbf', $this->FileName))) {
$this->DBFFile = dbase_open(str_replace('.*', '.dbf', $this->FileName), ($toWrite ? 2 : 0));
if (!$this->DBFFile) {
return $this->setError(sprintf("It wasn't possible to open the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
} else {
return $this->setError(sprintf("It wasn't possible to find the DBase file '%s'", str_replace('.*', '.dbf', $this->FileName)));
}
return TRUE;
}
function _closeDBFFile() {
if ($this->DBFFile) {
dbase_close($this->DBFFile);
$this->DBFFile = NULL;
}
}
function setError($error) {
$this->lastError = $error;
return false;
}
}
class ShapeRecord {
var $SHPFile = NULL;
var $DBFFile = NULL;
var $recordNumber = NULL;
var $shapeType = NULL;
var $lastError = "";
var $SHPData = array();
var $DBFData = array();
function ShapeRecord($shapeType) {
$this->shapeType = $shapeType;
}
function loadFromFile(&$SHPFile, &$DBFFile) {
$this->SHPFile = $SHPFile;
$this->DBFFile = $DBFFile;
$this->_loadHeaders();
switch ($this->shapeType) {
case 0:
$this->_loadNullRecord();
break;
case 1:
$this->_loadPointRecord();
break;
case 3:
$this->_loadPolyLineRecord();
break;
case 5:
$this->_loadPolygonRecord();
break;
case 8:
$this->_loadMultiPointRecord();
break;
default:
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
$this->_loadDBFData();
}
function saveToFile(&$SHPFile, &$DBFFile, $recordNumber) {
$this->SHPFile = $SHPFile;
$this->DBFFile = $DBFFile;
$this->recordNumber = $recordNumber;
$this->_saveHeaders();
switch ($this->shapeType) {
case 0:
$this->_saveNullRecord();
break;
case 1:
$this->_savePointRecord();
break;
case 3:
$this->_savePolyLineRecord();
break;
case 5:
$this->_savePolygonRecord();
break;
case 8:
$this->_saveMultiPointRecord();
break;
default:
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
$this->_saveDBFData();
}
function updateDBFInfo($header) {
$tmp = $this->DBFData;
unset($this->DBFData);
$this->DBFData = array();
reset($header);
while (list($key, $value) = each($header)) {
$this->DBFData[$value[0]] = (isset($tmp[$value[0]])) ? $tmp[$value[0]] : "";
}
}
function _loadHeaders() {
$this->recordNumber = loadData("N", fread($this->SHPFile, 4));
$tmp = loadData("N", fread($this->SHPFile, 4)); //We read the length of the record
$this->shapeType = loadData("V", fread($this->SHPFile, 4));
}
function _saveHeaders() {
fwrite($this->SHPFile, pack("N", $this->recordNumber));
fwrite($this->SHPFile, pack("N", $this->getContentLength()));
fwrite($this->SHPFile, pack("V", $this->shapeType));
}
function _loadPoint() {
$data = array();
$data["x"] = loadData("d", fread($this->SHPFile, 8));
$data["y"] = loadData("d", fread($this->SHPFile, 8));
return $data;
}
function _savePoint($data) {
fwrite($this->SHPFile, packDouble($data["x"]));
fwrite($this->SHPFile, packDouble($data["y"]));
}
function _loadNullRecord() {
$this->SHPData = array();
}
function _saveNullRecord() {
//Don't save anything
}
function _loadPointRecord() {
$this->SHPData = $this->_loadPoint();
}
function _savePointRecord() {
$this->_savePoint($this->SHPData);
}
function _loadMultiPointRecord() {
$this->SHPData = array();
$this->SHPData["xmin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["xmax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["numpoints"] = loadData("V", fread($this->SHPFile, 4));
for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
$this->SHPData["points"][] = $this->_loadPoint();
}
}
function _saveMultiPointRecord() {
fwrite($this->SHPFile, pack("dddd", $this->SHPData["xmin"], $this->SHPData["ymin"], $this->SHPData["xmax"], $this->SHPData["ymax"]));
fwrite($this->SHPFile, pack("V", $this->SHPData["numpoints"]));
for ($i = 0; $i <= $this->SHPData["numpoints"]; $i++) {
$this->_savePoint($this->SHPData["points"][$i]);
}
}
function _loadPolyLineRecord() {
$this->SHPData = array();
$this->SHPData["xmin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymin"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["xmax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["ymax"] = loadData("d", fread($this->SHPFile, 8));
$this->SHPData["numparts"] = loadData("V", fread($this->SHPFile, 4));
$this->SHPData["numpoints"] = loadData("V", fread($this->SHPFile, 4));
for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
$this->SHPData["parts"][$i] = loadData("V", fread($this->SHPFile, 4));
}
$firstIndex = ftell($this->SHPFile);
$readPoints = 0;
reset($this->SHPData["parts"]);
while (list($partIndex, $partData) = each($this->SHPData["parts"])) {
if (!isset($this->SHPData["parts"][$partIndex]["points"]) || !is_array($this->SHPData["parts"][$partIndex]["points"])) {
$this->SHPData["parts"][$partIndex] = array();
$this->SHPData["parts"][$partIndex]["points"] = array();
}
while (!in_array($readPoints, $this->SHPData["parts"]) && ($readPoints < ($this->SHPData["numpoints"])) && !feof($this->SHPFile)) {
$this->SHPData["parts"][$partIndex]["points"][] = $this->_loadPoint();
$readPoints++;
}
}
fseek($this->SHPFile, $firstIndex + ($readPoints*16));
}
function _savePolyLineRecord() {
fwrite($this->SHPFile, pack("dddd", $this->SHPData["xmin"], $this->SHPData["ymin"], $this->SHPData["xmax"], $this->SHPData["ymax"]));
fwrite($this->SHPFile, pack("VV", $this->SHPData["numparts"], $this->SHPData["numpoints"]));
for ($i = 0; $i < $this->SHPData["numparts"]; $i++) {
fwrite($this->SHPFile, pack("V", count($this->SHPData["parts"][$i])));
}
reset($this->SHPData["parts"]);
foreach ($this->SHPData["parts"] as $partData){
reset($partData["points"]);
while (list($pointIndex, $pointData) = each($partData["points"])) {
$this->_savePoint($pointData);
}
}
}
function _loadPolygonRecord() {
$this->_loadPolyLineRecord();
}
function _savePolygonRecord() {
$this->_savePolyLineRecord();
}
function addPoint($point, $partIndex = 0) {
switch ($this->shapeType) {
case 0:
//Don't add anything
break;
case 1:
//Substitutes the value of the current point
$this->SHPData = $point;
break;
case 3:
case 5:
//Adds a new point to the selected part
if (!isset($this->SHPData["xmin"]) || ($this->SHPData["xmin"] > $point["x"])) $this->SHPData["xmin"] = $point["x"];
if (!isset($this->SHPData["ymin"]) || ($this->SHPData["ymin"] > $point["y"])) $this->SHPData["ymin"] = $point["y"];
if (!isset($this->SHPData["xmax"]) || ($this->SHPData["xmax"] < $point["x"])) $this->SHPData["xmax"] = $point["x"];
if (!isset($this->SHPData["ymax"]) || ($this->SHPData["ymax"] < $point["y"])) $this->SHPData["ymax"] = $point["y"];
$this->SHPData["parts"][$partIndex]["points"][] = $point;
$this->SHPData["numparts"] = count($this->SHPData["parts"]);
$this->SHPData["numpoints"]++;
break;
case 8:
//Adds a new point
if (!isset($this->SHPData["xmin"]) || ($this->SHPData["xmin"] > $point["x"])) $this->SHPData["xmin"] = $point["x"];
if (!isset($this->SHPData["ymin"]) || ($this->SHPData["ymin"] > $point["y"])) $this->SHPData["ymin"] = $point["y"];
if (!isset($this->SHPData["xmax"]) || ($this->SHPData["xmax"] < $point["x"])) $this->SHPData["xmax"] = $point["x"];
if (!isset($this->SHPData["ymax"]) || ($this->SHPData["ymax"] < $point["y"])) $this->SHPData["ymax"] = $point["y"];
$this->SHPData["points"][] = $point;
$this->SHPData["numpoints"]++;
break;
default:
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
}
function deletePoint($pointIndex = 0, $partIndex = 0) {
switch ($this->shapeType) {
case 0:
//Don't delete anything
break;
case 1:
//Sets the value of the point to zero
$this->SHPData["x"] = 0.0;
$this->SHPData["y"] = 0.0;
break;
case 3:
case 5:
//Deletes the point from the selected part, if exists
if (isset($this->SHPData["parts"][$partIndex]) && isset($this->SHPData["parts"][$partIndex]["points"][$pointIndex])) {
for ($i = $pointIndex; $i < (count($this->SHPData["parts"][$partIndex]["points"]) - 1); $i++) {
$this->SHPData["parts"][$partIndex]["points"][$i] = $this->SHPData["parts"][$partIndex]["points"][$i + 1];
}
unset($this->SHPData["parts"][$partIndex]["points"][count($this->SHPData["parts"][$partIndex]["points"]) - 1]);
$this->SHPData["numparts"] = count($this->SHPData["parts"]);
$this->SHPData["numpoints"]--;
}
break;
case 8:
//Deletes the point, if exists
if (isset($this->SHPData["points"][$pointIndex])) {
for ($i = $pointIndex; $i < (count($this->SHPData["points"]) - 1); $i++) {
$this->SHPData["points"][$i] = $this->SHPData["points"][$i + 1];
}
unset($this->SHPData["points"][count($this->SHPData["points"]) - 1]);
$this->SHPData["numpoints"]--;
}
break;
default:
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
}
function getContentLength() {
switch ($this->shapeType) {
case 0:
$result = 0;
break;
case 1:
$result = 10;
break;
case 3:
case 5:
$result = 22 + 2*count($this->SHPData["parts"]);
for ($i = 0; $i < count($this->SHPData["parts"]); $i++) {
$result += 8*count($this->SHPData["parts"][$i]["points"]);
}
break;
case 8:
$result = 20 + 8*count($this->SHPData["points"]);
break;
default:
$result = false;
$this->setError(sprintf("The Shape Type '%s' is not supported.", $this->shapeType));
break;
}
return $result;
}
function _loadDBFData() {
$this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
unset($this->DBFData["deleted"]);
}
function _saveDBFData() {
unset($this->DBFData["deleted"]);
if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
if (!dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
$this->setError("I wasn't possible to update the information in the DBF file.");
}
} else {
if (!dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
$this->setError("I wasn't possible to add the information to the DBF file.");
}
}
}
function setError($error) {
$this->lastError = $error;
return false;
}
}
?>

View File

@ -0,0 +1,582 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package BLOBStreaming
*/
/**
* Initializes PBMS database
*
* @return bool
*/
function initPBMSDatabase()
{
// If no other choice then try this.
$query = "create database IF NOT EXISTS pbms;";
/*
* The user may not have privileges to create the 'pbms' database
* so if it doesn't exist then we perform a select on a pbms system
* table in an already existing database which will cause the PBMS
* daemon to create the 'pbms' database.
*/
$db_array = PMA_DBI_fetch_result('SHOW DATABASES;');
if (! empty($db_array)) {
$target = "";
foreach ($db_array as $current_db) {
if ($current_db == 'pbms') {
return true;
}
if ($target == "") {
if ($current_db != 'pbxt'
&& ! PMA_is_system_schema($current_db, true)
) {
$target = $current_db;
}
}
}
if ($target != "") {
// If it exists this table will not contain much
$query = "select * from $target.pbms_metadata_header";
}
}
$result = PMA_DBI_query($query);
if (! $result) {
return false;
}
return true;
}
/**
* checks whether the necessary plugins for BLOBStreaming exist
*
* @access public
* @return boolean
*/
function checkBLOBStreamingPlugins()
{
if (PMA_cacheGet('skip_blobstreaming', true) === true) {
return false;
}
// load PMA configuration
$PMA_Config = $GLOBALS['PMA_Config'];
// return if unable to load PMA configuration
if (empty($PMA_Config)) {
return false;
}
// If we don't know that we can skip blobstreaming, we continue
// verifications; anyway, in case we won't skip blobstreaming,
// we still need to set some variables in non-persistent settings,
// which is done via $PMA_Config->set().
/** Retrieve current server configuration;
* at this point, $PMA_Config->get('Servers') contains the server parameters
* as explicitely defined in config.inc.php, so it cannot be used; it's
* better to use $GLOBALS['cfg']['Server'] which contains the explicit
* parameters merged with the default ones
*
*/
$serverCfg = $GLOBALS['cfg']['Server'];
// return if unable to retrieve current server configuration
if (! $serverCfg) {
return false;
}
// if PHP extension in use is 'mysql', specify element 'PersistentConnections'
if ($serverCfg['extension'] == "mysql") {
$serverCfg['PersistentConnections'] = $PMA_Config->settings['PersistentConnections'];
}
// if connection type is TCP, unload socket variable
if (strtolower($serverCfg['connect_type']) == "tcp") {
$serverCfg['socket'] = "";
}
$has_blobstreaming = PMA_cacheGet('has_blobstreaming', true);
if ($has_blobstreaming === null) {
if (! PMA_DRIZZLE && PMA_MYSQL_INT_VERSION >= 50109) {
// Retrieve MySQL plugins
$existing_plugins = PMA_DBI_fetch_result('SHOW PLUGINS');
foreach ($existing_plugins as $one_existing_plugin) {
// check if required plugins exist
if ( strtolower($one_existing_plugin['Library']) == 'libpbms.so'
&& $one_existing_plugin['Status'] == "ACTIVE"
) {
$has_blobstreaming = true;
break;
}
}
unset($existing_plugins, $one_existing_plugin);
} else if (PMA_DRIZZLE) {
$has_blobstreaming = (bool) PMA_DBI_fetch_result(
"SELECT 1
FROM data_dictionary.plugins
WHERE module_name = 'PBMS'
AND is_active = true
LIMIT 1"
);
}
PMA_cacheSet('has_blobstreaming', $has_blobstreaming, true);
}
// set variable indicating BS plugin existence
$PMA_Config->set('BLOBSTREAMING_PLUGINS_EXIST', $has_blobstreaming);
if (! $has_blobstreaming) {
PMA_cacheSet('skip_blobstreaming', true, true);
return false;
}
if ($has_blobstreaming) {
$bs_variables = PMA_BS_GetVariables();
// if no BS variables exist, set plugin existence to false and return
if (count($bs_variables) == 0) {
$PMA_Config->set('BLOBSTREAMING_PLUGINS_EXIST', false);
PMA_cacheSet('skip_blobstreaming', true, true);
PMA_cacheSet('has_blobstreaming', false, true);
return false;
} // end if (count($bs_variables) <= 0)
// Check that the required pbms functions exist:
if (function_exists("pbms_connect") == false
|| function_exists("pbms_error") == false
|| function_exists("pbms_close") == false
|| function_exists("pbms_is_blob_reference") == false
|| function_exists("pbms_get_info") == false
|| function_exists("pbms_get_metadata_value") == false
|| function_exists("pbms_add_metadata") == false
|| function_exists("pbms_read_stream") == false
) {
// We should probably notify the user that they need to install
// the pbms client lib and PHP extension to make use of blob streaming.
$PMA_Config->set('BLOBSTREAMING_PLUGINS_EXIST', false);
PMA_cacheSet('skip_blobstreaming', true, true);
PMA_cacheSet('has_blobstreaming', false, true);
return false;
}
if (function_exists("pbms_connection_pool_size")) {
if ( isset($PMA_Config->settings['pbms_connection_pool_size'])) {
$pool_size = $PMA_Config->settings['pbms_connection_pool_size'];
if ($pool_size == "") {
$pool_size = 1;
}
} else {
$pool_size = 1;
}
pbms_connection_pool_size($pool_size);
}
// get BS server port
$BS_PORT = $bs_variables['pbms_port'];
// if no BS server port or 'pbms' database exists,
// set plugin existance to false and return
if ((! $BS_PORT) || (! initPBMSDatabase())) {
$PMA_Config->set('BLOBSTREAMING_PLUGINS_EXIST', false);
PMA_cacheSet('skip_blobstreaming', true, true);
return false;
} // end if (!$BS_PORT)
// Ping PBMS: the database doesn't need to exist for this to work.
if (pbms_connect($serverCfg['host'], $BS_PORT, "anydb") == false) {
$PMA_Config->set('BLOBSTREAMING_PLUGINS_EXIST', false);
PMA_cacheSet('skip_blobstreaming', true, true);
return false;
}
pbms_close();
if (function_exists("pbms_pconnect")) {
$PMA_Config->set('PBMS_PCONNECT_EXISTS', true);
} else {
$PMA_Config->set('PBMS_PCONNECT_EXISTS', false);
}
// add selected BS, CURL and fileinfo library variables to PMA configuration
$PMA_Config->set('BLOBSTREAMING_PORT', $BS_PORT);
$PMA_Config->set('BLOBSTREAMING_HOST', $serverCfg['host']);
$PMA_Config->set('BLOBSTREAMING_SERVER', $serverCfg['host'] . ':' . $BS_PORT);
$PMA_Config->set('PHP_PBMS_EXISTS', false);
$PMA_Config->set('FILEINFO_EXISTS', false);
// check if PECL's fileinfo library exist
$finfo = null;
if (function_exists("finfo_open")) {
$finfo = finfo_open(FILEINFO_MIME);
}
// fileinfo library exists, set necessary variable and close resource
if (! empty($finfo)) {
$PMA_Config->set('FILEINFO_EXISTS', true);
finfo_close($finfo);
} // end if (!empty($finfo))
} else {
PMA_cacheSet('skip_blobstreaming', true, true);
return false;
} // end if ($has_blobstreaming)
return true;
}
/**
* returns a list of BLOBStreaming variables used by MySQL
*
* @access public
* @return array - list of BLOBStreaming variables
*/
function PMA_BS_GetVariables()
{
// load PMA configuration
$PMA_Config = $GLOBALS['PMA_Config'];
// return if unable to load PMA configuration
if (empty($PMA_Config)) {
return null;
}
// run query to retrieve BS variables
$query = "SHOW VARIABLES LIKE '%pbms%'";
$result = PMA_DBI_query($query);
$BS_Variables = array();
// while there are records to retrieve
while ($data = @PMA_DBI_fetch_assoc($result)) {
$BS_Variables[$data['Variable_name']] = $data['Value'];
}
// return BS variables
return $BS_Variables;
}
/**
* Retrieves and shows PBMS error.
*
* @param sting $msg error message
*
* @return nothing
*/
function PMA_BS_ReportPBMSError($msg)
{
$tmp_err = pbms_error();
PMA_showMessage(__('PBMS error') . " $msg $tmp_err");
}
/**
* Tries to connect to PBMS server.
*
* @param string $db_name Database name
* @param bool $quiet Whether to report errors
*
* @return bool Connection status.
*/
function PMA_do_connect($db_name, $quiet)
{
$PMA_Config = $GLOBALS['PMA_Config'];
// return if unable to load PMA configuration
if (empty($PMA_Config)) {
return false;
}
// generate bs reference link
$pbms_host = $PMA_Config->get('BLOBSTREAMING_HOST');
$pbms_port = $PMA_Config->get('BLOBSTREAMING_PORT');
if ($PMA_Config->get('PBMS_PCONNECT_EXISTS')) {
// Open a persistent connection.
$ok = pbms_pconnect($pbms_host, $pbms_port, $db_name);
} else {
$ok = pbms_connect($pbms_host, $pbms_port, $db_name);
}
if ($ok == false) {
if ($quiet == false) {
PMA_BS_ReportPBMSError(
__('PBMS connection failed:')
. " pbms_connect($pbms_host, $pbms_port, $db_name)"
);
}
return false;
}
return true;
}
/**
* Disconnects from PBMS server.
*
* @return nothing
*/
function PMA_do_disconnect()
{
pbms_close();
}
/**
* Checks whether the BLOB reference looks valid
*
* @param string $bs_reference BLOB reference
* @param string $db_name Database name
*
* @return bool True on success.
*/
function PMA_BS_IsPBMSReference($bs_reference, $db_name)
{
if (PMA_cacheGet('skip_blobstreaming', true)) {
return false;
}
// You do not really need a connection to the PBMS Daemon
// to check if a reference looks valid but unfortunalty the API
// requires one at this point so until the API is updated
// we need to epen one here. If you use pool connections this
// will not be a performance problem.
if (PMA_do_connect($db_name, false) == false) {
return false;
}
$ok = pbms_is_blob_reference($bs_reference);
return $ok ;
}
//------------
function PMA_BS_CreateReferenceLink($bs_reference, $db_name)
{
if (PMA_do_connect($db_name, false) == false) {
return __('Error');
}
if (pbms_get_info(trim($bs_reference)) == false) {
PMA_BS_ReportPBMSError(
__('PBMS get BLOB info failed:')
. " pbms_get_info($bs_reference)"
);
PMA_do_disconnect();
return __('Error');
}
$content_type = pbms_get_metadata_value("Content-Type");
if ($content_type == false) {
$br = trim($bs_reference);
PMA_BS_ReportPBMSError(
"PMA_BS_CreateReferenceLink('$br', '$db_name'): "
. __('PBMS get BLOB Content-Type failed')
);
}
PMA_do_disconnect();
if (! $content_type) {
$content_type = "image/jpeg";
}
$bs_url = PMA_BS_getURL($bs_reference);
if (empty($bs_url)) {
PMA_BS_ReportPBMSError(__('No blob streaming server configured!'));
return 'Error';
}
$output = $content_type;
// specify custom HTML for various content types
switch ($content_type) {
// no content specified
case null:
$output = "NULL";
break;
// image content
case 'image/jpeg':
case 'image/png':
$output .= ' (<a href="' . $bs_url . '" target="new">'
. __('View image') . '</a>)';
break;
// audio content
case 'audio/mpeg':
$output .= ' (<a href="#" onclick="popupBSMedia(\''
. PMA_generate_common_url() . '\',\'' . urlencode($bs_reference)
. '\', \'' . urlencode($content_type) . '\','
. ($is_custom_type ? 1 : 0) . ', 640, 120)">' . __('Play audio')
. '</a>)';
break;
// video content
case 'application/x-flash-video':
case 'video/mpeg':
$output .= ' (<a href="#" onclick="popupBSMedia(\''
. PMA_generate_common_url() . '\',\'' . urlencode($bs_reference)
. '\', \'' . urlencode($content_type) . '\','
. ($is_custom_type ? 1 : 0) . ', 640, 480)">' . __('View video')
. '</a>)';
break;
// unsupported content. specify download
default:
$output .= ' (<a href="' . $bs_url . '" target="new">'
. __('Download file') . '</a>)';
}
return $output;
}
/**
* In the future there may be server variables to turn on/off PBMS
* BLOB streaming on a per table or database basis. So in anticipation of this
* PMA_BS_IsTablePBMSEnabled() passes in the table and database name even though
* they are not currently needed.
*
* @param string $db_name database name
* @param string $tbl_name table name
* @param string $tbl_type table type
*
* @return bool
*/
function PMA_BS_IsTablePBMSEnabled($db_name, $tbl_name, $tbl_type)
{
if (PMA_cacheGet('skip_blobstreaming', true)) {
return false;
}
if ((isset($tbl_type) == false) || (strlen($tbl_type) == 0)) {
return false;
}
// load PMA configuration
$PMA_Config = $GLOBALS['PMA_Config'];
// return if unable to load PMA configuration
if (empty($PMA_Config)) {
return false;
}
if (! $PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST')) {
return false;
}
// This information should be cached rather than selecting it each time.
// $query = "SELECT count(*) FROM information_schema.TABLES T,
// pbms.pbms_enabled E where T.table_schema = ". PMA_backquote($db_name) . "
// and T.table_name = ". PMA_backquote($tbl_name) . " and T.engine = E.name";
$query = "SELECT count(*) FROM pbms.pbms_enabled E where E.name = '"
. PMA_sqlAddSlashes($tbl_type) . "'";
$result = PMA_DBI_query($query);
$data = PMA_DBI_fetch_row($result);
if ($data[0] == 1) {
return true;
}
return false;
}
//------------
function PMA_BS_UpLoadFile($db_name, $tbl_name, $file_type, $file_name)
{
if (PMA_cacheGet('skip_blobstreaming', true)) {
return false;
}
if (PMA_do_connect($db_name, false) == false) {
return false;
}
$fh = fopen($file_name, 'r');
if (! $fh) {
PMA_do_disconnect();
PMA_showMessage(sprintf(__('Could not open file: %s'), $file_name));
return false;
}
pbms_add_metadata("Content-Type", $file_type);
$pbms_blob_url = pbms_read_stream($fh, filesize($file_name), $tbl_name);
if (! $pbms_blob_url) {
PMA_BS_ReportPBMSError("pbms_read_stream()");
}
fclose($fh);
PMA_do_disconnect();
return $pbms_blob_url;
}
//------------
function PMA_BS_SetContentType($db_name, $bsTable, $blobReference, $contentType)
{
if (PMA_cacheGet('skip_blobstreaming', true)) {
return false;
}
// This is a really ugly way to do this but currently there is nothing better.
// In a future version of PBMS the system tables will be redesigned to make this
// more efficient.
$query = "SELECT Repository_id, Repo_blob_offset FROM pbms_reference"
. " WHERE Blob_url='" . PMA_sqlAddSlashes($blobReference) . "'";
//error_log(" PMA_BS_SetContentType: $query\n", 3, "/tmp/mylog");
$result = PMA_DBI_query($query);
//error_log(" $query\n", 3, "/tmp/mylog");
// if record exists
if ($data = PMA_DBI_fetch_assoc($result)) {
$where = "WHERE Repository_id=" . $data['Repository_id']
. " AND Repo_blob_offset=" . $data['Repo_blob_offset'] ;
$query = "SELECT name from pbms_metadata $where";
$result = PMA_DBI_query($query);
if (PMA_DBI_num_rows($result) == 0) {
$query = "INSERT into pbms_metadata Values( ". $data['Repository_id']
. ", " . $data['Repo_blob_offset'] . ", 'Content_type', '"
. PMA_sqlAddSlashes($contentType) . "')";
} else {
$query = "UPDATE pbms_metadata SET name = 'Content_type', Value = '"
. PMA_sqlAddSlashes($contentType) . "' $where";
}
//error_log("$query\n", 3, "/tmp/mylog");
PMA_DBI_query($query);
} else {
return false;
}
return true;
}
//------------
function PMA_BS_IsHiddenTable($table)
{
if ($table === 'pbms_repository'
|| $table === 'pbms_reference'
|| $table === 'pbms_metadata'
|| $table === 'pbms_metadata_header'
|| $table === 'pbms_dump'
) {
return true;
}
return false;
}
//------------
function PMA_BS_getURL($reference)
{
// load PMA configuration
$PMA_Config = $GLOBALS['PMA_Config'];
if (empty($PMA_Config)) {
return false;
}
// retrieve BS server variables from PMA configuration
$bs_server = $PMA_Config->get('BLOBSTREAMING_SERVER');
if (empty($bs_server)) {
return false;
}
$bs_url = PMA_linkURL('http://' . $bs_server . '/' . rtrim($reference));
return $bs_url;
}
?>

View File

@ -0,0 +1,535 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* The Horde_Cipher_Blowfish:: class implements the Horde_Cipher interface
* encryption data using the Blowfish algorithm.
*
* Copyright 2002-2009 The Horde Project (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
* @author Mike Cochrane <mike@graftonhall.co.nz>
* @package Horde_Cipher
*/
class Horde_Cipher_blowfish
{
/**
* Pi Array
*
* @var array
*/
protected $p = array(
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
0x9216D5D9, 0x8979FB1B);
/**
* S Box (s1)
*
* @var array
*/
protected $s1 = array(
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A);
/**
* S Box (s2)
*
* @var array
*/
protected $s2 = array(
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7);
/**
* S Box (s3)
*
* @var array
*/
protected $s3 = array(
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0);
/**
* S Box (s4)
*
* @var array
*/
protected $s4 = array(
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6);
/**
* The number of rounds to do
*
* @var integer
*/
protected $_rounds = 16;
/**
* Set the key to be used for en/decryption.
*
* @param string $key The key to use.
* @return bool
*/
public function setKey($key)
{
$key = array_values(unpack('C*', $key));
$keyLen = count($key);
if ($keyLen == 0) {
return false;
}
$keyPos = $keyXor = 0;
for ($i = 0, $iMax = count($this->p); $i < $iMax; ++$i) {
for ($t = 0; $t < 4; $t++) {
$keyXor = ($keyXor << 8) | (($key[$keyPos]) & 0x0ff);
if (++$keyPos == $keyLen) {
$keyPos = 0;
}
}
$this->p[$i] = $this->p[$i] ^ $keyXor;
}
$encZero = array('L' => 0, 'R' => 0);
for ($i = 0; $i + 1 < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->p[$i] = $encZero['L'];
$this->p[$i + 1] = $encZero['R'];
}
$iMax = count($this->s1);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s1[$i] = $encZero['L'];
$this->s1[$i + 1] = $encZero['R'];
}
$iMax = count($this->s2);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s2[$i] = $encZero['L'];
$this->s2[$i + 1] = $encZero['R'];
}
$iMax = count($this->s3);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s3[$i] = $encZero['L'];
$this->s3[$i + 1] = $encZero['R'];
}
$iMax = count($this->s4);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s4[$i] = $encZero['L'];
$this->s4[$i + 1] = $encZero['R'];
}
}
/**
* Encrypt a block of data.
*
* @param string $block The data to encrypt.
* @param string $key The key to use.
*
* @return string The encrypted output.
*/
public function encryptBlock($block, $key = null)
{
if (!is_null($key)) {
$this->setKey($key);
}
list($L, $R) = array_values(unpack('N*', $block));
$parts = $this->_encryptBlock($L, $R);
return pack('NN', $parts['L'], $parts['R']);
}
/**
* Encrypt left and right halves of a block of data.
*
* @param integer $L Left half of the data.
* @param integer $R Right half of the data.
*
* @return array A hash, with keys 'L' and 'R', and the encrypted data as
* the values.
*/
protected function _encryptBlock($L, $R)
{
$L ^= $this->p[0];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[1];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[2];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[3];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[4];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[5];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[6];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[7];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[8];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[9];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[10];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[11];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[12];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[13];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[14];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[15];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[16];
$R ^= $this->p[17];
return array('L' => $R, 'R' => $L);
}
/**
* Decrypt a block of data.
*
* @param string $block The data to decrypt.
* @param string $key The key to use.
*
* @return string The decrypted output.
*/
public function decryptBlock($block, $key = null)
{
if (!is_null($key)) {
$this->setKey($key);
}
// change for phpMyAdmin
$L = null;
$R = null;
$retarray = array_values(unpack('N*', $block));
if (isset($retarray[0])) {
$L = $retarray[0];
}
if (isset($retarray[1])) {
$R = $retarray[1];
}
// end change for phpMyAdmin
$L ^= $this->p[17];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[16];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[15];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[14];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[13];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[12];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[11];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[10];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[9];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[8];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[7];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[6];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[5];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[4];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[3];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[2];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[1];
return pack("NN", $R ^ $this->p[0], $L);
}
}
// higher-level functions:
/**
* Encryption using blowfish algorithm
*
* @param string original data
* @param string the secret
*
* @return string the encrypted result
*
* @access public
*
*/
function PMA_blowfish_encrypt($data, $secret)
{
$pma_cipher = new Horde_Cipher_blowfish;
$encrypt = '';
$mod = strlen($data) % 8;
if ($mod > 0) {
$data .= str_repeat("\0", 8 - $mod);
}
foreach (str_split($data, 8) as $chunk) {
$encrypt .= $pma_cipher->encryptBlock($chunk, $secret);
}
return base64_encode($encrypt);
}
/**
* Decryption using blowfish algorithm
*
* @param string encrypted data
* @param string the secret
*
* @return string original data
*
* @access public
*
*/
function PMA_blowfish_decrypt($encdata, $secret)
{
$pma_cipher = new Horde_Cipher_blowfish;
$decrypt = '';
$data = base64_decode($encdata);
foreach (str_split($data, 8) as $chunk) {
$decrypt .= $pma_cipher->decryptBlock($chunk, $secret);
}
return trim($decrypt);
}
?>

View File

@ -0,0 +1,187 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used with the bookmark feature
*
* @package PhpMyAdmin
*/
/**
* Defines the bookmark parameters for the current user
*
* @return array the bookmark parameters for the current user
* @access public
*/
function PMA_Bookmark_getParams()
{
static $cfgBookmark = null;
if (null !== $cfgBookmark) {
return $cfgBookmark;
}
$cfgRelation = PMA_getRelationsParam();
if ($cfgRelation['bookmarkwork']) {
$cfgBookmark = array(
'user' => $GLOBALS['cfg']['Server']['user'],
'db' => $GLOBALS['cfg']['Server']['pmadb'],
'table' => $GLOBALS['cfg']['Server']['bookmarktable'],
);
} else {
$cfgBookmark = false;
}
return $cfgBookmark;
} // end of the 'PMA_Bookmark_getParams()' function
/**
* Gets the list of bookmarks defined for the current database
*
* @global resource the controluser db connection handle
*
* @param string the current database name
*
* @return array the bookmarks list (key as index, label as value)
*
* @access public
*/
function PMA_Bookmark_getList($db)
{
global $controllink;
$cfgBookmark = PMA_Bookmark_getParams();
if (empty($cfgBookmark)) {
return array();
}
$query = 'SELECT label, id FROM '. PMA_backquote($cfgBookmark['db']) . '.' . PMA_backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA_sqlAddSlashes($db) . '\''
. ' AND user = \'' . PMA_sqlAddSlashes($cfgBookmark['user']) . '\''
. ' ORDER BY label';
$per_user = PMA_DBI_fetch_result($query, 'id', 'label', $controllink, PMA_DBI_QUERY_STORE);
$query = 'SELECT label, id FROM '. PMA_backquote($cfgBookmark['db']) . '.' . PMA_backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA_sqlAddSlashes($db) . '\''
. ' AND user = \'\''
. ' ORDER BY label';
$global = PMA_DBI_fetch_result($query, 'id', 'label', $controllink, PMA_DBI_QUERY_STORE);
foreach ($global as $key => $val) {
$global[$key] = $val . ' (' . __('shared') . ')';
}
$ret = $global + $per_user;
asort($ret);
return $ret;
} // end of the 'PMA_Bookmark_getList()' function
/**
* Gets the sql command from a bookmark
*
* @global resource the controluser db connection handle
*
* @param string the current database name
* @param mixed the id of the bookmark to get
* @param string which field to look up the $id
* @param boolean true: get all bookmarks regardless of the owning user
* @param boolean whether to ignore bookmarks with no user
*
* @return string the sql query
*
* @access public
*/
function PMA_Bookmark_get($db, $id, $id_field = 'id', $action_bookmark_all = false, $exact_user_match = false)
{
global $controllink;
$cfgBookmark = PMA_Bookmark_getParams();
if (empty($cfgBookmark)) {
return '';
}
$query = 'SELECT query FROM ' . PMA_backquote($cfgBookmark['db']) . '.' . PMA_backquote($cfgBookmark['table'])
. ' WHERE dbase = \'' . PMA_sqlAddSlashes($db) . '\'';
if (!$action_bookmark_all) {
$query .= ' AND (user = \'' . PMA_sqlAddSlashes($cfgBookmark['user']) . '\'';
if (!$exact_user_match) {
$query .= ' OR user = \'\'';
}
$query .= ')';
}
$query .= ' AND ' . PMA_backquote($id_field) . ' = ' . $id;
return PMA_DBI_fetch_value($query, 0, 0, $controllink);
} // end of the 'PMA_Bookmark_get()' function
/**
* Adds a bookmark
*
* @global resource the controluser db connection handle
*
* @param array the properties of the bookmark to add; here,
* $fields['query'] is urlencoded
* @param boolean whether to make the bookmark available for all users
*
* @return boolean whether the INSERT succeeds or not
*
* @access public
*/
function PMA_Bookmark_save($fields, $all_users = false)
{
global $controllink;
$cfgBookmark = PMA_Bookmark_getParams();
if (empty($cfgBookmark)) {
return false;
}
$query = 'INSERT INTO ' . PMA_backquote($cfgBookmark['db']) . '.' . PMA_backquote($cfgBookmark['table'])
. ' (id, dbase, user, query, label) VALUES (NULL, \'' . PMA_sqlAddSlashes($fields['dbase']) . '\', \'' . ($all_users ? '' : PMA_sqlAddSlashes($fields['user'])) . '\', \'' . PMA_sqlAddSlashes(urldecode($fields['query'])) . '\', \'' . PMA_sqlAddSlashes($fields['label']) . '\')';
return PMA_DBI_query($query, $controllink);
} // end of the 'PMA_Bookmark_save()' function
/**
* Deletes a bookmark
*
* @global resource the controluser db connection handle
*
* @param string the current database name
* @param integer the id of the bookmark to get
*
* @access public
*/
function PMA_Bookmark_delete($db, $id)
{
global $controllink;
$cfgBookmark = PMA_Bookmark_getParams();
if (empty($cfgBookmark)) {
return false;
}
$query = 'DELETE FROM ' . PMA_backquote($cfgBookmark['db']) . '.' . PMA_backquote($cfgBookmark['table'])
. ' WHERE (user = \'' . PMA_sqlAddSlashes($cfgBookmark['user']) . '\''
. ' OR user = \'\')'
. ' AND id = ' . $id;
return PMA_DBI_try_query($query, $controllink);
} // end of the 'PMA_Bookmark_delete()' function
/**
* Bookmark Support
*/
$GLOBALS['cfg']['Bookmark'] = PMA_Bookmark_getParams();
?>

View File

@ -0,0 +1,159 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Prepares the $column_order array
*
* @return array
*/
function PMA_getColumnOrder()
{
$column_order['DEFAULT_COLLATION_NAME'] = array(
'disp_name' => __('Collation'),
'description_function' => 'PMA_getCollationDescr',
'format' => 'string',
'footer' => PMA_getServerCollation(),
);
$column_order['SCHEMA_TABLES'] = array(
'disp_name' => __('Tables'),
'format' => 'number',
'footer' => 0,
);
$column_order['SCHEMA_TABLE_ROWS'] = array(
'disp_name' => __('Rows'),
'format' => 'number',
'footer' => 0,
);
$column_order['SCHEMA_DATA_LENGTH'] = array(
'disp_name' => __('Data'),
'format' => 'byte',
'footer' => 0,
);
$column_order['SCHEMA_INDEX_LENGTH'] = array(
'disp_name' => __('Indexes'),
'format' => 'byte',
'footer' => 0,
);
$column_order['SCHEMA_LENGTH'] = array(
'disp_name' => __('Total'),
'format' => 'byte',
'footer' => 0,
);
$column_order['SCHEMA_DATA_FREE'] = array(
'disp_name' => __('Overhead'),
'format' => 'byte',
'footer' => 0,
);
return $column_order;
}
/*
* Builds the HTML td elements for one database to display in the list
* of databases from server_databases.php (which can be modified by
* db_create.php)
*
* @param array $current
* @param boolean $is_superuser
* @param string $checkall
* @param string $url_query
* @param array $column_order
* @param array $replication_types
* @param array $replication_info
*
* @return array $column_order, $out
*/
function PMA_buildHtmlForDb($current, $is_superuser, $checkall, $url_query, $column_order, $replication_types, $replication_info)
{
$out = '';
if ($is_superuser || $GLOBALS['cfg']['AllowUserDropDatabase']) {
$out .= '<td class="tool">';
$out .= '<input type="checkbox" name="selected_dbs[]" title="' . htmlspecialchars($current['SCHEMA_NAME']) . '" value="' . htmlspecialchars($current['SCHEMA_NAME']) . '" ';
if (!PMA_is_system_schema($current['SCHEMA_NAME'], true)) {
$out .= (empty($checkall) ? '' : 'checked="checked" ') . '/>';
} else {
$out .= ' disabled="disabled" />';
}
$out .= '</td>';
}
$out .= '<td class="name">'
. ' <a onclick="'
. 'if (window.parent.openDb &amp;&amp; window.parent.openDb(\'' . PMA_jsFormat($current['SCHEMA_NAME'], false) . '\')) return false;'
. '" href="index.php?' . $url_query . '&amp;db='
. urlencode($current['SCHEMA_NAME']) . '" title="'
. sprintf(__('Jump to database'), htmlspecialchars($current['SCHEMA_NAME']))
. '" target="_parent">'
. ' ' . htmlspecialchars($current['SCHEMA_NAME'])
. '</a>'
. '</td>';
foreach ($column_order as $stat_name => $stat) {
if (array_key_exists($stat_name, $current)) {
if (is_numeric($stat['footer'])) {
$column_order[$stat_name]['footer'] += $current[$stat_name];
}
if ($stat['format'] === 'byte') {
list($value, $unit) = PMA_formatByteDown($current[$stat_name], 3, 1);
} elseif ($stat['format'] === 'number') {
$value = PMA_formatNumber($current[$stat_name], 0);
} else {
$value = htmlentities($current[$stat_name], 0);
}
$out .= '<td class="value">';
if (isset($stat['description_function'])) {
$out .= '<dfn title="' . $stat['description_function']($current[$stat_name]) . '">';
}
$out .= $value;
if (isset($stat['description_function'])) {
$out .= '</dfn>';
}
$out .= '</td>';
if ($stat['format'] === 'byte') {
$out .= '<td class="unit">' . $unit . '</td>';
}
}
}
foreach ($replication_types as $type) {
if ($replication_info[$type]['status']) {
$out .= '<td class="tool" style="text-align: center;">';
if (strlen(array_search($current["SCHEMA_NAME"], $replication_info[$type]['Ignore_DB'])) > 0) {
$out .= PMA_getIcon('s_cancel.png', __('Not replicated'));
} else {
$key = array_search($current["SCHEMA_NAME"], $replication_info[$type]['Do_DB']);
if (strlen($key) > 0 || ($replication_info[$type]['Do_DB'][0] == "" && count($replication_info[$type]['Do_DB']) == 1)) {
// if ($key != null) did not work for index "0"
$out .= PMA_getIcon('s_success.png', __('Replicated'));
}
}
$out .= '</td>';
}
}
if ($is_superuser && !PMA_DRIZZLE) {
$out .= '<td class="tool">'
. '<a onclick="'
. 'if (window.parent.setDb) window.parent.setDb(\'' . PMA_jsFormat($current['SCHEMA_NAME']) . '\');'
. '" href="./server_privileges.php?' . $url_query
. '&amp;checkprivs=' . urlencode($current['SCHEMA_NAME'])
. '" title="' . sprintf(__('Check privileges for database &quot;%s&quot;.'), htmlspecialchars($current['SCHEMA_NAME']))
. '">'
. ' '
. PMA_getIcon('s_rights.png', __('Check Privileges'))
. '</a></td>';
}
return array($column_order, $out);
}
?>

View File

@ -0,0 +1,87 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Charset conversion functions.
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
define('PMA_CHARSET_NONE', 0);
define('PMA_CHARSET_ICONV', 1);
define('PMA_CHARSET_RECODE', 2);
define('PMA_CHARSET_ICONV_AIX', 3);
// Finally detect which function we will use:
if ($cfg['RecodingEngine'] == 'iconv') {
if (@function_exists('iconv')) {
if ((@stristr(PHP_OS, 'AIX')) && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) {
$PMA_recoding_engine = PMA_CHARSET_ICONV_AIX;
} else {
$PMA_recoding_engine = PMA_CHARSET_ICONV;
}
} else {
$PMA_recoding_engine = PMA_CHARSET_NONE;
PMA_warnMissingExtension('iconv');
}
} elseif ($cfg['RecodingEngine'] == 'recode') {
if (@function_exists('recode_string')) {
$PMA_recoding_engine = PMA_CHARSET_RECODE;
} else {
$PMA_recoding_engine = PMA_CHARSET_NONE;
PMA_warnMissingExtension('recode');
}
} elseif ($cfg['RecodingEngine'] == 'auto') {
if (@function_exists('iconv')) {
if ((@stristr(PHP_OS, 'AIX')) && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) {
$PMA_recoding_engine = PMA_CHARSET_ICONV_AIX;
} else {
$PMA_recoding_engine = PMA_CHARSET_ICONV;
}
} elseif (@function_exists('recode_string')) {
$PMA_recoding_engine = PMA_CHARSET_RECODE;
} else {
$PMA_recoding_engine = PMA_CHARSET_NONE;
}
} else {
$PMA_recoding_engine = PMA_CHARSET_NONE;
}
/* Load AIX iconv wrapper if needed */
if ($PMA_recoding_engine == PMA_CHARSET_ICONV_AIX) {
include_once './libraries/iconv_wrapper.lib.php';
}
/**
* Converts encoding of text according to parameters with detected
* conversion function.
*
* @param string source charset
* @param string target charset
* @param string what to convert
*
* @return string converted text
*
* @access public
*
*/
function PMA_convert_string($src_charset, $dest_charset, $what)
{
if ($src_charset == $dest_charset) {
return $what;
}
switch ($GLOBALS['PMA_recoding_engine']) {
case PMA_CHARSET_RECODE:
return recode_string($src_charset . '..' . $dest_charset, $what);
case PMA_CHARSET_ICONV:
return iconv($src_charset, $dest_charset . $GLOBALS['cfg']['IconvExtraParams'], $what);
case PMA_CHARSET_ICONV_AIX:
return PMA_aix_iconv_wrapper($src_charset, $dest_charset . $GLOBALS['cfg']['IconvExtraParams'], $what);
default:
return $what;
}
} // end of the "PMA_convert_string()" function
?>

View File

@ -0,0 +1,151 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Get user's global privileges and some db-specific privileges
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
$GLOBALS['is_superuser'] = PMA_isSuperuser();
/**
* sets privilege information extracted from SHOW GRANTS result
*
* Detection for some CREATE privilege.
*
* Since MySQL 4.1.2, we can easily detect current user's grants using $userlink
* (no control user needed) and we don't have to try any other method for
* detection
*
* @todo fix to get really all privileges, not only explicitly defined for this user
* from MySQL manual: (http://dev.mysql.com/doc/refman/5.0/en/show-grants.html)
* SHOW GRANTS displays only the privileges granted explicitly to the named
* account. Other privileges might be available to the account, but they are not
* displayed. For example, if an anonymous account exists, the named account
* might be able to use its privileges, but SHOW GRANTS will not display them.
*
*/
function PMA_analyseShowGrant()
{
if (PMA_cacheExists('is_create_db_priv', true)) {
$GLOBALS['is_create_db_priv'] = PMA_cacheGet('is_create_db_priv', true);
$GLOBALS['is_process_priv'] = PMA_cacheGet('is_process_priv', true);
$GLOBALS['is_reload_priv'] = PMA_cacheGet('is_reload_priv', true);
$GLOBALS['db_to_create'] = PMA_cacheGet('db_to_create', true);
$GLOBALS['dbs_where_create_table_allowed']
= PMA_cacheGet('dbs_where_create_table_allowed', true);
return;
}
// defaults
$GLOBALS['is_create_db_priv'] = false;
$GLOBALS['is_process_priv'] = true;
$GLOBALS['is_reload_priv'] = false;
$GLOBALS['db_to_create'] = '';
$GLOBALS['dbs_where_create_table_allowed'] = array();
$rs_usr = PMA_DBI_try_query('SHOW GRANTS');
if (! $rs_usr) {
return;
}
$re0 = '(^|(\\\\\\\\)+|[^\\\\])'; // non-escaped wildcards
$re1 = '(^|[^\\\\])(\\\)+'; // escaped wildcards
while ($row = PMA_DBI_fetch_row($rs_usr)) {
// extract db from GRANT ... ON *.* or GRANT ... ON db.*
$db_name_offset = strpos($row[0], ' ON ') + 4;
$show_grants_dbname = substr($row[0],
$db_name_offset,
strpos($row[0], '.', $db_name_offset) - $db_name_offset);
$show_grants_dbname = PMA_unQuote($show_grants_dbname, '`');
$show_grants_str = substr($row[0], 6, (strpos($row[0], ' ON ') - 6));
if ($show_grants_str == 'RELOAD') {
$GLOBALS['is_reload_priv'] = true;
}
/**
* @todo if we find CREATE VIEW but not CREATE, do not offer
* the create database dialog box
*/
if ($show_grants_str == 'ALL'
|| $show_grants_str == 'ALL PRIVILEGES'
|| $show_grants_str == 'CREATE'
|| strpos($show_grants_str, 'CREATE,') !== false) {
if ($show_grants_dbname == '*') {
// a global CREATE privilege
$GLOBALS['is_create_db_priv'] = true;
$GLOBALS['is_reload_priv'] = true;
$GLOBALS['db_to_create'] = '';
$GLOBALS['dbs_where_create_table_allowed'][] = '*';
// @todo we should not break here, cause GRANT ALL *.*
// could be revoked by a later rule like GRANT SELECT ON db.*
break;
} else {
// this array may contain wildcards
$GLOBALS['dbs_where_create_table_allowed'][] = $show_grants_dbname;
$dbname_to_test = PMA_backquote($show_grants_dbname);
if ($GLOBALS['is_create_db_priv']) {
// no need for any more tests if we already know this
continue;
}
if ((preg_match('/' . $re0 . '%|_/', $show_grants_dbname)
&& ! preg_match('/\\\\%|\\\\_/', $show_grants_dbname))
// does this db exist?
|| (! PMA_DBI_try_query('USE ' . preg_replace('/' . $re1 . '(%|_)/', '\\1\\3', $dbname_to_test))
&& substr(PMA_DBI_getError(), 1, 4) != 1044)
) {
if ($GLOBALS['cfg']['SuggestDBName']) {
/**
* Do not handle the underscore wildcard
* (this case must be rare anyway)
*/
$GLOBALS['db_to_create'] = preg_replace('/' . $re0 . '%/', '\\1...', $show_grants_dbname);
$GLOBALS['db_to_create'] = preg_replace('/' . $re1 . '(%|_)/', '\\1\\3', $GLOBALS['db_to_create']);
}
$GLOBALS['is_create_db_priv'] = true;
/**
* @todo collect $GLOBALS['db_to_create'] into an array, to display a
* drop-down in the "Create database" dialog
*/
// we don't break, we want all possible databases
//break;
} // end if
} // end elseif
} // end if
} // end while
PMA_DBI_free_result($rs_usr);
// must also PMA_cacheUnset() them in libraries/auth/cookie.auth.lib.php
PMA_cacheSet('is_create_db_priv', $GLOBALS['is_create_db_priv'], true);
PMA_cacheSet('is_process_priv', $GLOBALS['is_process_priv'], true);
PMA_cacheSet('is_reload_priv', $GLOBALS['is_reload_priv'], true);
PMA_cacheSet('db_to_create', $GLOBALS['db_to_create'], true);
PMA_cacheSet('dbs_where_create_table_allowed', $GLOBALS['dbs_where_create_table_allowed'], true);
} // end function
if (!PMA_DRIZZLE) {
PMA_analyseShowGrant();
} else {
// todo: for simple_user_policy only database with user's login can be created (unless logged in as root)
$GLOBALS['is_create_db_priv'] = $GLOBALS['is_superuser'];
$GLOBALS['is_process_priv'] = false;
$GLOBALS['is_reload_priv'] = false;
$GLOBALS['db_to_create'] = '';
$GLOBALS['dbs_where_create_table_allowed'] = array('*');
}
?>

View File

@ -0,0 +1,44 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions for cleanup of user input.
*
* @package PhpMyAdmin
*/
/**
* Removes all variables from request except whitelisted ones.
*
* @param string list of variables to allow
* @return nothing
* @access public
*/
function PMA_remove_request_vars(&$whitelist)
{
// do not check only $_REQUEST because it could have been overwritten
// and use type casting because the variables could have become
// strings
$keys = array_keys(array_merge((array)$_REQUEST, (array)$_GET, (array)$_POST, (array)$_COOKIE));
foreach ($keys as $key) {
if (! in_array($key, $whitelist)) {
unset($_REQUEST[$key], $_GET[$key], $_POST[$key], $GLOBALS[$key]);
} else {
// allowed stuff could be compromised so escape it
// we require it to be a string
if (isset($_REQUEST[$key]) && ! is_string($_REQUEST[$key])) {
unset($_REQUEST[$key]);
}
if (isset($_POST[$key]) && ! is_string($_POST[$key])) {
unset($_POST[$key]);
}
if (isset($_COOKIE[$key]) && ! is_string($_COOKIE[$key])) {
unset($_COOKIE[$key]);
}
if (isset($_GET[$key]) && ! is_string($_GET[$key])) {
unset($_GET[$key]);
}
}
}
}
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,193 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database with allowed values for configuration stored in the $cfg array,
* used by setup script and user preferences to generate forms.
*
* @package PhpMyAdmin
*/
if (!defined('PHPMYADMIN')) {
exit;
}
/**
* Value meaning:
* o array - select field, array contains allowed values
* o string - type override
*
* Use normal array, paths won't be expanded
*/
$cfg_db = array();
$cfg_db['Servers'] = array(1 => array(
'port' => 'integer',
'connect_type' => array('tcp', 'socket'),
'extension' => array('mysql', 'mysqli'),
'auth_type' => array('config', 'http', 'signon', 'cookie'),
'AllowDeny' => array(
'order' => array('', 'deny,allow', 'allow,deny', 'explicit')),
'only_db' => 'array'));
$cfg_db['RecodingEngine'] = array('auto', 'iconv', 'recode', 'none');
$cfg_db['OBGzip'] = array('auto', true, false);
$cfg_db['MemoryLimit'] = 'short_string';
$cfg_db['ShowTooltipAliasTB'] = array('nested', true, false);
$cfg_db['DisplayDatabasesList'] = array('auto', true, false);
$cfg_db['LeftLogoLinkWindow'] = array('main', 'new');
$cfg_db['LeftDefaultTabTable'] = array(
'tbl_structure.php', // fields list
'tbl_sql.php', // SQL form
'tbl_select.php', // search page
'tbl_change.php', // insert row page
'sql.php'); // browse page
$cfg_db['LeftFrameDBSeparator'] = 'short_string';
$cfg_db['LeftFrameTableSeparator'] = 'short_string';
$cfg_db['NavigationBarIconic'] = array(true => __('Yes'), false => __('No'), 'both' => __('Both'));
$cfg_db['Order'] = array('ASC', 'DESC', 'SMART');
$cfg_db['RowActionLinks'] = array('none' => __('Nowhere'), 'left' => __('Left'), 'right' => __('Right'), 'both' => __('Both'));
$cfg_db['ProtectBinary'] = array(false, 'blob', 'all');
$cfg_db['DefaultDisplay'] = array('horizontal', 'vertical', 'horizontalflipped');
$cfg_db['CharEditing'] = array('input', 'textarea');
$cfg_db['PropertiesIconic'] = array(true => __('Yes'), false => __('No'), 'both' => __('Both'));
$cfg_db['DefaultTabServer'] = array(
'main.php', // the welcome page (recommended for multiuser setups)
'server_databases.php', // list of databases
'server_status.php', // runtime information
'server_variables.php', // MySQL server variables
'server_privileges.php', // user management
'server_processlist.php'); // process list
$cfg_db['DefaultTabDatabase'] = array(
'db_structure.php', // tables list
'db_sql.php', // SQL form
'db_search.php', // search query
'db_operations.php'); // operations on database
$cfg_db['DefaultTabTable'] = array(
'tbl_structure.php', // fields list
'tbl_sql.php', // SQL form
'tbl_select.php', // search page
'tbl_change.php', // insert row page
'sql.php'); // browse page
$cfg_db['QueryWindowDefTab'] = array(
'sql', // SQL
'files', // Import files
'history', // SQL history
'full'); // All (SQL and SQL history)
$cfg_db['InitialSlidersState'] = array(
'open' => __('Open'),
'closed' => __('Closed'),
'disabled' => __('Disabled'));
$cfg_db['Import']['format'] = array(
'csv', // CSV
'docsql', // DocSQL
'ldi', // CSV using LOAD DATA
'sql'); // SQL
$cfg_db['Import']['charset'] = array_merge(array(''), $GLOBALS['cfg']['AvailableCharsets']);
$cfg_db['Import']['sql_compatibility'] = $cfg_db['Export']['sql_compatibility'] = array(
'NONE', 'ANSI', 'DB2', 'MAXDB', 'MYSQL323', 'MYSQL40', 'MSSQL', 'ORACLE',
// removed; in MySQL 5.0.33, this produces exports that
// can't be read by POSTGRESQL (see our bug #1596328)
//'POSTGRESQL',
'TRADITIONAL');
$cfg_db['Import']['csv_terminated'] = 'short_string';
$cfg_db['Import']['csv_enclosed'] = 'short_string';
$cfg_db['Import']['csv_escaped'] = 'short_string';
$cfg_db['Import']['ldi_terminated'] = 'short_string';
$cfg_db['Import']['ldi_enclosed'] = 'short_string';
$cfg_db['Import']['ldi_escaped'] = 'short_string';
$cfg_db['Import']['ldi_local_option'] = array('auto', true, false);
$cfg_db['Export']['_sod_select'] = array(
'structure' => __('structure'),
'data' => __('data'),
'structure_and_data' => __('structure and data'));
$cfg_db['Export']['method'] = array(
'quick' => __('Quick - display only the minimal options to configure'),
'custom' => __('Custom - display all possible options to configure'),
'custom-no-form' => __('Custom - like above, but without the quick/custom choice'));
$cfg_db['Export']['format'] = array('codegen', 'csv', 'excel', 'htmlexcel',
'htmlword', 'latex', 'ods', 'odt', 'pdf', 'sql', 'texytext', 'xls', 'xml',
'yaml');
$cfg_db['Export']['compression'] = array('none', 'zip', 'gzip', 'bzip2');
$cfg_db['Export']['charset'] = array_merge(array(''), $GLOBALS['cfg']['AvailableCharsets']);
$cfg_db['Export']['codegen_format'] = array('#', 'NHibernate C# DO', 'NHibernate XML');
$cfg_db['Export']['csv_separator'] = 'short_string';
$cfg_db['Export']['csv_terminated'] = 'short_string';
$cfg_db['Export']['csv_enclosed'] = 'short_string';
$cfg_db['Export']['csv_escaped'] = 'short_string';
$cfg_db['Export']['csv_null'] = 'short_string';
$cfg_db['Export']['excel_null'] = 'short_string';
$cfg_db['Export']['excel_edition'] = array('win' => 'Windows',
'mac_excel2003' => 'Excel 2003 / Macintosh', 'mac_excel2008' => 'Excel 2008 / Macintosh');
$cfg_db['Export']['sql_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['sql_type'] = array('INSERT', 'UPDATE', 'REPLACE');
$cfg_db['Export']['sql_insert_syntax'] = array(
'complete' => __('complete inserts'),
'extended' => __('extended inserts'),
'both' => __('both of the above'),
'none' => __('neither of the above'));
$cfg_db['Export']['xls_null'] = 'short_string';
$cfg_db['Export']['xlsx_null'] = 'short_string';
$cfg_db['Export']['htmlword_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['htmlword_null'] = 'short_string';
$cfg_db['Export']['ods_null'] = 'short_string';
$cfg_db['Export']['odt_null'] = 'short_string';
$cfg_db['Export']['odt_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['texytext_structure_or_data'] = $cfg_db['Export']['_sod_select'];
$cfg_db['Export']['texytext_null'] = 'short_string';
/**
* Default values overrides
* Use only full paths
*/
$cfg_db['_overrides'] = array();
$cfg_db['_overrides']['Servers/1/extension'] = extension_loaded('mysqli')
? 'mysqli' : 'mysql';
/**
* Basic validator assignments (functions from libraries/config/validate.lib.php and 'validators'
* object in js/config.js)
* Use only full paths and form ids
*/
$cfg_db['_validators'] = array(
'CharTextareaCols' => 'validate_positive_number',
'CharTextareaRows' => 'validate_positive_number',
'ExecTimeLimit' => 'validate_non_negative_number',
'Export/sql_max_query_size' => 'validate_positive_number',
'ForeignKeyMaxLimit' => 'validate_positive_number',
'Import/csv_enclosed' => array(array('validate_by_regex', '/^.?$/')),
'Import/csv_escaped' => array(array('validate_by_regex', '/^.$/')),
'Import/csv_terminated' => array(array('validate_by_regex', '/^.$/')),
'Import/ldi_enclosed' => array(array('validate_by_regex', '/^.?$/')),
'Import/ldi_escaped' => array(array('validate_by_regex', '/^.$/')),
'Import/ldi_terminated' => array(array('validate_by_regex', '/^.$/')),
'Import/skip_queries' => 'validate_non_negative_number',
'InsertRows' => 'validate_positive_number',
'LeftFrameTableLevel' => 'validate_positive_number',
'LeftRecentTable' => 'validate_non_negative_number',
'LimitChars' => 'validate_positive_number',
'LoginCookieValidity' => 'validate_positive_number',
'LoginCookieStore' => 'validate_non_negative_number',
'MaxDbList' => 'validate_positive_number',
'MaxCharactersInDisplayedSQL' => 'validate_positive_number',
'MaxRows' => 'validate_positive_number',
'MaxTableList' => 'validate_positive_number',
'MemoryLimit' => array(array('validate_by_regex', '/^\d+(?:[kmg])?$/i')),
'QueryHistoryMax' => 'validate_positive_number',
'QueryWindowWidth' => 'validate_positive_number',
'QueryWindowHeight' => 'validate_positive_number',
'RepeatCells' => 'validate_non_negative_number',
'Server' => 'validate_server',
'Server_pmadb' => 'validate_pmadb',
'Servers/1/port' => 'validate_port_number',
'Servers/1/hide_db' => 'validate_regex',
'TextareaCols' => 'validate_positive_number',
'TextareaRows' => 'validate_positive_number',
'TrustedProxies' => 'validate_trusted_proxies');
/**
* Additional validators used for user preferences
*/
$cfg_db['_userValidators'] = array(
'MaxDbList' => array(array('validate_upper_bound', 'value:MaxDbList')),
'MaxTableList' => array(array('validate_upper_bound', 'value:MaxTableList')),
'QueryHistoryMax' => array(array('validate_upper_bound', 'value:QueryHistoryMax')),);
?>

View File

@ -0,0 +1,503 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Config file management
*
* @package PhpMyAdmin
*/
/**
* Config file management class.
* Stores its data in $_SESSION
*
* @package phpMyAdmin
*/
class ConfigFile
{
/**
* Stores default PMA config from config.default.php
* @var array
*/
private $cfg;
/**
* Stores original PMA_Config object, not modified by user preferences
* @var PMA_Config
*/
private $orgCfgObject;
/**
* Stores allowed values for non-standard fields
* @var array
*/
private $cfgDb;
/**
* Keys which will be always written to config file
* @var array
*/
private $persistKeys = array();
/**
* Changes keys while updating config in {@link updateWithGlobalConfig()} or reading
* by {@link getConfig()} or {@link getConfigArray()}
* @var array
*/
private $cfgUpdateReadMapping = array();
/**
* Key filter for {@link set()}
* @var array|null
*/
private $setFilter;
/**
* Instance id (key in $_SESSION array, separate for each server - ConfigFile{server id})
* @var string
*/
private $id;
/**
* Result for {@link _flattenArray()}
* @var array
*/
private $_flattenArrayResult;
/**
* ConfigFile instance
* @var ConfigFile
*/
private static $_instance;
/**
* Private constructor, use {@link getInstance()}
*
*/
private function __construct()
{
// load default config values
$cfg = &$this->cfg;
include './libraries/config.default.php';
$cfg['fontsize'] = '82%';
// create PMA_Config to read config.inc.php values
$this->orgCfgObject = new PMA_Config(CONFIG_FILE);
// load additional config information
$cfg_db = &$this->cfgDb;
include './libraries/config.values.php';
// apply default values overrides
if (count($cfg_db['_overrides'])) {
foreach ($cfg_db['_overrides'] as $path => $value) {
PMA_array_write($path, $cfg, $value);
}
}
$this->id = 'ConfigFile' . $GLOBALS['server'];
if (!isset($_SESSION[$this->id])) {
$_SESSION[$this->id] = array();
}
}
/**
* Returns class instance
*
* @return ConfigFile
*/
public static function getInstance()
{
if (is_null(self::$_instance)) {
self::$_instance = new ConfigFile();
}
return self::$_instance;
}
/**
* Returns PMA_Config without user preferences applied
*
* @return PMA_Config
*/
public function getOrgConfigObj()
{
return $this->orgCfgObject;
}
/**
* Sets names of config options which will be placed in config file even if they are set
* to their default values (use only full paths)
*
* @param array $keys
*/
public function setPersistKeys($keys)
{
// checking key presence is much faster than searching so move values to keys
$this->persistKeys = array_flip($keys);
}
/**
* Returns flipped array set by {@link setPersistKeys()}
*
* @return array
*/
public function getPersistKeysMap()
{
return $this->persistKeys;
}
/**
* By default ConfigFile allows setting of all configuration keys, use this method
* to set up a filter on {@link set()} method
*
* @param array|null $keys array of allowed keys or null to remove filter
*/
public function setAllowedKeys($keys)
{
if ($keys === null) {
$this->setFilter = null;
return;
}
// checking key presence is much faster than searching so move values to keys
$this->setFilter = array_flip($keys);
}
/**
* Sets path mapping for updating config in {@link updateWithGlobalConfig()} or reading
* by {@link getConfig()} or {@link getConfigArray()}
* @var array
*/
public function setCfgUpdateReadMapping(array $mapping)
{
$this->cfgUpdateReadMapping = $mapping;
}
/**
* Resets configuration data
*/
public function resetConfigData()
{
$_SESSION[$this->id] = array();
}
/**
* Sets configuration data (overrides old data)
*
* @param array $cfg
*/
public function setConfigData(array $cfg)
{
$_SESSION[$this->id] = $cfg;
}
/**
* Sets config value
*
* @param string $path
* @param mixed $value
* @param string $canonical_path
*/
public function set($path, $value, $canonical_path = null)
{
if ($canonical_path === null) {
$canonical_path = $this->getCanonicalPath($path);
}
// apply key whitelist
if ($this->setFilter !== null && !isset($this->setFilter[$canonical_path])) {
return;
}
// remove if the path isn't protected and it's empty or has a default value
if (!isset($this->persistKeys[$canonical_path])) {
$default_value = $this->getDefault($canonical_path);
// we need oryginal config values not overwritten by user preferences
// to allow for overwriting options set in config.inc.php with default values
$instance_default_value = PMA_array_read($canonical_path, $this->orgCfgObject->settings);
if (($value === $default_value && (defined('PMA_SETUP') || $instance_default_value === $default_value))
|| (empty($value) && empty($default_value) && (defined('PMA_SETUP') || empty($current_global)))) {
PMA_array_remove($path, $_SESSION[$this->id]);
return;
}
}
PMA_array_write($path, $_SESSION[$this->id], $value);
}
/**
* Flattens multidimensional array, changes indices to paths (eg. 'key/subkey').
* Used as array_walk() callback.
*
* @param mixed $value
* @param mixed $key
* @param mixed $prefix
*/
private function _flattenArray($value, $key, $prefix)
{
// no recursion for numeric arrays
if (is_array($value) && !isset($value[0])) {
$prefix .= $key . '/';
array_walk($value, array($this, '_flattenArray'), $prefix);
} else {
$this->_flattenArrayResult[$prefix . $key] = $value;
}
}
/**
* Returns default config in a flattened array
*
* @return array
*/
public function getFlatDefaultConfig()
{
$this->_flattenArrayResult = array();
array_walk($this->cfg, array($this, '_flattenArray'), '');
$flat_cfg = $this->_flattenArrayResult;
$this->_flattenArrayResult = null;
return $flat_cfg;
}
/**
* Updates config with values read from given array
* (config will contain differences to defaults from config.defaults.php).
*
* @param array $cfg
*/
public function updateWithGlobalConfig(array $cfg)
{
// load config array and flatten it
$this->_flattenArrayResult = array();
array_walk($cfg, array($this, '_flattenArray'), '');
$flat_cfg = $this->_flattenArrayResult;
$this->_flattenArrayResult = null;
// save values
// map for translating a few user preferences paths, should be complemented
// by code reading from generated config to perform inverse mapping
foreach ($flat_cfg as $path => $value) {
if (isset($this->cfgUpdateReadMapping[$path])) {
$path = $this->cfgUpdateReadMapping[$path];
}
$this->set($path, $value, $path);
}
}
/**
* Returns config value or $default if it's not set
*
* @param string $path
* @param mixed $default
* @return mixed
*/
public function get($path, $default = null)
{
return PMA_array_read($path, $_SESSION[$this->id], $default);
}
/**
* Returns default config value or $default it it's not set ie. it doesn't
* exist in config.default.php ($cfg) and config.values.php
* ($_cfg_db['_overrides'])
*
* @param string $canonical_path
* @param mixed $default
* @return mixed
*/
public function getDefault($canonical_path, $default = null)
{
return PMA_array_read($canonical_path, $this->cfg, $default);
}
/**
* Returns config value, if it's not set uses the default one; returns
* $default if the path isn't set and doesn't contain a default value
*
* @param string $path
* @param mixed $default
* @return mixed
*/
public function getValue($path, $default = null)
{
$v = PMA_array_read($path, $_SESSION[$this->id], null);
if ($v !== null) {
return $v;
}
$path = $this->getCanonicalPath($path);
return $this->getDefault($path, $default);
}
/**
* Returns canonical path
*
* @param string $path
* @return string
*/
public function getCanonicalPath($path) {
return preg_replace('#^Servers/([\d]+)/#', 'Servers/1/', $path);
}
/**
* Returns config database entry for $path ($cfg_db in config_info.php)
*
* @param string $path
* @param mixed $default
* @return mixed
*/
public function getDbEntry($path, $default = null)
{
return PMA_array_read($path, $this->cfgDb, $default);
}
/**
* Returns server count
*
* @return int
*/
public function getServerCount()
{
return isset($_SESSION[$this->id]['Servers'])
? count($_SESSION[$this->id]['Servers'])
: 0;
}
/**
* Returns server list
*
* @return array|null
*/
public function getServers()
{
return isset($_SESSION[$this->id]['Servers'])
? $_SESSION[$this->id]['Servers']
: null;
}
/**
* Returns DSN of given server
*
* @param integer $server
* @return string
*/
function getServerDSN($server)
{
if (!isset($_SESSION[$this->id]['Servers'][$server])) {
return '';
}
$path = 'Servers/' . $server;
$dsn = $this->getValue("$path/extension") . '://';
if ($this->getValue("$path/auth_type") == 'config') {
$dsn .= $this->getValue("$path/user");
if (!$this->getValue("$path/nopassword")) {
$dsn .= ':***';
}
$dsn .= '@';
}
if ($this->getValue("$path/connect_type") == 'tcp') {
$dsn .= $this->getValue("$path/host");
$port = $this->getValue("$path/port");
if ($port) {
$dsn .= ':' . $port;
}
} else {
$dsn .= $this->getValue("$path/socket");
}
return $dsn;
}
/**
* Returns server name
*
* @param int $id
* @return string
*/
public function getServerName($id)
{
if (!isset($_SESSION[$this->id]['Servers'][$id])) {
return '';
}
$verbose = $this->get("Servers/$id/verbose");
if (!empty($verbose)) {
return $verbose;
}
$host = $this->get("Servers/$id/host");
return empty($host) ? 'localhost' : $host;
}
/**
* Removes server
*
* @param int $server
*/
public function removeServer($server)
{
if (!isset($_SESSION[$this->id]['Servers'][$server])) {
return;
}
$last_server = $this->getServerCount();
for ($i = $server; $i < $last_server; $i++) {
$_SESSION[$this->id]['Servers'][$i] = $_SESSION[$this->id]['Servers'][$i+1];
}
unset($_SESSION[$this->id]['Servers'][$last_server]);
if (isset($_SESSION[$this->id]['ServerDefault'])
&& $_SESSION[$this->id]['ServerDefault'] >= 0) {
unset($_SESSION[$this->id]['ServerDefault']);
}
}
/**
* Returns config file path, relative to phpMyAdmin's root path
*
* @return string
*/
public function getFilePath()
{
// Load paths
if (!defined('SETUP_CONFIG_FILE')) {
include_once './libraries/vendor_config.php';
}
return SETUP_CONFIG_FILE;
}
/**
* Returns configuration array (full, multidimensional format)
*
* @return array
*/
public function getConfig()
{
$c = $_SESSION[$this->id];
foreach ($this->cfgUpdateReadMapping as $map_to => $map_from) {
PMA_array_write($map_to, $c, PMA_array_read($map_from, $c));
PMA_array_remove($map_from, $c);
}
return $c;
}
/**
* Returns configuration array (flat format)
*
* @return array
*/
public function getConfigArray()
{
$this->_flattenArrayResult = array();
array_walk($_SESSION[$this->id], array($this, '_flattenArray'), '');
$c = $this->_flattenArrayResult;
$this->_flattenArrayResult = null;
$persistKeys = array_diff(array_keys($this->persistKeys), array_keys($c));
foreach ($persistKeys as $k) {
$c[$k] = $this->getDefault($k);
}
foreach ($this->cfgUpdateReadMapping as $map_to => $map_from) {
if (!isset($c[$map_from])) {
continue;
}
$c[$map_to] = $c[$map_from];
unset($c[$map_from]);
}
return $c;
}
}
?>

View File

@ -0,0 +1,201 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Form handling code.
*
* @package PhpMyAdmin
*/
/**
* Base class for forms, loads default configuration options, checks allowed
* values etc.
*
* @package phpMyAdmin
*/
class Form
{
/**
* Form name
* @var string
*/
public $name;
/**
* Arbitrary index, doesn't affect class' behavior
* @var int
*/
public $index;
/**
* Form fields (paths), filled by {@link readFormPaths()}, indexed by field name
* @var array
*/
public $fields;
/**
* Stores default values for some fields (eg. pmadb tables)
* @var array
*/
public $default;
/**
* Caches field types, indexed by field names
* @var array
*/
private $fieldsTypes;
/**
* Constructor, reads default config values
*
* @param string $form_name
* @param array $form
* @param int $index arbitrary index, stored in Form::$index
*/
public function __construct($form_name, array $form, $index = null)
{
$this->index = $index;
$this->loadForm($form_name, $form);
}
/**
* Returns type of given option
*
* @param string $option_name path or field name
* @return string|null one of: boolean, integer, double, string, select, array
*/
public function getOptionType($option_name)
{
$key = ltrim(substr($option_name, strrpos($option_name, '/')), '/');
return isset($this->fieldsTypes[$key])
? $this->fieldsTypes[$key]
: null;
}
/**
* Returns allowed values for select fields
*
* @param string $option_path
* @return array
*/
public function getOptionValueList($option_path)
{
$value = ConfigFile::getInstance()->getDbEntry($option_path);
if ($value === null) {
trigger_error("$option_path - select options not defined", E_USER_ERROR);
return array();
}
if (!is_array($value)) {
trigger_error("$option_path - not a static value list", E_USER_ERROR);
return array();
}
// convert array('#', 'a', 'b') to array('a', 'b')
if (isset($value[0]) && $value[0] === '#') {
// remove first element ('#')
array_shift($value);
} else {
// convert value list array('a', 'b') to array('a' => 'a', 'b' => 'b')
$has_string_keys = false;
$keys = array();
for ($i = 0; $i < count($value); $i++) {
if (!isset($value[$i])) {
$has_string_keys = true;
break;
}
$keys[] = is_bool($value[$i]) ? (int)$value[$i] : $value[$i];
}
if (!$has_string_keys) {
$value = array_combine($keys, $value);
}
}
// $value has keys and value names, return it
return $value;
}
/**
* array_walk callback function, reads path of form fields from
* array (see file comment in setup.forms.php or user_preferences.forms.inc)
*
* @param mixed $value
* @param mixed $key
* @param mixed $prefix
*/
private function _readFormPathsCallback($value, $key, $prefix)
{
static $group_counter = 0;
if (is_array($value)) {
$prefix .= $key . '/';
array_walk($value, array($this, '_readFormPathsCallback'), $prefix);
} else {
if (!is_int($key)) {
$this->default[$prefix . $key] = $value;
$value = $key;
}
// add unique id to group ends
if ($value == ':group:end') {
$value .= ':' . $group_counter++;
}
$this->fields[] = $prefix . $value;
}
}
/**
* Reads form paths to {@link $fields}
*
* @param array $form
*/
protected function readFormPaths($form)
{
// flatten form fields' paths and save them to $fields
$this->fields = array();
array_walk($form, array($this, '_readFormPathsCallback'), '');
// $this->fields is an array of the form: [0..n] => 'field path'
// change numeric indexes to contain field names (last part of the path)
$paths = $this->fields;
$this->fields = array();
foreach ($paths as $path) {
$key = ltrim(substr($path, strrpos($path, '/')), '/');
$this->fields[$key] = $path;
}
// now $this->fields is an array of the form: 'field name' => 'field path'
}
/**
* Reads fields' types to $this->fieldsTypes
*
*/
protected function readTypes()
{
$cf = ConfigFile::getInstance();
foreach ($this->fields as $name => $path) {
if (strpos($name, ':group:') === 0) {
$this->fieldsTypes[$name] = 'group';
continue;
}
$v = $cf->getDbEntry($path);
if ($v !== null) {
$type = is_array($v) ? 'select' : $v;
} else {
$type = gettype($cf->getDefault($path));
}
$this->fieldsTypes[$name] = $type;
}
}
/**
* Reads form settings and prepares class to work with given subset of
* config file
*
* @param string $form_name
* @param array $form
*/
public function loadForm($form_name, $form)
{
$this->name = $form_name;
$this->readFormPaths($form);
$this->readTypes();
}
}
?>

View File

@ -0,0 +1,758 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Form management class, displays and processes forms
*
* Explanation of used terms:
* o work_path - original field path, eg. Servers/4/verbose
* o system_path - work_path modified so that it points to the first server,
* eg. Servers/1/verbose
* o translated_path - work_path modified for HTML field name, a path with
* slashes changed to hyphens, eg. Servers-4-verbose
*
* @package PhpMyAdmin
*/
/**
* Core libraries.
*/
require_once './libraries/config/FormDisplay.tpl.php';
require_once './libraries/config/validate.lib.php';
require_once './libraries/js_escape.lib.php';
/**
* Form management class, displays and processes forms
*/
class FormDisplay
{
/**
* Form list
* @var Form[]
*/
private $forms = array();
/**
* Stores validation errors, indexed by paths
* [ Form_name ] is an array of form errors
* [path] is a string storing error associated with single field
* @var array
*/
private $errors = array();
/**
* Paths changed so that they can be used as HTML ids, indexed by paths
* @var array
*/
private $translated_paths = array();
/**
* Server paths change indexes so we define maps from current server
* path to the first one, indexed by work path
* @var array
*/
private $system_paths = array();
/**
* Language strings which will be sent to PMA_messages JS variable
* Will be looked up in $GLOBALS: str{value} or strSetup{value}
* @var array
*/
private $js_lang_strings = array();
/**
* Tells whether forms have been validated
* @var bool
*/
private $is_validated = true;
/**
* Dictionary with user preferences keys
* @var array
*/
private $userprefs_keys;
/**
* Dictionary with disallowed user preferences keys
* @var array
*/
private $userprefs_disallow;
public function __construct()
{
$this->js_lang_strings = array(
'error_nan_p' => __('Not a positive number'),
'error_nan_nneg' => __('Not a non-negative number'),
'error_incorrect_port' => __('Not a valid port number'),
'error_invalid_value' => __('Incorrect value'),
'error_value_lte' => __('Value must be equal or lower than %s'));
// initialize validators
PMA_config_get_validators();
}
/**
* Registers form in form manager
*
* @param string $form_name
* @param array $form
* @param int $server_id 0 if new server, validation; >= 1 if editing a server
*/
public function registerForm($form_name, array $form, $server_id = null)
{
$this->forms[$form_name] = new Form($form_name, $form, $server_id);
$this->is_validated = false;
foreach ($this->forms[$form_name]->fields as $path) {
$work_path = $server_id === null
? $path
: str_replace('Servers/1/', "Servers/$server_id/", $path);
$this->system_paths[$work_path] = $path;
$this->translated_paths[$work_path] = str_replace('/', '-', $work_path);
}
}
/**
* Processes forms, returns true on successful save
*
* @param bool $allow_partial_save allows for partial form saving on failed validation
* @param bool $check_form_submit whether check for $_POST['submit_save']
* @return boolean
*/
public function process($allow_partial_save = true, $check_form_submit = true)
{
if ($check_form_submit && !isset($_POST['submit_save'])) {
return false;
}
// save forms
if (count($this->forms) > 0) {
return $this->save(array_keys($this->forms), $allow_partial_save);
}
return false;
}
/**
* Runs validation for all registered forms
*
*/
private function _validate()
{
if ($this->is_validated) {
return;
}
$cf = ConfigFile::getInstance();
$paths = array();
$values = array();
foreach ($this->forms as $form) {
/* @var $form Form */
$paths[] = $form->name;
// collect values and paths
foreach ($form->fields as $path) {
$work_path = array_search($path, $this->system_paths);
$values[$path] = $cf->getValue($work_path);
$paths[] = $path;
}
}
// run validation
$errors = PMA_config_validate($paths, $values, false);
// change error keys from canonical paths to work paths
if (is_array($errors) && count($errors) > 0) {
$this->errors = array();
foreach ($errors as $path => $error_list) {
$work_path = array_search($path, $this->system_paths);
// field error
if (!$work_path) {
// form error, fix path
$work_path = $path;
}
$this->errors[$work_path] = $error_list;
}
}
$this->is_validated = true;
}
/**
* Outputs HTML for forms
*
* @param bool $tabbed_form
* @param bool $show_restore_default whether show "restore default" button besides the input field
*/
public function display($tabbed_form = false, $show_restore_default = false)
{
static $js_lang_sent = false;
$js = array();
$js_default = array();
$tabbed_form = $tabbed_form && (count($this->forms) > 1);
$validators = PMA_config_get_validators();
display_form_top();
if ($tabbed_form) {
$tabs = array();
foreach ($this->forms as $form) {
$tabs[$form->name] = PMA_lang("Form_$form->name");
}
display_tabs_top($tabs);
}
// valdiate only when we aren't displaying a "new server" form
$is_new_server = false;
foreach ($this->forms as $form) {
/* @var $form Form */
if ($form->index === 0) {
$is_new_server = true;
break;
}
}
if (!$is_new_server) {
$this->_validate();
}
// user preferences
$this->_loadUserprefsInfo();
// display forms
foreach ($this->forms as $form) {
/* @var $form Form */
$form_desc = isset($GLOBALS["strConfigForm_{$form->name}_desc"])
? PMA_lang("Form_{$form->name}_desc")
: '';
$form_errors = isset($this->errors[$form->name])
? $this->errors[$form->name] : null;
display_fieldset_top(
PMA_lang("Form_$form->name"),
$form_desc,
$form_errors,
array('id' => $form->name)
);
foreach ($form->fields as $field => $path) {
$work_path = array_search($path, $this->system_paths);
$translated_path = $this->translated_paths[$work_path];
// always true/false for user preferences display
// otherwise null
$userprefs_allow = isset($this->userprefs_keys[$path])
? !isset($this->userprefs_disallow[$path])
: null;
// display input
$this->_displayFieldInput(
$form,
$field,
$path,
$work_path,
$translated_path,
$show_restore_default,
$userprefs_allow,
$js_default
);
// register JS validators for this field
if (isset($validators[$path])) {
js_validate($translated_path, $validators[$path], $js);
}
}
display_fieldset_bottom();
}
if ($tabbed_form) {
display_tabs_bottom();
}
display_form_bottom();
// if not already done, send strings used for valdiation to JavaScript
if (!$js_lang_sent) {
$js_lang_sent = true;
$js_lang = array();
foreach ($this->js_lang_strings as $strName => $strValue) {
$js_lang[] = "'$strName': '" . PMA_jsFormat($strValue, false) . '\'';
}
$js[] = "$.extend(PMA_messages, {\n\t" . implode(",\n\t", $js_lang) . '})';
}
$js[] = "$.extend(defaultValues, {\n\t" . implode(",\n\t", $js_default) . '})';
display_js($js);
}
/**
* Prepares data for input field display and outputs HTML code
*
* @param Form $form
* @param string $field field name as it appears in $form
* @param string $system_path field path, eg. Servers/1/verbose
* @param string $work_path work path, eg. Servers/4/verbose
* @param string $translated_path work path changed so that it can be used as XHTML id
* @param bool $show_restore_default whether show "restore default" button besides the input field
* @param mixed $userprefs_allow whether user preferences are enabled for this field
* (null - no support, true/false - enabled/disabled)
* @param array &$js_default array which stores JavaScript code to be displayed
*/
private function _displayFieldInput(Form $form, $field, $system_path, $work_path,
$translated_path, $show_restore_default, $userprefs_allow, array &$js_default)
{
$name = PMA_lang_name($system_path);
$description = PMA_lang_name($system_path, 'desc', '');
$cf = ConfigFile::getInstance();
$value = $cf->get($work_path);
$value_default = $cf->getDefault($system_path);
$value_is_default = false;
if ($value === null || $value === $value_default) {
$value = $value_default;
$value_is_default = true;
}
$opts = array(
'doc' => $this->getDocLink($system_path),
'wiki' => $this->getWikiLink($system_path),
'show_restore_default' => $show_restore_default,
'userprefs_allow' => $userprefs_allow,
'userprefs_comment' => PMA_lang_name($system_path, 'cmt', ''));
if (isset($form->default[$system_path])) {
$opts['setvalue'] = $form->default[$system_path];
}
if (isset($this->errors[$work_path])) {
$opts['errors'] = $this->errors[$work_path];
}
switch ($form->getOptionType($field)) {
case 'string':
$type = 'text';
break;
case 'short_string':
$type = 'short_text';
break;
case 'double':
case 'integer':
$type = 'number_text';
break;
case 'boolean':
$type = 'checkbox';
break;
case 'select':
$type = 'select';
$opts['values'] = $form->getOptionValueList($form->fields[$field]);
break;
case 'array':
$type = 'list';
$value = (array) $value;
$value_default = (array) $value_default;
break;
case 'group':
if (substr($field, 7, 4) != 'end:') { // :group:end is changed to :group:end:{unique id} in Form class
display_group_header(substr($field, 7));
} else {
display_group_footer();
}
return;
case 'NULL':
trigger_error("Field $system_path has no type", E_USER_WARNING);
return;
}
// TrustedProxies requires changes before displaying
if ($system_path == 'TrustedProxies') {
foreach ($value as $ip => &$v) {
if (!preg_match('/^-\d+$/', $ip)) {
$v = $ip . ': ' . $v;
}
}
}
$this->_setComments($system_path, $opts);
// send default value to form's JS
$js_line = '\'' . $translated_path . '\': ';
switch ($type) {
case 'text':
case 'short_text':
case 'number_text':
$js_line .= '\'' . PMA_escapeJsString($value_default) . '\'';
break;
case 'checkbox':
$js_line .= $value_default ? 'true' : 'false';
break;
case 'select':
$value_default_js = is_bool($value_default)
? (int) $value_default
: $value_default;
$js_line .= '[\'' . PMA_escapeJsString($value_default_js) . '\']';
break;
case 'list':
$js_line .= '\'' . PMA_escapeJsString(implode("\n", $value_default)) . '\'';
break;
}
$js_default[] = $js_line;
display_input($translated_path, $name, $description, $type,
$value, $value_is_default, $opts);
}
/**
* Displays errors
*
*/
public function displayErrors()
{
$this->_validate();
if (count($this->errors) == 0) {
return;
}
foreach ($this->errors as $system_path => $error_list) {
if (isset($this->system_paths[$system_path])) {
$path = $this->system_paths[$system_path];
$name = PMA_lang_name($path);
} else {
$name = $GLOBALS["strConfigForm_$system_path"];
}
display_errors($name, $error_list);
}
}
/**
* Reverts erroneous fields to their default values
*
*
*/
public function fixErrors()
{
$this->_validate();
if (count($this->errors) == 0) {
return;
}
$cf = ConfigFile::getInstance();
foreach (array_keys($this->errors) as $work_path) {
if (!isset($this->system_paths[$work_path])) {
continue;
}
$canonical_path = $this->system_paths[$work_path];
$cf->set($work_path, $cf->getDefault($canonical_path));
}
}
/**
* Validates select field and casts $value to correct type
*
* @param string $value
* @param array $allowed
* @return bool
*/
private function _validateSelect(&$value, array $allowed)
{
$value_cmp = is_bool($value)
? (int) $value
: $value;
foreach ($allowed as $vk => $v) {
// equality comparison only if both values are numeric or not numeric
// (allows to skip 0 == 'string' equalling to true) or identity (for string-string)
if (($vk == $value && !(is_numeric($value_cmp) xor is_numeric($vk)))
|| $vk === $value) {
// keep boolean value as boolean
if (!is_bool($value)) {
settype($value, gettype($vk));
}
return true;
}
}
return false;
}
/**
* Validates and saves form data to session
*
* @param array|string $forms array of form names
* @param bool $allow_partial_save allows for partial form saving on failed validation
* @return boolean true on success (no errors and all saved)
*/
public function save($forms, $allow_partial_save = true)
{
$result = true;
$cf = ConfigFile::getInstance();
$forms = (array) $forms;
$values = array();
$to_save = array();
$is_setup_script = defined('PMA_SETUP');
if ($is_setup_script) {
$this->_loadUserprefsInfo();
}
$this->errors = array();
foreach ($forms as $form_name) {
/* @var $form Form */
if (isset($this->forms[$form_name])) {
$form = $this->forms[$form_name];
} else {
continue;
}
// get current server id
$change_index = $form->index === 0
? $cf->getServerCount() + 1
: false;
// grab POST values
foreach ($form->fields as $field => $system_path) {
$work_path = array_search($system_path, $this->system_paths);
$key = $this->translated_paths[$work_path];
$type = $form->getOptionType($field);
// skip groups
if ($type == 'group') {
continue;
}
// ensure the value is set
if (!isset($_POST[$key])) {
// checkboxes aren't set by browsers if they're off
if ($type == 'boolean') {
$_POST[$key] = false;
} else {
$this->errors[$form->name][] = sprintf(
__('Missing data for %s'),
'<i>' . PMA_lang_name($system_path) . '</i>');
$result = false;
continue;
}
}
// user preferences allow/disallow
if ($is_setup_script && isset($this->userprefs_keys[$system_path])) {
if (isset($this->userprefs_disallow[$system_path])
&& isset($_POST[$key . '-userprefs-allow'])) {
unset($this->userprefs_disallow[$system_path]);
} else if (!isset($_POST[$key . '-userprefs-allow'])) {
$this->userprefs_disallow[$system_path] = true;
}
}
// cast variables to correct type
switch ($type) {
case 'double':
settype($_POST[$key], 'float');
break;
case 'boolean':
case 'integer':
if ($_POST[$key] !== '') {
settype($_POST[$key], $type);
}
break;
case 'select':
// special treatment for NavigationBarIconic and PropertiesIconic
if ($key === 'NavigationBarIconic' || $key === 'PropertiesIconic') {
if ($_POST[$key] !== 'both') {
settype($_POST[$key], 'boolean');
}
}
if (!$this->_validateSelect($_POST[$key], $form->getOptionValueList($system_path))) {
$this->errors[$work_path][] = __('Incorrect value');
$result = false;
continue;
}
break;
case 'string':
case 'short_string':
$_POST[$key] = trim($_POST[$key]);
break;
case 'array':
// eliminate empty values and ensure we have an array
$post_values = is_array($_POST[$key])
? $_POST[$key]
: explode("\n", $_POST[$key]);
$_POST[$key] = array();
foreach ($post_values as $v) {
$v = trim($v);
if ($v !== '') {
$_POST[$key][] = $v;
}
}
break;
}
// now we have value with proper type
$values[$system_path] = $_POST[$key];
if ($change_index !== false) {
$work_path = str_replace("Servers/$form->index/",
"Servers/$change_index/", $work_path);
}
$to_save[$work_path] = $system_path;
}
}
// save forms
if ($allow_partial_save || empty($this->errors)) {
foreach ($to_save as $work_path => $path) {
// TrustedProxies requires changes before saving
if ($path == 'TrustedProxies') {
$proxies = array();
$i = 0;
foreach ($values[$path] as $value) {
$matches = array();
if (preg_match("/^(.+):(?:[ ]?)(\\w+)$/", $value, $matches)) {
// correct 'IP: HTTP header' pair
$ip = trim($matches[1]);
$proxies[$ip] = trim($matches[2]);
} else {
// save also incorrect values
$proxies["-$i"] = $value;
$i++;
}
}
$values[$path] = $proxies;
}
$cf->set($work_path, $values[$path], $path);
}
if ($is_setup_script) {
$cf->set('UserprefsDisallow', array_keys($this->userprefs_disallow));
}
}
// don't look for non-critical errors
$this->_validate();
return $result;
}
/**
* Tells whether form validation failed
*
* @return boolean
*/
public function hasErrors()
{
return count($this->errors) > 0;
}
/**
* Returns link to documentation
*
* @param string $path
* @return string
*/
public function getDocLink($path)
{
$test = substr($path, 0, 6);
if ($test == 'Import' || $test == 'Export') {
return '';
}
return 'Documentation.html#cfg_' . $this->_getOptName($path);
}
/**
* Returns link to wiki
*
* @param string $path
* @return string
*/
public function getWikiLink($path)
{
$opt_name = $this->_getOptName($path);
if (substr($opt_name, 0, 7) == 'Servers') {
$opt_name = substr($opt_name, 8);
if (strpos($opt_name, 'AllowDeny') === 0) {
$opt_name = str_replace('_', '_.28', $opt_name) . '.29';
}
}
$test = substr($path, 0, 6);
if ($test == 'Import') {
$opt_name = substr($opt_name, 7);
if ($opt_name == 'format') {
$opt_name = 'format_2';
}
}
if ($test == 'Export') {
$opt_name = substr($opt_name, 7);
}
return PMA_linkURL('http://wiki.phpmyadmin.net/pma/Config#' . $opt_name);
}
/**
* Changes path so it can be used in URLs
*
* @param string $path
* @return string
*/
private function _getOptName($path)
{
return str_replace(array('Servers/1/', '/'), array('Servers/', '_'), $path);
}
/**
* Fills out {@link userprefs_keys} and {@link userprefs_disallow}
*
*/
private function _loadUserprefsInfo()
{
if ($this->userprefs_keys === null) {
$this->userprefs_keys = array_flip(PMA_read_userprefs_fieldnames());
// read real config for user preferences display
$userprefs_disallow = defined('PMA_SETUP')
? ConfigFile::getInstance()->get('UserprefsDisallow', array())
: $GLOBALS['cfg']['UserprefsDisallow'];
$this->userprefs_disallow = array_flip($userprefs_disallow);
}
}
/**
* Sets field comments and warnings based on current environment
*
* @param string $system_path
* @param array $opts
*/
private function _setComments($system_path, array &$opts)
{
// RecodingEngine - mark unavailable types
if ($system_path == 'RecodingEngine') {
$comment = '';
if (!function_exists('iconv')) {
$opts['values']['iconv'] .= ' (' . __('unavailable') . ')';
$comment = sprintf(__('"%s" requires %s extension'), 'iconv', 'iconv');
}
if (!function_exists('recode_string')) {
$opts['values']['recode'] .= ' (' . __('unavailable') . ')';
$comment .= ($comment ? ", " : '') . sprintf(__('"%s" requires %s extension'),
'recode', 'recode');
}
$opts['comment'] = $comment;
$opts['comment_warning'] = true;
}
// ZipDump, GZipDump, BZipDump - check function availability
if ($system_path == 'ZipDump' || $system_path == 'GZipDump' || $system_path == 'BZipDump') {
$comment = '';
$funcs = array(
'ZipDump' => array('zip_open', 'gzcompress'),
'GZipDump' => array('gzopen', 'gzencode'),
'BZipDump' => array('bzopen', 'bzcompress'));
if (!function_exists($funcs[$system_path][0])) {
$comment = sprintf(__('import will not work, missing function (%s)'),
$funcs[$system_path][0]);
}
if (!function_exists($funcs[$system_path][1])) {
$comment .= ($comment ? '; ' : '') . sprintf(__('export will not work, missing function (%s)'),
$funcs[$system_path][1]);
}
$opts['comment'] = $comment;
$opts['comment_warning'] = true;
}
if ($system_path == 'SQLQuery/Validate' && !$GLOBALS['cfg']['SQLValidator']['use']) {
$opts['comment'] = __('SQL Validator is disabled');
$opts['comment_warning'] = true;
}
if ($system_path == 'SQLValidator/use') {
if (!class_exists('SOAPClient')) {
@include_once 'SOAP/Client.php';
if (!class_exists('SOAP_Client')) {
$opts['comment'] = __('SOAP extension not found');
$opts['comment_warning'] = true;
}
}
}
if (!defined('PMA_SETUP')) {
if (($system_path == 'MaxDbList' || $system_path == 'MaxTableList'
|| $system_path == 'QueryHistoryMax')) {
$opts['comment'] = sprintf(__('maximum %s'), $GLOBALS['cfg'][$system_path]);
}
}
}
}
?>

View File

@ -0,0 +1,446 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Form templates
*
* @package PhpMyAdmin
*/
/**
* Displays top part of the form
*
* @param string $action default: $_SERVER['REQUEST_URI']
* @param string $method 'post' or 'get'
* @param array $hidden_fields array of form hidden fields (key: field name)
*/
function display_form_top($action = null, $method = 'post', $hidden_fields = null)
{
static $has_check_page_refresh = false;
if ($action === null) {
$action = $_SERVER['REQUEST_URI'];
}
if ($method != 'post') {
$method = 'get';
}
?>
<form method="<?php echo $method ?>" action="<?php echo htmlspecialchars($action) ?>" class="config-form">
<input type="hidden" name="tab_hash" value="" />
<?php
// we do validation on page refresh when browser remembers field values,
// add a field with known value which will be used for checks
if (!$has_check_page_refresh) {
$has_check_page_refresh = true;
echo '<input type="hidden" name="check_page_refresh" id="check_page_refresh"'
. ' value="" />' . "\n";
}
echo PMA_generate_common_hidden_inputs('', '', 0, 'server') . "\n";
echo PMA_getHiddenFields((array)$hidden_fields);
}
/**
* Displays form tabs which are given by an array indexed by fieldset id
* ({@link display_fieldset_top}), with values being tab titles.
*
* @param array $tabs
*/
function display_tabs_top($tabs)
{
?>
<ul class="tabs">
<?php foreach ($tabs as $tab_id => $tab_name): ?>
<li><a href="#<?php echo $tab_id ?>"><?php echo htmlspecialchars($tab_name); ?></a></li>
<?php endforeach; ?>
</ul>
<br clear="right" />
<div class="tabs_contents">
<?php
}
/**
* Displays top part of a fieldset
*
* @param string $title
* @param string $description
* @param array $errors
* @param array $attributes
*/
function display_fieldset_top($title = '', $description = '', $errors = null, $attributes = array())
{
global $_FormDisplayGroup;
$_FormDisplayGroup = 0;
$attributes = array_merge(array('class' => 'optbox'), $attributes);
foreach ($attributes as $k => &$attr) {
$attr = $k . '="' . htmlspecialchars($attr) . '"';
}
echo '<fieldset ' . implode(' ', $attributes) . '>';
echo '<legend>' . $title . '</legend>';
if (!empty($description)) {
echo '<p>' . $description . '</p>';
}
// this must match with displayErrors() in scripts.js
if (is_array($errors) && count($errors) > 0) {
echo '<dl class="errors">';
foreach ($errors as $error) {
echo '<dd>' . $error . '</dd>';
}
echo '</dl>';
}
?>
<table width="100%" cellspacing="0">
<?php
}
/**
* Displays input field
*
* $opts keys:
* o doc - (string) documentation link
* o errors - error array
* o setvalue - (string) shows button allowing to set poredefined value
* o show_restore_default - (boolean) whether show "restore default" button
* o userprefs_allow - whether user preferences are enabled for this field (null - no support,
* true/false - enabled/disabled)
* o userprefs_comment - (string) field comment
* o values - key - value paris for <select> fields
* o values_escaped - (boolean) tells whether values array is already escaped (defaults to false)
* o values_disabled - (array)list of disabled values (keys from values)
* o comment - (string) tooltip comment
* o comment_warning - (bool) whether this comments warns about something
* o wiki - (string) wiki link
*
* @param string $path
* @param string $name
* @param string $description
* @param string $type
* @param mixed $value
* @param bool $value_is_default
* @param array $opts
*/
function display_input($path, $name, $description = '', $type, $value, $value_is_default = true, $opts = null)
{
global $_FormDisplayGroup;
static $base_dir; // Relative path to the root phpMyAdmin folder
static $icons; // An array of IMG tags used further below in the function
$is_setup_script = defined('PMA_SETUP');
if ($base_dir === null) { // if the static variables have not been initialised
$base_dir = $is_setup_script ? '../' : '';
$icons = array();
// Icon definitions:
// The same indexes will be used in the $icons array.
// The first element contains the filename and the second
// element is used for the "alt" and "title" attributes.
$icon_init = array(
'edit' => array('b_edit.png', ''),
'help' => array('b_help.png', __('Documentation')),
'info' => array('b_info.png', __('Wiki')),
'reload' => array('s_reload.png', ''),
'tblops' => array('b_tblops.png', '')
);
if ($is_setup_script) {
// When called from the setup script, we don't have access to the
// sprite-aware PMA_getImage() function because the PMA_theme class
// has not been loaded, so we generate the img tags manually.
foreach ($icon_init as $k => $v) {
$title = '';
if (! empty($v[1])) {
$title = ' title="' . $v[1] . '"';
}
$icons[$k] = sprintf(
'<img alt="%s" src="%s"%s />',
$v[1],
".{$GLOBALS['cfg']['ThemePath']}/original/img/{$v[0]}",
$title
);
}
} else {
// In this case we just use PMA_getImage() because it's available
foreach ($icon_init as $k => $v) {
$icons[$k] = PMA_getImage($v[0], $v[1]);
}
}
}
$has_errors = isset($opts['errors']) && !empty($opts['errors']);
$option_is_disabled = !$is_setup_script && isset($opts['userprefs_allow']) && !$opts['userprefs_allow'];
$name_id = 'name="' . htmlspecialchars($path) . '" id="' . htmlspecialchars($path) . '"';
$field_class = $type == 'checkbox' ? 'checkbox' : '';
if (!$value_is_default) {
$field_class .= ($field_class == '' ? '' : ' ') . ($has_errors ? 'custom field-error' : 'custom');
}
$field_class = $field_class ? ' class="' . $field_class . '"' : '';
$tr_class = $_FormDisplayGroup > 0
? 'group-field group-field-' . $_FormDisplayGroup
: '';
if (isset($opts['setvalue']) && $opts['setvalue'] == ':group') {
unset($opts['setvalue']);
$_FormDisplayGroup++;
$tr_class = 'group-header-field group-header-' . $_FormDisplayGroup;
}
if ($option_is_disabled) {
$tr_class .= ($tr_class ? ' ' : '') . 'disabled-field';
}
$tr_class = $tr_class ? ' class="' . $tr_class . '"' : '';
?>
<tr<?php echo $tr_class ?>>
<th>
<label for="<?php echo htmlspecialchars($path) ?>"><?php echo $name ?></label>
<?php if (!empty($opts['doc']) || !empty($opts['wiki'])) { ?>
<span class="doc">
<?php if (!empty($opts['doc'])) { ?><a href="<?php echo $base_dir . $opts['doc'] ?>" target="documentation"><?php echo $icons['help']; ?></a><?php } ?>
<?php if (!empty($opts['wiki'])){ ?><a href="<?php echo $opts['wiki'] ?>" target="wiki"><?php echo $icons['info']; ?></a><?php } ?>
</span>
<?php } ?>
<?php if ($option_is_disabled) { ?>
<span class="disabled-notice" title="<?php echo __('This setting is disabled, it will not be applied to your configuration') ?>"><?php echo __('Disabled') ?></span>
<?php } ?>
<?php if (!empty($description)) { ?><small><?php echo $description ?></small><?php } ?>
</th>
<td>
<?php
switch ($type) {
case 'text':
echo '<input type="text" size="60" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'short_text':
echo '<input type="text" size="25" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'number_text':
echo '<input type="text" size="15" ' . $name_id . $field_class
. ' value="' . htmlspecialchars($value) . '" />';
break;
case 'checkbox':
echo '<span' . $field_class . '><input type="checkbox" ' . $name_id
. ($value ? ' checked="checked"' : '') . ' /></span>';
break;
case 'select':
echo '<select ' . $name_id . $field_class . '>';
$escape = !(isset($opts['values_escaped']) && $opts['values_escaped']);
$values_disabled = isset($opts['values_disabled'])
? array_flip($opts['values_disabled']) : array();
foreach ($opts['values'] as $opt_value_key => $opt_value) {
// set names for boolean values
if (is_bool($opt_value)) {
$opt_value = strtolower($opt_value ? __('Yes') : __('No'));
}
// escape if necessary
if ($escape) {
$display = htmlspecialchars($opt_value);
$display_value = htmlspecialchars($opt_value_key);
} else {
$display = $opt_value;
$display_value = $opt_value_key;
}
// compare with selected value
// boolean values are cast to integers when used as array keys
$selected = is_bool($value)
? (int) $value === $opt_value_key
: $opt_value_key === $value;
echo '<option value="' . $display_value . '"'
. ($selected ? ' selected="selected"' : '')
. (isset($values_disabled[$opt_value_key]) ? ' disabled="disabled"' : '')
. '>' . $display . '</option>';
}
echo '</select>';
break;
case 'list':
echo '<textarea cols="40" rows="5" ' . $name_id . $field_class . '>'
. htmlspecialchars(implode("\n", $value))
. '</textarea>';
break;
}
if (isset($opts['comment']) && $opts['comment']) {
$class = 'field-comment-mark';
if (isset($opts['comment_warning']) && $opts['comment_warning']) {
$class .= ' field-comment-warning';
}
?>
<span class="<?php echo $class ?>" title="<?php echo htmlspecialchars($opts['comment']) ?>">i</span>
<?php
}
if ($is_setup_script && isset($opts['userprefs_comment']) && $opts['userprefs_comment']) {
?>
<a class="userprefs-comment" title="<?php echo htmlspecialchars($opts['userprefs_comment']) ?>"><?php echo $icons['tblops']; ?></a>
<?php
}
if (isset($opts['setvalue']) && $opts['setvalue']) {
?>
<a class="set-value" href="#<?php echo htmlspecialchars("$path={$opts['setvalue']}") ?>" title="<?php echo sprintf(__('Set value: %s'), htmlspecialchars($opts['setvalue'])) ?>" style="display:none"><?php echo $icons['edit']; ?></a>
<?php
}
if (isset($opts['show_restore_default']) && $opts['show_restore_default']) {
?>
<a class="restore-default" href="#<?php echo $path ?>" title="<?php echo __('Restore default value') ?>" style="display:none"><?php echo $icons['reload']; ?></a>
<?php
}
// this must match with displayErrors() in scripts/config.js
if ($has_errors) {
echo "\n <dl class=\"inline_errors\">";
foreach ($opts['errors'] as $error) {
echo '<dd>' . htmlspecialchars($error) . '</dd>';
}
echo '</dl>';
}
?>
</td>
<?php
if ($is_setup_script && isset($opts['userprefs_allow'])) {
?>
<td class="userprefs-allow" title="<?php echo __('Allow users to customize this value') ?>">
<input type="checkbox" name="<?php echo $path ?>-userprefs-allow" <?php if ($opts['userprefs_allow']) echo 'checked="checked"' ?> />
</td>
<?php
} else if ($is_setup_script) {
echo '<td>&nbsp;</td>';
}
?>
</tr>
<?php
}
/**
* Display group header
*
* @param string $header_text
*/
function display_group_header($header_text)
{
global $_FormDisplayGroup;
$_FormDisplayGroup++;
if (!$header_text) {
return;
}
$colspan = defined('PMA_SETUP')
? 3
: 2;
?>
<tr class="group-header group-header-<?php echo $_FormDisplayGroup ?>">
<th colspan="<?php echo $colspan ?>">
<?php echo $header_text ?>
</th>
</tr>
<?php
}
/**
* Display group footer
*
*/
function display_group_footer()
{
global $_FormDisplayGroup;
$_FormDisplayGroup--;
}
/**
* Displays bottom part of a fieldset
*/
function display_fieldset_bottom()
{
$colspan = 2;
if (defined('PMA_SETUP')) {
$colspan++;
}
?>
<tr>
<td colspan="<?php echo $colspan ?>" class="lastrow">
<input type="submit" name="submit_save" value="<?php echo __('Save') ?>" class="green" />
<input type="button" name="submit_reset" value="<?php echo __('Reset') ?>" />
</td>
</tr>
</table>
</fieldset>
<?php
}
/**
* Displays simple bottom part of a fieldset (without submit buttons)
*/
function display_fieldset_bottom_simple()
{
?>
</table>
</fieldset>
<?php
}
/**
* Closes form tabs
*/
function display_tabs_bottom()
{
echo "</div>\n";
}
/**
* Displays bottom part of the form
*/
function display_form_bottom()
{
echo "</form>\n";
}
/**
* Appends JS validation code to $js_array
*
* @param string $field_id
* @param string|array $validator
* @param array $js_array
*/
function js_validate($field_id, $validators, &$js_array)
{
foreach ((array)$validators as $validator) {
$validator = (array)$validator;
$v_name = array_shift($validator);
$v_args = array();
foreach ($validator as $arg) {
$v_args[] = PMA_escapeJsString($arg);
}
$v_args = $v_args ? ", ['" . implode("', '", $v_args) . "']" : '';
$js_array[] = "validateField('$field_id', '$v_name', true$v_args)";
}
}
/**
* Displays JavaScript code
*
* @param array $js_array
*/
function display_js($js_array)
{
if (empty($js_array)) {
return;
}
?>
<script type="text/javascript">
<?php echo implode(";\n", $js_array) . ";\n" ?>
</script>
<?php
}
/**
* Displays error list
*
* @param string $name
* @param array $error_list
*/
function display_errors($name, $error_list)
{
echo '<dl>';
echo '<dt>' . htmlspecialchars($name) . '</dt>';
foreach ($error_list as $error) {
echo '<dd>' . htmlspecialchars($error) . '</dd>';
}
echo '</dl>';
}
?>

View File

@ -0,0 +1,51 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Common config manipulation functions
*
* @package PhpMyAdmin
*/
/**
* Returns sanitized language string, taking into account our special codes
* for formatting. Takes variable number of arguments.
* Based on PMA_sanitize from sanitize.lib.php.
*
* @param string $lang_key key in $GLOBALS WITHOUT 'strSetup' prefix
* @param mixed $args,... arguments for sprintf
* @return string
*/
function PMA_lang($lang_key, $args = null)
{
$message = isset($GLOBALS["strConfig$lang_key"]) ? $GLOBALS["strConfig$lang_key"] : $lang_key;
$message = PMA_sanitize($message);
if (func_num_args() == 1) {
return $message;
} else {
$args = func_get_args();
array_shift($args);
return vsprintf($message, $args);
}
}
/**
* Returns translated field name/description or comment
*
* @param string $canonical_path
* @param string $type 'name', 'desc' or 'cmt'
* @param mixed $default
* @return string
*/
function PMA_lang_name($canonical_path, $type = 'name', $default = 'key')
{
$lang_key = str_replace(
array('Servers/1/', '/'),
array('Servers/', '_'),
$canonical_path) . '_' . $type;
return isset($GLOBALS["strConfig$lang_key"])
? ($type == 'desc' ? PMA_lang($lang_key) : $GLOBALS["strConfig$lang_key"])
: ($default == 'key' ? $lang_key : $default);
}
?>

View File

@ -0,0 +1,527 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Messages for phpMyAdmin.
*
* This file defines variables in a special format suited for the
* configuration subsystem, with $strConfig as a prefix, _desc or _name
* as a suffix, and the directive name in between.
*
* @package PhpMyAdmin
*/
if (!function_exists('__')) {
die('Bad invocation!');
}
$strConfigAjaxEnable_desc = __('Improves efficiency of screen refresh');
$strConfigAjaxEnable_name = __('Enable Ajax');
$strConfigAllowArbitraryServer_desc = __('If enabled user can enter any MySQL server in login form for cookie auth');
$strConfigAllowArbitraryServer_name = __('Allow login to any MySQL server');
$strConfigAllowThirdPartyFraming_desc = __('Enabling this allows a page located on a different domain to call phpMyAdmin inside a frame, and is a potential [strong]security hole[/strong] allowing cross-frame scripting attacks');
$strConfigAllowThirdPartyFraming_name = __('Allow third party framing');
$strConfigAllowUserDropDatabase_name = __('Show &quot;Drop database&quot; link to normal users');
$strConfigblowfish_secret_desc = __('Secret passphrase used for encrypting cookies in [kbd]cookie[/kbd] authentication');
$strConfigblowfish_secret_name = __('Blowfish secret');
$strConfigBrowseMarkerEnable_desc = __('Highlight selected rows');
$strConfigBrowseMarkerEnable_name = __('Row marker');
$strConfigBrowsePointerEnable_desc = __('Highlight row pointed by the mouse cursor');
$strConfigBrowsePointerEnable_name = __('Highlight pointer');
$strConfigBZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/Bzip2]bzip2[/a] compression for import and export operations');
$strConfigBZipDump_name = __('Bzip2');
$strConfigCharEditing_desc = __('Defines which type of editing controls should be used for CHAR and VARCHAR columns; [kbd]input[/kbd] - allows limiting of input length, [kbd]textarea[/kbd] - allows newlines in columns');
$strConfigCharEditing_name = __('CHAR columns editing');
$strConfigMinSizeForInputField_desc = __('Defines the minimum size for input fields generated for CHAR and VARCHAR columns');
$strConfigMinSizeForInputField_name = __('Minimum size for input field');
$strConfigMaxSizeForInputField_desc = __('Defines the maximum size for input fields generated for CHAR and VARCHAR columns');
$strConfigMaxSizeForInputField_name = __('Maximum size for input field');
$strConfigCharTextareaCols_desc = __('Number of columns for CHAR/VARCHAR textareas');
$strConfigCharTextareaCols_name = __('CHAR textarea columns');
$strConfigCharTextareaRows_desc = __('Number of rows for CHAR/VARCHAR textareas');
$strConfigCharTextareaRows_name = __('CHAR textarea rows');
$strConfigCheckConfigurationPermissions_name = __('Check config file permissions');
$strConfigCompressOnFly_desc = __('Compress gzip/bzip2 exports on the fly without the need for much memory; if you encounter problems with created gzip/bzip2 files disable this feature');
$strConfigCompressOnFly_name = __('Compress on the fly');
$strConfigConfigurationFile = __('Configuration file');
$strConfigConfirm_desc = __('Whether a warning (&quot;Are your really sure...&quot;) should be displayed when you\'re about to lose data');
$strConfigConfirm_name = __('Confirm DROP queries');
$strConfigDBG_sql_name = __('Debug SQL');
$strConfigDefaultDisplay_name = __('Default display direction');
$strConfigDefaultTabDatabase_desc = __('Tab that is displayed when entering a database');
$strConfigDefaultTabDatabase_name = __('Default database tab');
$strConfigDefaultTabServer_desc = __('Tab that is displayed when entering a server');
$strConfigDefaultTabServer_name = __('Default server tab');
$strConfigDefaultTabTable_desc = __('Tab that is displayed when entering a table');
$strConfigDefaultTabTable_name = __('Default table tab');
$strConfigDisplayBinaryAsHex_desc = __('Show binary contents as HEX by default');
$strConfigDisplayBinaryAsHex_name = __('Show binary contents as HEX');
$strConfigDisplayDatabasesList_desc = __('Show database listing as a list instead of a drop down');
$strConfigDisplayDatabasesList_name = __('Display databases as a list');
$strConfigDisplayServersList_desc = __('Show server listing as a list instead of a drop down');
$strConfigDisplayServersList_name = __('Display servers as a list');
$strConfigDisableMultiTableMaintenance_desc = __('Disable the table maintenance mass operations, like optimizing or repairing the selected tables of a database.');
$strConfigDisableMultiTableMaintenance_name = __('Disable multi table maintenance');
$strConfigEditInWindow_desc = __('Edit SQL queries in popup window');
$strConfigEditInWindow_name = __('Edit in window');
$strConfigError_Handler_display_name = __('Display errors');
$strConfigError_Handler_gather_name = __('Gather errors');
$strConfigErrorIconic_desc = __('Show icons for warning, error and information messages');
$strConfigErrorIconic_name = __('Iconic errors');
$strConfigExecTimeLimit_desc = __('Set the number of seconds a script is allowed to run ([kbd]0[/kbd] for no limit)');
$strConfigExecTimeLimit_name = __('Maximum execution time');
$strConfigExport_asfile_name = __('Save as file');
$strConfigExport_charset_name = __('Character set of the file');
$strConfigExport_codegen_format_name = __('Format');
$strConfigExport_compression_name = __('Compression');
$strConfigExport_csv_columns_name = __('Put columns names in the first row');
$strConfigExport_csv_enclosed_name = __('Columns enclosed by');
$strConfigExport_csv_escaped_name = __('Columns escaped by');
$strConfigExport_csv_null_name = __('Replace NULL by');
$strConfigExport_csv_removeCRLF_name = __('Remove CRLF characters within columns');
$strConfigExport_csv_separator_name = __('Columns terminated by');
$strConfigExport_csv_terminated_name = __('Lines terminated by');
$strConfigExport_excel_columns_name = __('Put columns names in the first row');
$strConfigExport_excel_edition_name = __('Excel edition');
$strConfigExport_excel_null_name = __('Replace NULL by');
$strConfigExport_excel_removeCRLF_name = __('Remove CRLF characters within columns');
$strConfigExport_file_template_database_name = __('Database name template');
$strConfigExport_file_template_server_name = __('Server name template');
$strConfigExport_file_template_table_name = __('Table name template');
$strConfigExport_format_name = __('Format');
$strConfigExport_htmlword_columns_name = __('Put columns names in the first row');
$strConfigExport_htmlword_null_name = __('Replace NULL by');
$strConfigExport_htmlword_structure_or_data_name = __('Dump table');
$strConfigExport_latex_caption_name = __('Include table caption');
$strConfigExport_latex_columns_name = __('Put columns names in the first row');
$strConfigExport_latex_comments_name = __('Comments');
$strConfigExport_latex_data_caption_name = __('Table caption');
$strConfigExport_latex_data_continued_caption_name = __('Continued table caption');
$strConfigExport_latex_data_label_name = __('Label key');
$strConfigExport_latex_mime_name = __('MIME type');
$strConfigExport_latex_null_name = __('Replace NULL by');
$strConfigExport_latex_relation_name = __('Relations');
$strConfigExport_latex_structure_caption_name = __('Table caption');
$strConfigExport_latex_structure_continued_caption_name = __('Continued table caption');
$strConfigExport_latex_structure_label_name = __('Label key');
$strConfigExport_latex_structure_or_data_name = __('Dump table');
$strConfigExport_method_name = __('Export method');
$strConfigExport_ods_columns_name = __('Put columns names in the first row');
$strConfigExport_ods_null_name = __('Replace NULL by');
$strConfigExport_odt_columns_name = __('Put columns names in the first row');
$strConfigExport_odt_comments_name = __('Comments');
$strConfigExport_odt_mime_name = __('MIME type');
$strConfigExport_odt_null_name = __('Replace NULL by');
$strConfigExport_odt_relation_name = __('Relations');
$strConfigExport_odt_structure_or_data_name = __('Dump table');
$strConfigExport_onserver_name = __('Save on server');
$strConfigExport_onserver_overwrite_name = __('Overwrite existing file(s)');
$strConfigExport_quick_export_onserver_name = __('Save on server');
$strConfigExport_quick_export_onserver_overwrite_name = __('Overwrite existing file(s)');
$strConfigExport_remember_file_template_name = __('Remember file name template');
$strConfigExport_sql_auto_increment_name = __('Add AUTO_INCREMENT value');
$strConfigExport_sql_backquotes_name = __('Enclose table and column names with backquotes');
$strConfigExport_sql_compatibility_name = __('SQL compatibility mode');
$strConfigExport_sql_create_table_statements_name = __('<code>CREATE TABLE</code> options:');
$strConfigExport_sql_dates_name = __('Creation/Update/Check dates');
$strConfigExport_sql_delayed_name = __('Use delayed inserts');
$strConfigExport_sql_disable_fk_name = __('Disable foreign key checks');
$strConfigExport_sql_drop_database_name = sprintf(__('Add %s'), 'DROP DATABASE');
$strConfigExport_sql_drop_table_name = sprintf(__('Add %s'), 'DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT');
$strConfigExport_sql_hex_for_blob_name = __('Use hexadecimal for BLOB');
$strConfigExport_sql_if_not_exists_name = sprintf(__('Add %s'), 'IF NOT EXISTS');
$strConfigExport_sql_ignore_name = __('Use ignore inserts');
$strConfigExport_sql_include_comments_name = __('Comments');
$strConfigExport_sql_insert_syntax_name = __('Syntax to use when inserting data');
$strConfigExport_sql_max_query_size_name = __('Maximal length of created query');
$strConfigExport_sql_mime_name = __('MIME type');
$strConfigExport_sql_procedure_function_name = sprintf(__('Add %s'), 'CREATE PROCEDURE / FUNCTION / EVENT');
$strConfigExport_sql_relation_name = __('Relations');
$strConfigExport_sql_structure_or_data_name = __('Dump table');
$strConfigExport_sql_type_name = __('Export type');
$strConfigExport_sql_use_transaction_name = __('Enclose export in a transaction');
$strConfigExport_sql_utc_time_name = __('Export time in UTC');
$strConfigExport_texytext_columns_name = __('Put columns names in the first row');
$strConfigExport_texytext_null_name = __('Replace NULL by');
$strConfigExport_texytext_structure_or_data_name = __('Dump table');
$strConfigExport_xls_columns_name = __('Put columns names in the first row');
$strConfigExport_xls_null_name = __('Replace NULL by');
$strConfigExport_xlsx_columns_name = __('Put columns names in the first row');
$strConfigExport_xlsx_null_name = __('Replace NULL by');
$strConfigForceSSL_desc = __('Force secured connection while using phpMyAdmin');
$strConfigForceSSL_name = __('Force SSL connection');
$strConfigForeignKeyDropdownOrder_desc = __('Sort order for items in a foreign-key dropdown box; [kbd]content[/kbd] is the referenced data, [kbd]id[/kbd] is the key value');
$strConfigForeignKeyDropdownOrder_name = __('Foreign key dropdown order');
$strConfigForeignKeyMaxLimit_desc = __('A dropdown will be used if fewer items are present');
$strConfigForeignKeyMaxLimit_name = __('Foreign key limit');
$strConfigForm_Browse = __('Browse mode');
$strConfigForm_Browse_desc = __('Customize browse mode');
$strConfigForm_CodeGen = 'CodeGen';
$strConfigForm_CodeGen_desc = __('Customize default options');
$strConfigForm_Csv = __('CSV');
$strConfigForm_Csv_desc = __('Customize default options');
$strConfigForm_Developer = __('Developer');
$strConfigForm_Developer_desc = __('Settings for phpMyAdmin developers');
$strConfigForm_Edit = __('Edit mode');
$strConfigForm_Edit_desc = __('Customize edit mode');
$strConfigForm_Export = __('Export');
$strConfigForm_Export_defaults = __('Export defaults');
$strConfigForm_Export_defaults_desc = __('Customize default export options');
$strConfigForm_Features = __('Features');
$strConfigForm_General = __('General');
$strConfigForm_General_desc = __('Set some commonly used options');
$strConfigForm_Import = __('Import');
$strConfigForm_Import_defaults = __('Import defaults');
$strConfigForm_Import_defaults_desc = __('Customize default common import options');
$strConfigForm_Import_export = __('Import / export');
$strConfigForm_Import_export_desc = __('Set import and export directories and compression options');
$strConfigForm_Latex = __('LaTeX');
$strConfigForm_Latex_desc = __('Customize default options');
$strConfigForm_Left_databases = __('Databases');
$strConfigForm_Left_databases_desc = __('Databases display options');
$strConfigForm_Left_frame = __('Navigation frame');
$strConfigForm_Left_frame_desc = __('Customize appearance of the navigation frame');
$strConfigForm_Left_servers = __('Servers');
$strConfigForm_Left_servers_desc = __('Servers display options');
$strConfigForm_Left_tables = __('Tables');
$strConfigForm_Left_tables_desc = __('Tables display options');
$strConfigForm_Main_frame = __('Main frame');
$strConfigForm_Microsoft_Office = __('Microsoft Office');
$strConfigForm_Microsoft_Office_desc = __('Customize default options');
$strConfigForm_Open_Document = __('Open Document');
$strConfigForm_Open_Document_desc = __('Customize default options');
$strConfigForm_Other_core_settings = __('Other core settings');
$strConfigForm_Other_core_settings_desc = __('Settings that didn\'t fit enywhere else');
$strConfigForm_Page_titles = __('Page titles');
$strConfigForm_Page_titles_desc = __('Specify browser\'s title bar text. Refer to [a@Documentation.html#cfg_TitleTable]documentation[/a] for magic strings that can be used to get special values.');
$strConfigForm_Query_window = __('Query window');
$strConfigForm_Query_window_desc = __('Customize query window options');
$strConfigForm_Security = __('Security');
$strConfigForm_Security_desc = __('Please note that phpMyAdmin is just a user interface and its features do not limit MySQL');
$strConfigForm_Server = __('Basic settings');
$strConfigForm_Server_auth = __('Authentication');
$strConfigForm_Server_auth_desc = __('Authentication settings');
$strConfigForm_Server_config = __('Server configuration');
$strConfigForm_Server_config_desc = __('Advanced server configuration, do not change these options unless you know what they are for');
$strConfigForm_Server_desc = __('Enter server connection parameters');
$strConfigForm_Server_pmadb = __('Configuration storage');
$strConfigForm_Server_pmadb_desc = __('Configure phpMyAdmin configuration storage to gain access to additional features, see [a@Documentation.html#linked-tables]phpMyAdmin configuration storage[/a] in documentation');
$strConfigForm_Server_tracking = __('Changes tracking');
$strConfigForm_Server_tracking_desc = __('Tracking of changes made in database. Requires the phpMyAdmin configuration storage.');
$strConfigFormset_Export = __('Customize export options');
$strConfigFormset_Features = __('Features');
$strConfigFormset_Import = __('Customize import defaults');
$strConfigFormset_Left_frame = __('Customize navigation frame');
$strConfigFormset_Main_frame = __('Customize main frame');
$strConfigFormset_Sql_queries = __('SQL queries');
$strConfigForm_Sql = __('SQL');
$strConfigForm_Sql_box = __('SQL Query box');
$strConfigForm_Sql_box_desc = __('Customize links shown in SQL Query boxes');
$strConfigForm_Sql_desc = __('Customize default options');
$strConfigForm_Sql_queries = __('SQL queries');
$strConfigForm_Sql_queries_desc = __('SQL queries settings');
$strConfigForm_Sql_validator = __('SQL Validator');
$strConfigForm_Sql_validator_desc = __('If you wish to use the SQL Validator service, you should be aware that [strong]all SQL statements are stored anonymously for statistical purposes[/strong].[br][em][a@http://sqlvalidator.mimer.com/]Mimer SQL Validator[/a], Copyright 2002 Upright Database Technology. All rights reserved.[/em]');
$strConfigForm_Startup = __('Startup');
$strConfigForm_Startup_desc = __('Customize startup page');
$strConfigForm_Tabs = __('Tabs');
$strConfigForm_Tabs_desc = __('Choose how you want tabs to work');
$strConfigForm_Text_fields = __('Text fields');
$strConfigForm_Text_fields_desc = __('Customize text input fields');
$strConfigForm_Texy = __('Texy! text');
$strConfigForm_Texy_desc = __('Customize default options');
$strConfigForm_Warnings = __('Warnings');
$strConfigForm_Warnings_desc = __('Disable some of the warnings shown by phpMyAdmin');
$strConfigGZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/Gzip]gzip[/a] compression for import and export operations');
$strConfigGZipDump_name = __('GZip');
$strConfigIconvExtraParams_name = __('Extra parameters for iconv');
$strConfigIgnoreMultiSubmitErrors_desc = __('If enabled, phpMyAdmin continues computing multiple-statement queries even if one of the queries failed');
$strConfigIgnoreMultiSubmitErrors_name = __('Ignore multiple statement errors');
$strConfigImport_allow_interrupt_desc = __('Allow interrupt of import in case script detects it is close to time limit. This might be good way to import large files, however it can break transactions.');
$strConfigImport_allow_interrupt_name = __('Partial import: allow interrupt');
$strConfigImport_charset_name = __('Character set of the file');
$strConfigImport_csv_col_names_name = __('Lines terminated by');
$strConfigImport_csv_enclosed_name = __('Columns enclosed by');
$strConfigImport_csv_escaped_name = __('Columns escaped by');
$strConfigImport_csv_ignore_name = __('Do not abort on INSERT error');
$strConfigImport_csv_replace_name = __('Replace table data with file');
$strConfigImport_csv_terminated_name = __('Columns terminated by');
$strConfigImport_format_desc = __('Default format; be aware that this list depends on location (database, table) and only SQL is always available');
$strConfigImport_format_name = __('Format of imported file');
$strConfigImport_ldi_enclosed_name = __('Columns enclosed by');
$strConfigImport_ldi_escaped_name = __('Columns escaped by');
$strConfigImport_ldi_ignore_name = __('Do not abort on INSERT error');
$strConfigImport_ldi_local_option_name = __('Use LOCAL keyword');
$strConfigImport_ldi_replace_name = __('Replace table data with file');
$strConfigImport_ldi_terminated_name = __('Columns terminated by');
$strConfigImport_ods_col_names_name = __('Column names in first row');
$strConfigImport_ods_empty_rows_name = __('Do not import empty rows');
$strConfigImport_ods_recognize_currency_name = __('Import currencies ($5.00 to 5.00)');
$strConfigImport_ods_recognize_percentages_name = __('Import percentages as proper decimals (12.00% to .12)');
$strConfigImport_skip_queries_desc = __('Number of queries to skip from start');
$strConfigImport_skip_queries_name = __('Partial import: skip queries');
$strConfigImport_sql_compatibility_name = __('SQL compatibility mode');
$strConfigImport_sql_no_auto_value_on_zero_name = __('Do not use AUTO_INCREMENT for zero values');
$strConfigImport_xls_col_names_name = __('Column names in first row');
$strConfigImport_xlsx_col_names_name = __('Column names in first row');
$strConfigInitialSlidersState_name = __('Initial state for sliders');
$strConfigInsertRows_desc = __('How many rows can be inserted at one time');
$strConfigInsertRows_name = __('Number of inserted rows');
$strConfigLeftDefaultTabTable_name = __('Target for quick access icon');
$strConfigLeftDisplayLogo_desc = __('Show logo in left frame');
$strConfigLeftDisplayLogo_name = __('Display logo');
$strConfigLeftDisplayServers_desc = __('Display server choice at the top of the left frame');
$strConfigLeftDisplayServers_name = __('Display servers selection');
$strConfigLeftDisplayTableFilterMinimum_name = __('Minimum number of tables to display the table filter box');
$strConfigLeftFrameDBSeparator_desc = __('String that separates databases into different tree levels');
$strConfigLeftFrameDBSeparator_name = __('Database tree separator');
$strConfigLeftFrameDBTree_desc = __('Only light version; display databases in a tree (determined by the separator defined below)');
$strConfigLeftFrameDBTree_name = __('Display databases in a tree');
$strConfigLeftFrameLight_desc = __('Disable this if you want to see all databases at once');
$strConfigLeftFrameLight_name = __('Use light version');
$strConfigLeftFrameTableLevel_name = __('Maximum table tree depth');
$strConfigLeftFrameTableSeparator_desc = __('String that separates tables into different tree levels');
$strConfigLeftFrameTableSeparator_name = __('Table tree separator');
$strConfigLeftLogoLink_desc = __('URL where logo in the navigation frame will point to');
$strConfigLeftLogoLink_name = __('Logo link URL');
$strConfigLeftLogoLinkWindow_desc = __('Open the linked page in the main window ([kbd]main[/kbd]) or in a new one ([kbd]new[/kbd])');
$strConfigLeftLogoLinkWindow_name = __('Logo link target');
$strConfigLeftPointerEnable_desc = __('Highlight server under the mouse cursor');
$strConfigLeftPointerEnable_name = __('Enable highlighting');
$strConfigLeftRecentTable_desc = __('Maximum number of recently used tables; set 0 to disable');
$strConfigLeftRecentTable_name = __('Recently used tables');
$strConfigLightTabs_desc = __('Use less graphically intense tabs');
$strConfigLightTabs_name = __('Light tabs');
$strConfigLimitChars_desc = __('Maximum number of characters shown in any non-numeric column on browse view');
$strConfigLimitChars_name = __('Limit column characters');
$strConfigLoginCookieDeleteAll_desc = __('If TRUE, logout deletes cookies for all servers; when set to FALSE, logout only occurs for the current server. Setting this to FALSE makes it easy to forget to log out from other servers when connected to multiple servers.');
$strConfigLoginCookieDeleteAll_name = __('Delete all cookies on logout');
$strConfigLoginCookieRecall_desc = __('Define whether the previous login should be recalled or not in cookie authentication mode');
$strConfigLoginCookieRecall_name = __('Recall user name');
$strConfigLoginCookieStore_desc = __('Defines how long (in seconds) a login cookie should be stored in browser. The default of 0 means that it will be kept for the existing session only, and will be deleted as soon as you close the browser window. This is recommended for non-trusted environments.');
$strConfigLoginCookieStore_name = __('Login cookie store');
$strConfigLoginCookieValidity_desc = __('Define how long (in seconds) a login cookie is valid');
$strConfigLoginCookieValidity_name = __('Login cookie validity');
$strConfigLongtextDoubleTextarea_desc = __('Double size of textarea for LONGTEXT columns');
$strConfigLongtextDoubleTextarea_name = __('Bigger textarea for LONGTEXT');
$strConfigMainPageIconic_name = __('Use icons on main page');
$strConfigMaxCharactersInDisplayedSQL_desc = __('Maximum number of characters used when a SQL query is displayed');
$strConfigMaxCharactersInDisplayedSQL_name = __('Maximum displayed SQL length');
$strConfigMaxDbList_cmt = __('Users cannot set a higher value');
$strConfigMaxDbList_desc = __('Maximum number of databases displayed in left frame and database list');
$strConfigMaxDbList_name = __('Maximum databases');
$strConfigMaxRows_desc = __('Number of rows displayed when browsing a result set. If the result set contains more rows, &quot;Previous&quot; and &quot;Next&quot; links will be shown.');
$strConfigMaxRows_name = __('Maximum number of rows to display');
$strConfigMaxTableList_cmt = __('Users cannot set a higher value');
$strConfigMaxTableList_desc = __('Maximum number of tables displayed in table list');
$strConfigMaxTableList_name = __('Maximum tables');
$strConfigMcryptDisableWarning_desc = __('Disable the default warning that is displayed if mcrypt is missing for cookie authentication');
$strConfigMcryptDisableWarning_name = __('mcrypt warning');
$strConfigMemoryLimit_desc = __('The number of bytes a script is allowed to allocate, eg. [kbd]32M[/kbd] ([kbd]0[/kbd] for no limit)');
$strConfigMemoryLimit_name = __('Memory limit');
$strConfigRowActionLinks_desc = __('These are Edit, Copy and Delete links');
$strConfigRowActionLinks_name = __('Where to show the table row links');
$strConfigNaturalOrder_desc = __('Use natural order for sorting table and database names');
$strConfigNaturalOrder_name = __('Natural order');
$strConfigNavigationBarIconic_desc = __('Use only icons, only text or both');
$strConfigNavigationBarIconic_name = __('Iconic navigation bar');
$strConfigOBGzip_desc = __('use GZip output buffering for increased speed in HTTP transfers');
$strConfigOBGzip_name = __('GZip output buffering');
$strConfigOrder_desc = __('[kbd]SMART[/kbd] - i.e. descending order for columns of type TIME, DATE, DATETIME and TIMESTAMP, ascending order otherwise');
$strConfigOrder_name = __('Default sorting order');
$strConfigPersistentConnections_desc = __('Use persistent connections to MySQL databases');
$strConfigPersistentConnections_name = __('Persistent connections');
$strConfigPmaNoRelation_DisableWarning_desc = __('Disable the default warning that is displayed on the database details Structure page if any of the required tables for the phpMyAdmin configuration storage could not be found');
$strConfigPmaNoRelation_DisableWarning_name = __('Missing phpMyAdmin configuration storage tables');
$strConfigPropertiesIconic_desc = __('Use only icons, only text or both');
$strConfigPropertiesIconic_name = __('Iconic table operations');
$strConfigProtectBinary_desc = __('Disallow BLOB and BINARY columns from editing');
$strConfigProtectBinary_name = __('Protect binary columns');
$strConfigQueryHistoryDB_desc = __('Enable if you want DB-based query history (requires phpMyAdmin configuration storage). If disabled, this utilizes JS-routines to display query history (lost by window close).');
$strConfigQueryHistoryDB_name = __('Permanent query history');
$strConfigQueryHistoryMax_cmt = __('Users cannot set a higher value');
$strConfigQueryHistoryMax_desc = __('How many queries are kept in history');
$strConfigQueryHistoryMax_name = __('Query history length');
$strConfigQueryWindowDefTab_desc = __('Tab displayed when opening a new query window');
$strConfigQueryWindowDefTab_name = __('Default query window tab');
$strConfigQueryWindowHeight_desc = __('Query window height (in pixels)');
$strConfigQueryWindowHeight_name = __('Query window height');
$strConfigQueryWindowWidth_desc = __('Query window width (in pixels)');
$strConfigQueryWindowWidth_name = __('Query window width');
$strConfigRecodingEngine_desc = __('Select which functions will be used for character set conversion');
$strConfigRecodingEngine_name = __('Recoding engine');
$strConfigRememberSorting_desc = __('When browsing tables, the sorting of each table is remembered');
$strConfigRememberSorting_name = __('Remember table\'s sorting');
$strConfigRepeatCells_desc = __('Repeat the headers every X cells, [kbd]0[/kbd] deactivates this feature');
$strConfigRepeatCells_name = __('Repeat headers');
$strConfigReplaceHelpImg_desc = __('Show help button instead of Documentation text');
$strConfigReplaceHelpImg_name = __('Show help button');
$strConfigRestoreDefaultValue = __('Restore default value');
$strConfigSaveCellsAtOnce_name = __('Save all edited cells at once');
$strConfigSaveDir_desc = __('Directory where exports can be saved on server');
$strConfigSaveDir_name = __('Save directory');
$strConfigServers_AllowDeny_order_desc = __('Leave blank if not used');
$strConfigServers_AllowDeny_order_name = __('Host authorization order');
$strConfigServers_AllowDeny_rules_desc = __('Leave blank for defaults');
$strConfigServers_AllowDeny_rules_name = __('Host authorization rules');
$strConfigServers_AllowNoPassword_name = __('Allow logins without a password');
$strConfigServers_AllowRoot_name = __('Allow root login');
$strConfigServers_auth_http_realm_desc = __('HTTP Basic Auth Realm name to display when doing HTTP Auth');
$strConfigServers_auth_http_realm_name = __('HTTP Realm');
$strConfigServers_auth_swekey_config_desc = __('The path for the config file for [a@http://swekey.com]SweKey hardware authentication[/a] (not located in your document root; suggested: /etc/swekey.conf)');
$strConfigServers_auth_swekey_config_name = __('SweKey config file');
$strConfigServers_auth_type_desc = __('Authentication method to use');
$strConfigServers_auth_type_name = __('Authentication type');
$strConfigServers_bookmarktable_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma_bookmark[/kbd]');
$strConfigServers_bookmarktable_name = __('Bookmark table');
$strConfigServers_column_info_desc = __('Leave blank for no column comments/mime types, suggested: [kbd]pma_column_info[/kbd]');
$strConfigServers_column_info_name = __('Column information table');
$strConfigServers_compress_desc = __('Compress connection to MySQL server');
$strConfigServers_compress_name = __('Compress connection');
$strConfigServers_connect_type_desc = __('How to connect to server, keep [kbd]tcp[/kbd] if unsure');
$strConfigServers_connect_type_name = __('Connection type');
$strConfigServers_controlpass_name = __('Control user password');
$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a@http://wiki.phpmyadmin.net/pma/controluser]wiki[/a]');
$strConfigServers_controluser_name = __('Control user');
$strConfigServers_controlhost_desc = __('An alternate host to hold the configuration storage; leave blank to use the already defined host');
$strConfigServers_controlhost_name = __('Control host');
$strConfigServers_CountTables_desc = __('Count tables when showing database list');
$strConfigServers_CountTables_name = __('Count tables');
$strConfigServers_designer_coords_desc = __('Leave blank for no Designer support, suggested: [kbd]pma_designer_coords[/kbd]');
$strConfigServers_designer_coords_name = __('Designer table');
$strConfigServers_DisableIS_desc = __('More information on [a@http://sf.net/support/tracker.php?aid=1849494]PMA bug tracker[/a] and [a@http://bugs.mysql.com/19588]MySQL Bugs[/a]');
$strConfigServers_DisableIS_name = __('Disable use of INFORMATION_SCHEMA');
$strConfigServers_extension_desc = __('What PHP extension to use; you should use mysqli if supported');
$strConfigServers_extension_name = __('PHP extension to use');
$strConfigServers_hide_db_desc = __('Hide databases matching regular expression (PCRE)');
$strConfigServers_hide_db_name = __('Hide databases');
$strConfigServers_history_desc = __('Leave blank for no SQL query history support, suggested: [kbd]pma_history[/kbd]');
$strConfigServers_history_name = __('SQL query history table');
$strConfigServers_host_desc = __('Hostname where MySQL server is running');
$strConfigServers_host_name = __('Server hostname');
$strConfigServers_LogoutURL_name = __('Logout URL');
$strConfigServers_MaxTableUiprefs_desc = __('Limits number of table preferences which are stored in database, the oldest records are automatically removed');
$strConfigServers_MaxTableUiprefs_name = __('Maximal number of table preferences to store');
$strConfigServers_nopassword_desc = __('Try to connect without password');
$strConfigServers_nopassword_name = __('Connect without password');
$strConfigServers_only_db_desc = __('You can use MySQL wildcard characters (% and _), escape them if you want to use their literal instances, i.e. use [kbd]\'my\_db\'[/kbd] and not [kbd]\'my_db\'[/kbd]. Using this option you can sort database list, just enter their names in order and use [kbd]*[/kbd] at the end to show the rest in alphabetical order.');
$strConfigServers_only_db_name = __('Show only listed databases');
$strConfigServers_password_desc = __('Leave empty if not using config auth');
$strConfigServers_password_name = __('Password for config auth');
$strConfigServers_pdf_pages_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma_pdf_pages[/kbd]');
$strConfigServers_pdf_pages_name = __('PDF schema: pages table');
$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a@http://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]');
$strConfigServers_pmadb_name = __('Database name');
$strConfigServers_port_desc = __('Port on which MySQL server is listening, leave empty for default');
$strConfigServers_port_name = __('Server port');
$strConfigServers_recent_desc = __('Leave blank for no "persistent" recently used tables across sessions, suggested: [kbd]pma_recent[/kbd]');
$strConfigServers_recent_name = __('Recently used table');
$strConfigServers_relation_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma_relation[/kbd]');
$strConfigServers_relation_name = __('Relation table');
$strConfigServers_ShowDatabasesCommand_desc = __('SQL command to fetch available databases');
$strConfigServers_ShowDatabasesCommand_name = __('SHOW DATABASES command');
$strConfigServers_SignonSession_desc = __('See [a@http://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example');
$strConfigServers_SignonSession_name = __('Signon session name');
$strConfigServers_SignonURL_name = __('Signon URL');
$strConfigServers_socket_desc = __('Socket on which MySQL server is listening, leave empty for default');
$strConfigServers_socket_name = __('Server socket');
$strConfigServers_ssl_desc = __('Enable SSL for connection to MySQL server');
$strConfigServers_ssl_name = __('Use SSL');
$strConfigServers_table_coords_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma_table_coords[/kbd]');
$strConfigServers_table_coords_name = __('PDF schema: table coordinates');
$strConfigServers_table_info_desc = __('Table to describe the display columns, leave blank for no support; suggested: [kbd]pma_table_info[/kbd]');
$strConfigServers_table_info_name = __('Display columns table');
$strConfigServers_table_uiprefs_desc = __('Leave blank for no "persistent" tables\'UI preferences across sessions, suggested: [kbd]pma_table_uiprefs[/kbd]');
$strConfigServers_table_uiprefs_name = __('UI preferences table');
$strConfigServers_tracking_add_drop_database_desc = __('Whether a DROP DATABASE IF EXISTS statement will be added as first line to the log when creating a database.');
$strConfigServers_tracking_add_drop_database_name = __('Add DROP DATABASE');
$strConfigServers_tracking_add_drop_table_desc = __('Whether a DROP TABLE IF EXISTS statement will be added as first line to the log when creating a table.');
$strConfigServers_tracking_add_drop_table_name = __('Add DROP TABLE');
$strConfigServers_tracking_add_drop_view_desc = __('Whether a DROP VIEW IF EXISTS statement will be added as first line to the log when creating a view.');
$strConfigServers_tracking_add_drop_view_name = __('Add DROP VIEW');
$strConfigServers_tracking_default_statements_desc = __('Defines the list of statements the auto-creation uses for new versions.');
$strConfigServers_tracking_default_statements_name = __('Statements to track');
$strConfigServers_tracking_desc = __('Leave blank for no SQL query tracking support, suggested: [kbd]pma_tracking[/kbd]');
$strConfigServers_tracking_name = __('SQL query tracking table');
$strConfigServers_tracking_version_auto_create_desc = __('Whether the tracking mechanism creates versions for tables and views automatically.');
$strConfigServers_tracking_version_auto_create_name = __('Automatically create versions');
$strConfigServers_userconfig_desc = __('Leave blank for no user preferences storage in database, suggested: [kbd]pma_userconfig[/kbd]');
$strConfigServers_userconfig_name = __('User preferences storage table');
$strConfigServers_user_desc = __('Leave empty if not using config auth');
$strConfigServers_user_name = __('User for config auth');
$strConfigServers_verbose_check_desc = __('Disable if you know that your pma_* tables are up to date. This prevents compatibility checks and thereby increases performance');
$strConfigServers_verbose_check_name = __('Verbose check');
$strConfigServers_verbose_desc = __('A user-friendly description of this server. Leave blank to display the hostname instead.');
$strConfigServers_verbose_name = __('Verbose name of this server');
$strConfigShowAll_desc = __('Whether a user should be displayed a &quot;show all (rows)&quot; button');
$strConfigShowAll_name = __('Allow to display all the rows');
$strConfigShowChgPassword_desc = __('Please note that enabling this has no effect with [kbd]config[/kbd] authentication mode because the password is hard coded in the configuration file; this does not limit the ability to execute the same command directly');
$strConfigShowChgPassword_name = __('Show password change form');
$strConfigShowCreateDb_name = __('Show create database form');
$strConfigShowDisplayDirection_desc = __('Defines whether or not type display direction option is shown when browsing a table');
$strConfigShowDisplayDirection_name = __('Show display direction');
$strConfigShowFieldTypesInDataEditView_desc = __('Defines whether or not type fields should be initially displayed in edit/insert mode');
$strConfigShowFieldTypesInDataEditView_name = __('Show field types');
$strConfigShowFunctionFields_desc = __('Display the function fields in edit/insert mode');
$strConfigShowFunctionFields_name = __('Show function fields');
$strConfigShowHint_desc = __('Whether to show hint or not');
$strConfigShowHint_name = __('Show hint');
$strConfigShowPhpInfo_desc = __('Shows link to [a@http://php.net/manual/function.phpinfo.php]phpinfo()[/a] output');
$strConfigShowPhpInfo_name = __('Show phpinfo() link');
$strConfigShowServerInfo_name = __('Show detailed MySQL server information');
$strConfigShowSQL_desc = __('Defines whether SQL queries generated by phpMyAdmin should be displayed');
$strConfigShowSQL_name = __('Show SQL queries');
$strConfigRetainQueryBox_desc = __('Defines whether the query box should stay on-screen after its submission');
$strConfigRetainQueryBox_name = __('Retain query box');
$strConfigShowStats_desc = __('Allow to display database and table statistics (eg. space usage)');
$strConfigShowStats_name = __('Show statistics');
$strConfigShowTooltipAliasDB_desc = __('If tooltips are enabled and a database comment is set, this will flip the comment and the real name');
$strConfigShowTooltipAliasDB_name = __('Display database comment instead of its name');
$strConfigShowTooltipAliasTB_desc = __('When setting this to [kbd]nested[/kbd], the alias of the table name is only used to split/nest the tables according to the $cfg[\'LeftFrameTableSeparator\'] directive, so only the folder is called like the alias, the table name itself stays unchanged');
$strConfigShowTooltipAliasTB_name = __('Display table comment instead of its name');
$strConfigShowTooltip_name = __('Display table comments in tooltips');
$strConfigSkipLockedTables_desc = __('Mark used tables and make it possible to show databases with locked tables');
$strConfigSkipLockedTables_name = __('Skip locked tables');
$strConfigSQLQuery_Edit_name = __('Edit');
$strConfigSQLQuery_Explain_name = __('Explain SQL');
$strConfigSQLQuery_Refresh_name = __('Refresh');
$strConfigSQLQuery_ShowAsPHP_name = __('Create PHP Code');
$strConfigSQLQuery_Validate_desc = __('Requires SQL Validator to be enabled');
$strConfigSQLQuery_Validate_name = __('Validate SQL');
$strConfigSQLValidator_password_name = __('Password');
$strConfigSQLValidator_use_desc = __('[strong]Warning:[/strong] requires PHP SOAP extension or PEAR SOAP to be installed');
$strConfigSQLValidator_use_name = __('Enable SQL Validator');
$strConfigSQLValidator_username_desc = __('If you have a custom username, specify it here (defaults to [kbd]anonymous[/kbd])');
$strConfigSQLValidator_username_name = __('Username');
$strConfigSuggestDBName_desc = __('Suggest a database name on the &quot;Create Database&quot; form (if possible) or keep the text field empty');
$strConfigSuggestDBName_name = __('Suggest new database name');
$strConfigSuhosinDisableWarning_desc = __('A warning is displayed on the main page if Suhosin is detected');
$strConfigSuhosinDisableWarning_name = __('Suhosin warning');
$strConfigTextareaCols_desc = __('Textarea size (columns) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)');
$strConfigTextareaCols_name = __('Textarea columns');
$strConfigTextareaRows_desc = __('Textarea size (rows) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)');
$strConfigTextareaRows_name = __('Textarea rows');
$strConfigTitleDatabase_desc = __('Title of browser window when a database is selected');
$strConfigTitleDatabase_name = __('Database');
$strConfigTitleDefault_desc = __('Title of browser window when nothing is selected');
$strConfigTitleDefault_name = __('Default title');
$strConfigTitleServer_desc = __('Title of browser window when a server is selected');
$strConfigTitleServer_name = __('Server');
$strConfigTitleTable_desc = __('Title of browser window when a table is selected');
$strConfigTitleTable_name = __('Table');
$strConfigTrustedProxies_desc = __('Input proxies as [kbd]IP: trusted HTTP header[/kbd]. The following example specifies that phpMyAdmin should trust a HTTP_X_FORWARDED_FOR (X-Forwarded-For) header coming from the proxy 1.2.3.4:[br][kbd]1.2.3.4: HTTP_X_FORWARDED_FOR[/kbd]');
$strConfigTrustedProxies_name = __('List of trusted proxies for IP allow/deny');
$strConfigUploadDir_desc = __('Directory on server where you can upload files for import');
$strConfigUploadDir_name = __('Upload directory');
$strConfigUseDbSearch_desc = __('Allow for searching inside the entire database');
$strConfigUseDbSearch_name = __('Use database search');
$strConfigUserprefsDeveloperTab_desc = __('When disabled, users cannot set any of the options below, regardless of the checkbox on the right');
$strConfigUserprefsDeveloperTab_name = __('Enable the Developer tab in settings');
$strConfigVerboseMultiSubmit_desc = __('Show affected rows of each statement on multiple-statement queries. See libraries/import.lib.php for defaults on how many queries a statement may contain.');
$strConfigVerboseMultiSubmit_name = __('Verbose multiple statements');
$strConfigVersionCheckLink = __('Check for latest version');
$strConfigVersionCheck_desc = __('Enables check for latest version on main phpMyAdmin page');
$strConfigVersionCheck_name = __('Version check');
$strConfigZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/ZIP_(file_format)]ZIP[/a] compression for import and export operations');
$strConfigZipDump_name = __('ZIP');
?>

View File

@ -0,0 +1,372 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* List of avaible forms, each form is described as an array of fields to display.
* Fields MUST have their counterparts in the $cfg array.
*
* There are two possible notations:
* $forms['Form group']['Form name'] = array('Servers' => array(1 => array('host')));
* can be written as
* $forms['Form group']['Form name'] = array('Servers/1/host');
*
* You can assign default values set by special button ("set value: ..."), eg.:
* 'Servers/1/pmadb' => 'phpmyadmin'
*
* To group options, use:
* ':group:' . __('group name') // just define a group
* or
* 'option' => ':group' // group starting from this option
* End group blocks with:
* ':group:end'
*
* @package PhpMyAdmin-setup
*/
$forms = array();
$forms['_config.php'] = array(
'DefaultLang',
'ServerDefault');
$forms['Servers']['Server'] = array('Servers' => array(1 => array(
'verbose',
'host',
'port',
'socket',
'ssl',
'connect_type',
'extension',
'compress',
'nopassword')));
$forms['Servers']['Server_auth'] = array('Servers' => array(1 => array(
'auth_type',
':group:' . __('Config authentication'),
'user',
'password',
':group:end',
':group:' . __('Cookie authentication'),
'auth_swekey_config' => './swekey.conf',
':group:end',
':group:' . __('HTTP authentication'),
'auth_http_realm',
':group:end',
':group:' . __('Signon authentication'),
'SignonSession',
'SignonURL',
'LogoutURL')));
$forms['Servers']['Server_config'] = array('Servers' => array(1 => array(
'only_db',
'hide_db',
'AllowRoot',
'AllowNoPassword',
'DisableIS',
'AllowDeny/order',
'AllowDeny/rules',
'ShowDatabasesCommand',
'CountTables')));
$forms['Servers']['Server_pmadb'] = array('Servers' => array(1 => array(
'pmadb' => 'phpmyadmin',
'controlhost',
'controluser',
'controlpass',
'verbose_check',
'bookmarktable' => 'pma_bookmark',
'relation' => 'pma_relation',
'userconfig' => 'pma_userconfig',
'table_info' => 'pma_table_info',
'column_info' => 'pma_column_info',
'history' => 'pma_history',
'recent' => 'pma_recent',
'table_uiprefs' => 'pma_table_uiprefs',
'tracking' => 'pma_tracking',
'table_coords' => 'pma_table_coords',
'pdf_pages' => 'pma_pdf_pages',
'designer_coords' => 'pma_designer_coords',
'MaxTableUiprefs' => 100)));
$forms['Servers']['Server_tracking'] = array('Servers' => array(1 => array(
'tracking_version_auto_create',
'tracking_default_statements',
'tracking_add_drop_view',
'tracking_add_drop_table',
'tracking_add_drop_database',
)));
$forms['Features']['Import_export'] = array(
'UploadDir',
'SaveDir',
'RecodingEngine' => ':group',
'IconvExtraParams',
':group:end',
'ZipDump',
'GZipDump',
'BZipDump',
'CompressOnFly');
$forms['Features']['Security'] = array(
'blowfish_secret',
'ForceSSL',
'CheckConfigurationPermissions',
'TrustedProxies',
'AllowUserDropDatabase',
'AllowArbitraryServer',
'LoginCookieRecall',
'LoginCookieValidity',
'LoginCookieStore',
'LoginCookieDeleteAll');
$forms['Features']['Page_titles'] = array(
'TitleDefault',
'TitleTable',
'TitleDatabase',
'TitleServer');
$forms['Features']['Warnings'] = array(
'PmaNoRelation_DisableWarning',
'SuhosinDisableWarning',
'McryptDisableWarning');
$forms['Features']['Developer'] = array(
'UserprefsDeveloperTab',
'Error_Handler/display',
'Error_Handler/gather',
'DBG/sql');
$forms['Features']['Other_core_settings'] = array(
'AjaxEnable',
'VersionCheck',
'NaturalOrder',
'InitialSlidersState',
'ErrorIconic',
'ReplaceHelpImg',
'MaxDbList',
'MaxTableList',
'ShowHint',
'OBGzip',
'PersistentConnections',
'ExecTimeLimit',
'MemoryLimit',
'SkipLockedTables',
'DisableMultiTableMaintenance',
'UseDbSearch',
'AllowThirdPartyFraming');
$forms['Sql_queries']['Sql_queries'] = array(
'ShowSQL',
'Confirm',
'QueryHistoryDB',
'QueryHistoryMax',
'IgnoreMultiSubmitErrors',
'VerboseMultiSubmit',
'MaxCharactersInDisplayedSQL',
'EditInWindow',
//'QueryWindowWidth', // overridden in theme
//'QueryWindowHeight',
'QueryWindowDefTab',
'RetainQueryBox');
$forms['Sql_queries']['Sql_box'] = array('SQLQuery' => array(
'Edit',
'Explain',
'ShowAsPHP',
'Validate',
'Refresh'));
$forms['Sql_queries']['Sql_validator'] = array('SQLValidator' => array(
'use',
'username',
'password'));
$forms['Left_frame']['Left_frame'] = array(
'LeftFrameLight',
'LeftDisplayLogo',
'LeftLogoLink',
'LeftLogoLinkWindow',
'LeftPointerEnable',
'LeftRecentTable');
$forms['Left_frame']['Left_servers'] = array(
'LeftDisplayServers',
'DisplayServersList');
$forms['Left_frame']['Left_databases'] = array(
'DisplayDatabasesList',
'LeftFrameDBTree',
'LeftFrameDBSeparator',
'ShowTooltipAliasDB');
$forms['Left_frame']['Left_tables'] = array(
'LeftDisplayTableFilterMinimum',
'LeftDefaultTabTable',
'LeftFrameTableSeparator',
'LeftFrameTableLevel',
'ShowTooltip',
'ShowTooltipAliasTB');
$forms['Main_frame']['Startup'] = array(
'MainPageIconic',
'ShowCreateDb' => ':group',
'SuggestDBName',
':group:end',
'ShowStats',
'ShowServerInfo',
'ShowPhpInfo',
'ShowChgPassword');
$forms['Main_frame']['Browse'] = array(
'NavigationBarIconic',
'ShowAll',
'MaxRows',
'Order',
'BrowsePointerEnable',
'BrowseMarkerEnable',
'SaveCellsAtOnce',
'ShowDisplayDirection',
'RepeatCells',
'LimitChars',
'RowActionLinks',
'DefaultDisplay',
'RememberSorting');
$forms['Main_frame']['Edit'] = array(
'ProtectBinary',
'ShowFunctionFields',
'ShowFieldTypesInDataEditView',
'CharEditing',
'MinSizeForInputField',
'MaxSizeForInputField',
'CharTextareaCols',
'CharTextareaRows',
'TextareaCols',
'TextareaRows',
'LongtextDoubleTextarea',
'InsertRows',
'ForeignKeyDropdownOrder',
'ForeignKeyMaxLimit');
$forms['Main_frame']['Tabs'] = array(
'LightTabs',
'PropertiesIconic',
'DefaultTabServer',
'DefaultTabDatabase',
'DefaultTabTable',
'QueryWindowDefTab');
$forms['Import']['Import_defaults'] = array('Import' => array(
'format',
'charset',
'allow_interrupt',
'skip_queries'));
$forms['Import']['Sql'] = array('Import' => array(
'sql_compatibility',
'sql_no_auto_value_on_zero'));
$forms['Import']['Csv'] = array('Import' => array(
':group:' . __('CSV'),
'csv_replace',
'csv_ignore',
'csv_terminated',
'csv_enclosed',
'csv_escaped',
'csv_col_names',
':group:end',
':group:' . __('CSV using LOAD DATA'),
'ldi_replace',
'ldi_ignore',
'ldi_terminated',
'ldi_enclosed',
'ldi_escaped',
'ldi_local_option',
':group:end'));
$forms['Import']['Open_Document'] = array('Import' => array(
':group:' . __('Open Document Spreadsheet'),
'ods_col_names',
'ods_empty_rows',
'ods_recognize_percentages',
'ods_recognize_currency'));
$forms['Export']['Export_defaults'] = array('Export' => array(
'method',
':group:' . __('Quick'),
'quick_export_onserver',
'quick_export_onserver_overwrite',
':group:end',
':group:' . __('Custom'),
'format',
'compression',
'charset',
'asfile' => ':group',
'onserver',
'onserver_overwrite',
':group:end',
'remember_file_template',
'file_template_table',
'file_template_database',
'file_template_server'));
$forms['Export']['Sql'] = array('Export' => array(
'sql_include_comments' => ':group',
'sql_dates',
'sql_relation',
'sql_mime',
':group:end',
'sql_use_transaction',
'sql_disable_fk',
'sql_compatibility',
':group:' . __('Database export options'),
'sql_drop_database',
'sql_structure_or_data',
':group:end',
':group:' . __('Structure'),
'sql_drop_table',
'sql_procedure_function',
'sql_create_table_statements' => ':group',
'sql_if_not_exists',
'sql_auto_increment',
':group:end',
'sql_backquotes',
':group:end',
':group:' . __('Data'),
'sql_delayed',
'sql_ignore',
'sql_type',
'sql_insert_syntax',
'sql_max_query_size',
'sql_hex_for_blob',
'sql_utc_time'));
$forms['Export']['CodeGen'] = array('Export' => array(
'codegen_format'));
$forms['Export']['Csv'] = array('Export' => array(
':group:' . __('CSV'),
'csv_separator',
'csv_enclosed',
'csv_escaped',
'csv_terminated',
'csv_null',
'csv_removeCRLF',
'csv_columns',
':group:end',
':group:' . __('CSV for MS Excel'),
'excel_null',
'excel_removeCRLF',
'excel_columns',
'excel_edition'));
$forms['Export']['Latex'] = array('Export' => array(
'latex_caption',
'latex_structure_or_data',
':group:' . __('Structure'),
'latex_structure_caption',
'latex_structure_continued_caption',
'latex_structure_label',
'latex_relation',
'latex_comments',
'latex_mime',
':group:end',
':group:' . __('Data'),
'latex_columns',
'latex_data_caption',
'latex_data_continued_caption',
'latex_data_label',
'latex_null'));
$forms['Export']['Microsoft_Office'] = array('Export' => array(
':group:' . __('Microsoft Word 2000'),
'htmlword_structure_or_data',
'htmlword_null',
'htmlword_columns'));
$forms['Export']['Open_Document'] = array('Export' => array(
':group:' . __('Open Document Spreadsheet'),
'ods_columns',
'ods_null',
':group:end',
':group:' . __('Open Document Text'),
'odt_structure_or_data',
':group:' . __('Structure'),
'odt_relation',
'odt_comments',
'odt_mime',
':group:end',
':group:' . __('Data'),
'odt_columns',
'odt_null'));
$forms['Export']['Texy'] = array('Export' => array(
'texytext_structure_or_data',
':group:' . __('Data'),
'texytext_null',
'texytext_columns'));
?>

View File

@ -0,0 +1,270 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* List of avaible forms, each form is described as an array of fields to display.
* Fields MUST have their counterparts in the $cfg array.
*
* To define form field, use the notatnion below:
* $forms['Form group']['Form name'] = array('Option/path');
*
* You can assign default values set by special button ("set value: ..."), eg.:
* 'Servers/1/pmadb' => 'phpmyadmin'
*
* To group options, use:
* ':group:' . __('group name') // just define a group
* or
* 'option' => ':group' // group starting from this option
* End group blocks with:
* ':group:end'
*
* @package PhpMyAdmin
*/
$forms = array();
$forms['Features']['General'] = array(
'AjaxEnable',
'VersionCheck',
'NaturalOrder',
'InitialSlidersState',
'ErrorIconic',
'LoginCookieValidity',
'ReplaceHelpImg',
'Servers/1/only_db', // saves to Server/only_db
'Servers/1/hide_db', // saves to Server/hide_db
'SkipLockedTables',
'DisableMultiTableMaintenance',
'MaxDbList',
'MaxTableList',
'ShowHint');
$forms['Features']['Text_fields'] = array(
'CharEditing',
'MinSizeForInputField',
'MaxSizeForInputField',
'CharTextareaCols',
'CharTextareaRows',
'TextareaCols',
'TextareaRows',
'LongtextDoubleTextarea');
$forms['Features']['Page_titles'] = array(
'TitleDefault',
'TitleTable',
'TitleDatabase',
'TitleServer');
$forms['Features']['Warnings'] = array(
'PmaNoRelation_DisableWarning',
'SuhosinDisableWarning',
'McryptDisableWarning');
// settings from this form are treated specially, see prefs_forms.php and user_preferences.lib.php
$forms['Features']['Developer'] = array(
'Error_Handler/display',
'Error_Handler/gather',
'DBG/sql');
$forms['Sql_queries']['Sql_queries'] = array(
'ShowSQL',
'Confirm',
'QueryHistoryMax',
'IgnoreMultiSubmitErrors',
'VerboseMultiSubmit',
'MaxCharactersInDisplayedSQL',
'EditInWindow',
//'QueryWindowWidth', // overridden in theme
//'QueryWindowHeight',
'QueryWindowDefTab',
'RetainQueryBox');
$forms['Sql_queries']['Sql_box'] = array(
'SQLQuery/Edit',
'SQLQuery/Explain',
'SQLQuery/ShowAsPHP',
'SQLQuery/Validate',
'SQLQuery/Refresh');
$forms['Left_frame']['Left_frame'] = array(
'LeftFrameLight',
'LeftDisplayLogo',
'LeftLogoLink',
'LeftLogoLinkWindow',
'LeftPointerEnable',
'LeftRecentTable');
$forms['Left_frame']['Left_databases'] = array(
'DisplayDatabasesList',
'LeftFrameDBTree',
'LeftFrameDBSeparator',
'ShowTooltipAliasDB');
$forms['Left_frame']['Left_tables'] = array(
'LeftDisplayTableFilterMinimum',
'LeftDefaultTabTable',
'LeftFrameTableSeparator',
'LeftFrameTableLevel',
'ShowTooltip',
'ShowTooltipAliasTB');
$forms['Main_frame']['Startup'] = array(
'MainPageIconic',
'ShowCreateDb' => ':group',
'SuggestDBName',
':group:end',
'ShowStats',
'ShowServerInfo');
$forms['Main_frame']['Browse'] = array(
'NavigationBarIconic',
'PropertiesIconic',
'ShowAll',
'MaxRows',
'Order',
'DisplayBinaryAsHex',
'BrowsePointerEnable',
'BrowseMarkerEnable',
'SaveCellsAtOnce',
'ShowDisplayDirection',
'RepeatCells',
'LimitChars',
'RowActionLinks',
'DefaultDisplay',
'RememberSorting');
$forms['Main_frame']['Edit'] = array(
'ProtectBinary',
'ShowFunctionFields',
'ShowFieldTypesInDataEditView',
'InsertRows',
'ForeignKeyDropdownOrder',
'ForeignKeyMaxLimit');
$forms['Main_frame']['Tabs'] = array(
'LightTabs',
'DefaultTabServer',
'DefaultTabDatabase',
'DefaultTabTable');
$forms['Import']['Import_defaults'] = array(
'Import/format',
'Import/charset',
'Import/allow_interrupt',
'Import/skip_queries');
$forms['Import']['Sql'] = array(
'Import/sql_compatibility',
'Import/sql_no_auto_value_on_zero');
$forms['Import']['Csv'] = array(
':group:' . __('CSV'),
'Import/csv_replace',
'Import/csv_ignore',
'Import/csv_terminated',
'Import/csv_enclosed',
'Import/csv_escaped',
'Import/csv_col_names',
':group:end',
':group:' . __('CSV using LOAD DATA'),
'Import/ldi_replace',
'Import/ldi_ignore',
'Import/ldi_terminated',
'Import/ldi_enclosed',
'Import/ldi_escaped',
'Import/ldi_local_option');
$forms['Import']['Open_Document'] = array(
':group:' . __('Open Document Spreadsheet'),
'Import/ods_col_names',
'Import/ods_empty_rows',
'Import/ods_recognize_percentages',
'Import/ods_recognize_currency');
$forms['Export']['Export_defaults'] = array(
'Export/method',
':group:' . __('Quick'),
'Export/quick_export_onserver',
'Export/quick_export_onserver_overwrite',
':group:end',
':group:' . __('Custom'),
'Export/format',
'Export/compression',
'Export/charset',
'Export/asfile' => ':group',
'Export/onserver',
'Export/onserver_overwrite',
':group:end',
'Export/file_template_table',
'Export/file_template_database',
'Export/file_template_server');
$forms['Export']['Sql'] = array(
'Export/sql_include_comments' => ':group',
'Export/sql_dates',
'Export/sql_relation',
'Export/sql_mime',
':group:end',
'Export/sql_use_transaction',
'Export/sql_disable_fk',
'Export/sql_compatibility',
':group:' . __('Database export options'),
'Export/sql_drop_database',
'Export/sql_structure_or_data',
':group:end',
':group:' . __('Structure'),
'Export/sql_drop_table',
'Export/sql_procedure_function',
'Export/sql_create_table_statements' => ':group',
'Export/sql_if_not_exists',
'Export/sql_auto_increment',
':group:end',
'Export/sql_backquotes',
':group:end',
':group:' . __('Data'),
'Export/sql_delayed',
'Export/sql_ignore',
'Export/sql_type',
'Export/sql_insert_syntax',
'Export/sql_max_query_size',
'Export/sql_hex_for_blob',
'Export/sql_utc_time');
$forms['Export']['CodeGen'] = array(
'Export/codegen_format');
$forms['Export']['Csv'] = array(
':group:' . __('CSV'),
'Export/csv_separator',
'Export/csv_enclosed',
'Export/csv_escaped',
'Export/csv_terminated',
'Export/csv_null',
'Export/csv_removeCRLF',
'Export/csv_columns',
':group:end',
':group:' . __('CSV for MS Excel'),
'Export/excel_null',
'Export/excel_removeCRLF',
'Export/excel_columns',
'Export/excel_edition');
$forms['Export']['Latex'] = array(
'Export/latex_caption',
'Export/latex_structure_or_data',
':group:' . __('Structure'),
'Export/latex_structure_caption',
'Export/latex_structure_continued_caption',
'Export/latex_structure_label',
'Export/latex_relation',
'Export/latex_comments',
'Export/latex_mime',
':group:end',
':group:' . __('Data'),
'Export/latex_columns',
'Export/latex_data_caption',
'Export/latex_data_continued_caption',
'Export/latex_data_label',
'Export/latex_null');
$forms['Export']['Microsoft_Office'] = array(
':group:' . __('Microsoft Word 2000'),
'Export/htmlword_structure_or_data',
'Export/htmlword_null',
'Export/htmlword_columns');
$forms['Export']['Open_Document'] = array(
':group:' . __('Open Document Spreadsheet'),
'Export/ods_columns',
'Export/ods_null',
':group:end',
':group:' . __('Open Document Text'),
'Export/odt_structure_or_data',
':group:' . __('Structure'),
'Export/odt_relation',
'Export/odt_comments',
'Export/odt_mime',
':group:end',
':group:' . __('Data'),
'Export/odt_columns',
'Export/odt_null');
$forms['Export']['Texy'] = array(
'Export/texytext_structure_or_data',
':group:' . __('Data'),
'Export/texytext_null',
'Export/texytext_columns');
?>

View File

@ -0,0 +1,481 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Various validation functions
*
* Validation function takes two argument: id for which it is called
* and array of fields' values (usually values for entire formset, as defined
* in forms.inc.php).
* The function must always return an array with an error (or error array)
* assigned to a form element (formset name or field path). Even if there are
* no errors, key must be set with an empty value.
*
* Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
*
* @package PhpMyAdmin
*/
/**
* Returns validator list
*
* @return array
*/
function PMA_config_get_validators()
{
static $validators = null;
if ($validators === null) {
$cf = ConfigFile::getInstance();
$validators = $cf->getDbEntry('_validators', array());
if (!defined('PMA_SETUP')) {
// not in setup script: load additional validators for user preferences
// we need oryginal config values not overwritten by user preferences, creating a new PMA_Config
// instance is a better idea than hacking into its code
$org_cfg = $cf->getOrgConfigObj();
$uvs = $cf->getDbEntry('_userValidators', array());
foreach ($uvs as $field => $uv_list) {
$uv_list = (array)$uv_list;
foreach ($uv_list as &$uv) {
if (!is_array($uv)) {
continue;
}
for ($i = 1; $i < count($uv); $i++) {
if (substr($uv[$i], 0, 6) == 'value:') {
$uv[$i] = PMA_array_read(substr($uv[$i], 6), $org_cfg->settings);
}
}
}
$validators[$field] = isset($validators[$field])
? array_merge((array)$validators[$field], $uv_list)
: $uv_list;
}
}
}
return $validators;
}
/**
* Runs validation $validator_id on values $values and returns error list.
*
* Return values:
* o array, keys - field path or formset id, values - array of errors
* when $isPostSource is true values is an empty array to allow for error list
* cleanup in HTML documen
* o false - when no validators match name(s) given by $validator_id
*
* @param string|array $validator_id
* @param array $values
* @param bool $isPostSource tells whether $values are directly from POST request
* @return bool|array
*/
function PMA_config_validate($validator_id, &$values, $isPostSource)
{
// find validators
$validator_id = (array) $validator_id;
$validators = PMA_config_get_validators();
$vids = array();
$cf = ConfigFile::getInstance();
foreach ($validator_id as &$vid) {
$vid = $cf->getCanonicalPath($vid);
if (isset($validators[$vid])) {
$vids[] = $vid;
}
}
if (empty($vids)) {
return false;
}
// create argument list with canonical paths and remember path mapping
$arguments = array();
$key_map = array();
foreach ($values as $k => $v) {
$k2 = $isPostSource ? str_replace('-', '/', $k) : $k;
$k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2;
$key_map[$k2] = $k;
$arguments[$k2] = $v;
}
// validate
$result = array();
foreach ($vids as $vid) {
// call appropriate validation functions
foreach ((array)$validators[$vid] as $validator) {
$vdef = (array) $validator;
$vname = array_shift($vdef);
$args = array_merge(array($vid, &$arguments), $vdef);
$r = call_user_func_array($vname, $args);
// merge results
if (is_array($r)) {
foreach ($r as $key => $error_list) {
// skip empty values if $isPostSource is false
if (!$isPostSource && empty($error_list)) {
continue;
}
if (!isset($result[$key])) {
$result[$key] = array();
}
$result[$key] = array_merge($result[$key], (array)$error_list);
}
}
}
}
// restore original paths
$new_result = array();
foreach ($result as $k => $v) {
$k2 = isset($key_map[$k]) ? $key_map[$k] : $k;
$new_result[$k2] = $v;
}
return empty($new_result) ? true : $new_result;
}
/**
* Empty error handler, used to temporarily restore PHP internal error handler
*
* @return bool
*/
function PMA_null_error_handler()
{
return false;
}
/**
* Ensures that $php_errormsg variable will be registered in case of an error
* and enables output buffering (when $start = true).
* Called with $start = false disables output buffering end restores
* html_errors and track_errors.
*
* @param boolean $start
*/
function test_php_errormsg($start = true)
{
static $old_html_errors, $old_track_errors, $old_error_reporting;
static $old_display_errors;
if ($start) {
$old_html_errors = ini_get('html_errors');
$old_track_errors = ini_get('track_errors');
$old_display_errors = ini_get('display_errors');
$old_error_reporting = error_reporting(E_ALL);
ini_set('html_errors', false);
ini_set('track_errors', true);
ini_set('display_errors', true);
set_error_handler("PMA_null_error_handler");
ob_start();
} else {
ob_end_clean();
restore_error_handler();
error_reporting($old_error_reporting);
ini_set('html_errors', $old_html_errors);
ini_set('track_errors', $old_track_errors);
ini_set('display_errors', $old_display_errors);
}
}
/**
* Test database connection
*
* @param string $extension 'drizzle', 'mysql' or 'mysqli'
* @param string $connect_type 'tcp' or 'socket'
* @param string $host
* @param string $port
* @param string $socket
* @param string $user
* @param string $pass
* @param string $error_key
* @return bool|array
*/
function test_db_connection($extension, $connect_type, $host, $port, $socket, $user, $pass = null, $error_key = 'Server')
{
// test_php_errormsg();
$socket = empty($socket) || $connect_type == 'tcp' ? null : $socket;
$port = empty($port) || $connect_type == 'socket' ? null : ':' . $port;
$error = null;
if ($extension == 'drizzle') {
while (1) {
$drizzle = @drizzle_create();
if (!$drizzle) {
$error = __('Could not initialize Drizzle connection library');
break;
}
$conn = $socket
? @drizzle_con_add_uds($socket, $user, $pass, null, 0)
: @drizzle_con_add_tcp($drizzle, $host, $port, $user, $pass, null, 0);
if (!$conn) {
$error = __('Could not connect to Drizzle server');
drizzle_free($drizzle);
break;
}
// connection object is set up but we have to send some query to actually connect
$res = @drizzle_query($conn, 'SELECT 1');
if (!$res) {
$error = __('Could not connect to Drizzle server');
} else {
drizzle_result_free($res);
}
drizzle_con_free($conn);
drizzle_free($drizzle);
break;
}
} else if ($extension == 'mysql') {
$conn = @mysql_connect($host . $socket . $port, $user, $pass);
if (!$conn) {
$error = __('Could not connect to MySQL server');
} else {
mysql_close($conn);
}
} else {
$conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
if (!$conn) {
$error = __('Could not connect to MySQL server');
} else {
mysqli_close($conn);
}
}
// test_php_errormsg(false);
if (isset($php_errormsg)) {
$error .= " - $php_errormsg";
}
return is_null($error) ? true : array($error_key => $error);
}
/**
* Validate server config
*
* @param string $path
* @param array $values
* @return array
*/
function validate_server($path, $values)
{
$result = array('Server' => '', 'Servers/1/user' => '', 'Servers/1/SignonSession' => '', 'Servers/1/SignonURL' => '');
$error = false;
if ($values['Servers/1/auth_type'] == 'config' && empty($values['Servers/1/user'])) {
$result['Servers/1/user'] = __('Empty username while using config authentication method');
$error = true;
}
if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonSession'])) {
$result['Servers/1/SignonSession'] = __('Empty signon session name while using signon authentication method');
$error = true;
}
if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonURL'])) {
$result['Servers/1/SignonURL'] = __('Empty signon URL while using signon authentication method');
$error = true;
}
if (!$error && $values['Servers/1/auth_type'] == 'config') {
$password = $values['Servers/1/nopassword'] ? null : $values['Servers/1/password'];
$test = test_db_connection($values['Servers/1/extension'], $values['Servers/1/connect_type'], $values['Servers/1/host'], $values['Servers/1/port'], $values['Servers/1/socket'], $values['Servers/1/user'], $password, 'Server');
if ($test !== true) {
$result = array_merge($result, $test);
}
}
return $result;
}
/**
* Validate pmadb config
*
* @param string $path
* @param array $values
* @return array
*/
function validate_pmadb($path, $values)
{
//$tables = array('Servers/1/bookmarktable', 'Servers/1/relation', 'Servers/1/table_info', 'Servers/1/table_coords', 'Servers/1/pdf_pages', 'Servers/1/column_info', 'Servers/1/history', 'Servers/1/designer_coords');
$result = array('Server_pmadb' => '', 'Servers/1/controluser' => '', 'Servers/1/controlpass' => '');
$error = false;
if ($values['Servers/1/pmadb'] == '') {
return $result;
}
$result = array();
if ($values['Servers/1/controluser'] == '') {
$result['Servers/1/controluser'] = __('Empty phpMyAdmin control user while using pmadb');
$error = true;
}
if ($values['Servers/1/controlpass'] == '') {
$result['Servers/1/controlpass'] = __('Empty phpMyAdmin control user password while using pmadb');
$error = true;
}
if (!$error) {
$test = test_db_connection($values['Servers/1/extension'], $values['Servers/1/connect_type'],
$values['Servers/1/host'], $values['Servers/1/port'], $values['Servers/1/socket'],
$values['Servers/1/controluser'], $values['Servers/1/controlpass'], 'Server_pmadb');
if ($test !== true) {
$result = array_merge($result, $test);
}
}
return $result;
}
/**
* Validates regular expression
*
* @param string $path
* @param array $values
* @return array
*/
function validate_regex($path, $values)
{
$result = array($path => '');
if ($values[$path] == '') {
return $result;
}
test_php_errormsg();
$matches = array();
// in libraries/List_Database.class.php _checkHideDatabase(),
// a '/' is used as the delimiter for hide_db
preg_match('/' . $values[$path] . '/', '', $matches);
test_php_errormsg(false);
if (isset($php_errormsg)) {
$error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
return array($path => $error);
}
return $result;
}
/**
* Validates TrustedProxies field
*
* @param string $path
* @param array $values
* @return array
*/
function validate_trusted_proxies($path, $values)
{
$result = array($path => array());
if (empty($values[$path])) {
return $result;
}
if (is_array($values[$path])) {
// value already processed by FormDisplay::save
$lines = array();
foreach ($values[$path] as $ip => $v) {
$lines[] = preg_match('/^-\d+$/', $ip)
? $v
: $ip . ': ' . $v;
}
} else {
// AJAX validation
$lines = explode("\n", $values[$path]);
}
foreach ($lines as $line) {
$line = trim($line);
$matches = array();
// we catch anything that may (or may not) be an IP
if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
$result[$path][] = __('Incorrect value') . ': ' . $line;
continue;
}
// now let's check whether we really have an IP address
if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
&& filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
$ip = htmlspecialchars(trim($matches[1]));
$result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip);
continue;
}
}
return $result;
}
/**
* Tests integer value
*
* @param string $path
* @param array $values
* @param bool $allow_neg allow negative values
* @param bool $allow_zero allow zero
* @param int $max_value max allowed value
* @param string $error_string error message key: $GLOBALS["strConfig$error_lang_key"]
* @return string empty string if test is successful
*/
function test_number($path, $values, $allow_neg, $allow_zero, $max_value, $error_string)
{
if ($values[$path] === '') {
return '';
}
if (intval($values[$path]) != $values[$path] || (!$allow_neg && $values[$path] < 0) || (!$allow_zero && $values[$path] == 0) || $values[$path] > $max_value) {
return $error_string;
}
return '';
}
/**
* Validates port number
*
* @param string $path
* @param array $values
* @return array
*/
function validate_port_number($path, $values)
{
return array($path => test_number($path, $values, false, false, 65535, __('Not a valid port number')));
}
/**
* Validates positive number
*
* @param string $path
* @param array $values
* @return array
*/
function validate_positive_number($path, $values)
{
return array($path => test_number($path, $values, false, false, PHP_INT_MAX, __('Not a positive number')));
}
/**
* Validates non-negative number
*
* @param string $path
* @param array $values
* @return array
*/
function validate_non_negative_number($path, $values)
{
return array($path => test_number($path, $values, false, true, PHP_INT_MAX, __('Not a non-negative number')));
}
/**
* Validates value according to given regular expression
* Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
*
* @param string $path
* @param array $values
* @param string $regex
* @return void
*/
function validate_by_regex($path, $values, $regex)
{
$result = preg_match($regex, $values[$path]);
return array($path => ($result ? '' : __('Incorrect value')));
}
/**
* Validates upper bound for numeric inputs
*
* @param string $path
* @param array $values
* @param int $max_value
* @return array
*/
function validate_upper_bound($path, $values, $max_value)
{
$result = $values[$path] <= $max_value;
return array($path => ($result ? '' : sprintf(__('Value must be equal or lower than %s'), $max_value)));
}
?>

View File

@ -0,0 +1,746 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Core functions used all over the scripts.
* This script is distinct from libraries/common.inc.php because this
* script is called from /test.
*
* @package PhpMyAdmin
*/
/**
* checks given $var and returns it if valid, or $default of not valid
* given $var is also checked for type being 'similar' as $default
* or against any other type if $type is provided
*
* <code>
* // $_REQUEST['db'] not set
* echo PMA_ifSetOr($_REQUEST['db'], ''); // ''
* // $_REQUEST['sql_query'] not set
* echo PMA_ifSetOr($_REQUEST['sql_query']); // null
* // $cfg['ForceSSL'] not set
* echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // false
* echo PMA_ifSetOr($cfg['ForceSSL']); // null
* // $cfg['ForceSSL'] set to 1
* echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // false
* echo PMA_ifSetOr($cfg['ForceSSL'], false, 'similar'); // 1
* echo PMA_ifSetOr($cfg['ForceSSL'], false); // 1
* // $cfg['ForceSSL'] set to true
* echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // true
* </code>
*
* @see PMA_isValid()
* @param mixed $var param to check
* @param mixed $default default value
* @param mixed $type var type or array of values to check against $var
* @return mixed $var or $default
*/
function PMA_ifSetOr(&$var, $default = null, $type = 'similar')
{
if (! PMA_isValid($var, $type, $default)) {
return $default;
}
return $var;
}
/**
* checks given $var against $type or $compare
*
* $type can be:
* - false : no type checking
* - 'scalar' : whether type of $var is integer, float, string or boolean
* - 'numeric' : whether type of $var is any number repesentation
* - 'length' : whether type of $var is scalar with a string length > 0
* - 'similar' : whether type of $var is similar to type of $compare
* - 'equal' : whether type of $var is identical to type of $compare
* - 'identical' : whether $var is identical to $compare, not only the type!
* - or any other valid PHP variable type
*
* <code>
* // $_REQUEST['doit'] = true;
* PMA_isValid($_REQUEST['doit'], 'identical', 'true'); // false
* // $_REQUEST['doit'] = 'true';
* PMA_isValid($_REQUEST['doit'], 'identical', 'true'); // true
* </code>
*
* NOTE: call-by-reference is used to not get NOTICE on undefined vars,
* but the var is not altered inside this function, also after checking a var
* this var exists nut is not set, example:
* <code>
* // $var is not set
* isset($var); // false
* functionCallByReference($var); // false
* isset($var); // true
* functionCallByReference($var); // true
* </code>
*
* to avoid this we set this var to null if not isset
*
* @todo create some testsuites
* @todo add some more var types like hex, bin, ...?
* @see http://php.net/gettype
* @param mixed $var variable to check
* @param mixed $type var type or array of valid values to check against $var
* @param mixed $compare var to compare with $var
* @return boolean whether valid or not
*/
function PMA_isValid(&$var, $type = 'length', $compare = null)
{
if (! isset($var)) {
// var is not even set
return false;
}
if ($type === false) {
// no vartype requested
return true;
}
if (is_array($type)) {
return in_array($var, $type);
}
// allow some aliaes of var types
$type = strtolower($type);
switch ($type) {
case 'identic' :
$type = 'identical';
break;
case 'len' :
$type = 'length';
break;
case 'bool' :
$type = 'boolean';
break;
case 'float' :
$type = 'double';
break;
case 'int' :
$type = 'integer';
break;
case 'null' :
$type = 'NULL';
break;
}
if ($type === 'identical') {
return $var === $compare;
}
// whether we should check against given $compare
if ($type === 'similar') {
switch (gettype($compare)) {
case 'string':
case 'boolean':
$type = 'scalar';
break;
case 'integer':
case 'double':
$type = 'numeric';
break;
default:
$type = gettype($compare);
}
} elseif ($type === 'equal') {
$type = gettype($compare);
}
// do the check
if ($type === 'length' || $type === 'scalar') {
$is_scalar = is_scalar($var);
if ($is_scalar && $type === 'length') {
return (bool) strlen($var);
}
return $is_scalar;
}
if ($type === 'numeric') {
return is_numeric($var);
}
if (gettype($var) === $type) {
return true;
}
return false;
}
/**
* Removes insecure parts in a path; used before include() or
* require() when a part of the path comes from an insecure source
* like a cookie or form.
*
* @param string The path to check
*
* @return string The secured path
*
* @access public
*/
function PMA_securePath($path)
{
// change .. to .
$path = preg_replace('@\.\.*@', '.', $path);
return $path;
} // end function
/**
* displays the given error message on phpMyAdmin error page in foreign language,
* ends script execution and closes session
*
* loads language file if not loaded already
*
* @todo use detected argument separator (PMA_Config)
* @param string $error_message the error message or named error message
* @param string|array $message_args arguments applied to $error_message
* @return exit
*/
function PMA_fatalError($error_message, $message_args = null)
{
/* Use format string if applicable */
if (is_string($message_args)) {
$error_message = sprintf($error_message, $message_args);
} elseif (is_array($message_args)) {
$error_message = vsprintf($error_message, $message_args);
}
$error_message = strtr($error_message, array('<br />' => '[br]'));
if (function_exists('__')) {
$error_header = __('Error');
} else {
$error_header = 'Error';
}
// Displays the error message
$lang = $GLOBALS['available_languages'][$GLOBALS['lang']][1];
$dir = $GLOBALS['text_dir'];
$type = $error_header;
$error = $error_message;
// on fatal errors it cannot hurt to always delete the current session
if (isset($GLOBALS['session_name']) && isset($_COOKIE[$GLOBALS['session_name']])) {
$GLOBALS['PMA_Config']->removeCookie($GLOBALS['session_name']);
}
include './libraries/error.inc.php';
if (!defined('TESTSUITE')) {
exit;
}
}
/**
* Returns a link to the PHP documentation
*
* @param string anchor in documentation
*
* @return string the URL
*
* @access public
*/
function PMA_getPHPDocLink($target)
{
/* Gettext does not have to be loaded yet */
if (function_exists('_pgettext')) {
/* l10n: Please check that translation actually exists. */
$lang = _pgettext('PHP documentation language', 'en');
} else {
$lang = 'en';
}
return PMA_linkURL('http://php.net/manual/' . $lang . '/' . $target);
}
/**
* Warn or fail on missing extension.
*
* @param string $extension Extension name
* @param bool $fatal Whether the error is fatal.
/ @param string $extra Extra string to append to messsage.
*/
function PMA_warnMissingExtension($extension, $fatal = false, $extra = '')
{
/* Gettext does not have to be loaded yet here */
if (function_exists('__')) {
$message = __('The %s extension is missing. Please check your PHP configuration.');
} else {
$message = 'The %s extension is missing. Please check your PHP configuration.';
}
$message = sprintf($message,
'[a@' . PMA_getPHPDocLink('book.' . $extension . '.php') . '@Documentation][em]' . $extension . '[/em][/a]');
if ($extra != '') {
$message .= ' ' . $extra;
}
if ($fatal) {
PMA_fatalError($message);
} else {
trigger_error($message, E_USER_WARNING);
}
}
/**
* returns count of tables in given db
*
* @param string $db database to count tables for
* @return integer count of tables in $db
*/
function PMA_getTableCount($db)
{
$tables = PMA_DBI_try_query(
'SHOW TABLES FROM ' . PMA_backquote($db) . ';',
null, PMA_DBI_QUERY_STORE);
if ($tables) {
$num_tables = PMA_DBI_num_rows($tables);
// do not count hidden blobstreaming tables
while ((($num_tables > 0)) && $data = PMA_DBI_fetch_assoc($tables)) {
if (PMA_BS_IsHiddenTable($data['Tables_in_' . $db])) {
$num_tables--;
}
}
PMA_DBI_free_result($tables);
} else {
$num_tables = 0;
}
return $num_tables;
}
/**
* Converts numbers like 10M into bytes
* Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
* (renamed with PMA prefix to avoid double definition when embedded
* in Moodle)
*
* @param string $size
* @return integer $size
*/
function PMA_get_real_size($size = 0)
{
if (! $size) {
return 0;
}
$scan['gb'] = 1073741824; //1024 * 1024 * 1024;
$scan['g'] = 1073741824; //1024 * 1024 * 1024;
$scan['mb'] = 1048576;
$scan['m'] = 1048576;
$scan['kb'] = 1024;
$scan['k'] = 1024;
$scan['b'] = 1;
foreach ($scan as $unit => $factor) {
if (strlen($size) > strlen($unit)
&& strtolower(substr($size, strlen($size) - strlen($unit))) == $unit) {
return substr($size, 0, strlen($size) - strlen($unit)) * $factor;
}
}
return $size;
} // end function PMA_get_real_size()
/**
* merges array recursive like array_merge_recursive() but keyed-values are
* always overwritten.
*
* array PMA_array_merge_recursive(array $array1[, array $array2[, array ...]])
*
* @see http://php.net/array_merge
* @see http://php.net/array_merge_recursive
* @param array array to merge
* @param array array to merge
* @param array ...
* @return array merged array
*/
function PMA_array_merge_recursive()
{
switch(func_num_args()) {
case 0 :
return false;
break;
case 1 :
// when does that happen?
return func_get_arg(0);
break;
case 2 :
$args = func_get_args();
if (! is_array($args[0]) || ! is_array($args[1])) {
return $args[1];
}
foreach ($args[1] as $key2 => $value2) {
if (isset($args[0][$key2]) && !is_int($key2)) {
$args[0][$key2] = PMA_array_merge_recursive($args[0][$key2],
$value2);
} else {
// we erase the parent array, otherwise we cannot override a directive that
// contains array elements, like this:
// (in config.default.php) $cfg['ForeignKeyDropdownOrder'] = array('id-content','content-id');
// (in config.inc.php) $cfg['ForeignKeyDropdownOrder'] = array('content-id');
if (is_int($key2) && $key2 == 0) {
unset($args[0]);
}
$args[0][$key2] = $value2;
}
}
return $args[0];
break;
default :
$args = func_get_args();
$args[1] = PMA_array_merge_recursive($args[0], $args[1]);
array_shift($args);
return call_user_func_array('PMA_array_merge_recursive', $args);
break;
}
}
/**
* calls $function vor every element in $array recursively
*
* this function is protected against deep recursion attack CVE-2006-1549,
* 1000 seems to be more than enough
*
* @see http://www.php-security.org/MOPB/MOPB-02-2007.html
* @see http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-1549
*
* @param array $array array to walk
* @param string $function function to call for every array element
*/
function PMA_arrayWalkRecursive(&$array, $function, $apply_to_keys_also = false)
{
static $recursive_counter = 0;
if (++$recursive_counter > 1000) {
die(__('possible deep recursion attack'));
}
foreach ($array as $key => $value) {
if (is_array($value)) {
PMA_arrayWalkRecursive($array[$key], $function, $apply_to_keys_also);
} else {
$array[$key] = $function($value);
}
if ($apply_to_keys_also && is_string($key)) {
$new_key = $function($key);
if ($new_key != $key) {
$array[$new_key] = $array[$key];
unset($array[$key]);
}
}
}
$recursive_counter--;
}
/**
* boolean phpMyAdmin.PMA_checkPageValidity(string &$page, array $whitelist)
*
* checks given given $page against given $whitelist and returns true if valid
* it ignores optionaly query paramters in $page (script.php?ignored)
*
* @param string &$page page to check
* @param array $whitelist whitelist to check page against
* @return boolean whether $page is valid or not (in $whitelist or not)
*/
function PMA_checkPageValidity(&$page, $whitelist)
{
if (! isset($page) || !is_string($page)) {
return false;
}
if (in_array($page, $whitelist)) {
return true;
} elseif (in_array(substr($page, 0, strpos($page . '?', '?')), $whitelist)) {
return true;
} else {
$_page = urldecode($page);
if (in_array(substr($_page, 0, strpos($_page . '?', '?')), $whitelist)) {
return true;
}
}
return false;
}
/**
* trys to find the value for the given environment vriable name
*
* searchs in $_SERVER, $_ENV than trys getenv() and apache_getenv()
* in this order
*
* @param string $var_name variable name
* @return string value of $var or empty string
*/
function PMA_getenv($var_name)
{
if (isset($_SERVER[$var_name])) {
return $_SERVER[$var_name];
} elseif (isset($_ENV[$var_name])) {
return $_ENV[$var_name];
} elseif (getenv($var_name)) {
return getenv($var_name);
} elseif (function_exists('apache_getenv')
&& apache_getenv($var_name, true)) {
return apache_getenv($var_name, true);
}
return '';
}
/**
* Send HTTP header, taking IIS limits into account (600 seems ok)
*
* @param string $uri the header to send
* @return boolean always true
*/
function PMA_sendHeaderLocation($uri)
{
if (PMA_IS_IIS && strlen($uri) > 600) {
include_once './libraries/js_escape.lib.php';
echo '<html><head><title>- - -</title>' . "\n";
echo '<meta http-equiv="expires" content="0">' . "\n";
echo '<meta http-equiv="Pragma" content="no-cache">' . "\n";
echo '<meta http-equiv="Cache-Control" content="no-cache">' . "\n";
echo '<meta http-equiv="Refresh" content="0;url=' . htmlspecialchars($uri) . '">' . "\n";
echo '<script type="text/javascript">' . "\n";
echo '//<![CDATA[' . "\n";
echo 'setTimeout("window.location = unescape(\'"' . PMA_escapeJsString($uri) . '"\')", 2000);' . "\n";
echo '//]]>' . "\n";
echo '</script>' . "\n";
echo '</head>' . "\n";
echo '<body>' . "\n";
echo '<script type="text/javascript">' . "\n";
echo '//<![CDATA[' . "\n";
echo 'document.write(\'<p><a href="' . htmlspecialchars($uri) . '">' . __('Go') . '</a></p>\');' . "\n";
echo '//]]>' . "\n";
echo '</script></body></html>' . "\n";
} else {
if (SID) {
if (strpos($uri, '?') === false) {
header('Location: ' . $uri . '?' . SID);
} else {
$separator = PMA_get_arg_separator();
header('Location: ' . $uri . $separator . SID);
}
} else {
session_write_close();
if (headers_sent()) {
if (function_exists('debug_print_backtrace')) {
echo '<pre>';
debug_print_backtrace();
echo '</pre>';
}
trigger_error('PMA_sendHeaderLocation called when headers are already sent!', E_USER_ERROR);
}
// bug #1523784: IE6 does not like 'Refresh: 0', it
// results in a blank page
// but we need it when coming from the cookie login panel)
if (PMA_IS_IIS && defined('PMA_COMING_FROM_COOKIE_LOGIN')) {
header('Refresh: 0; ' . $uri);
} else {
header('Location: ' . $uri);
}
}
}
}
/**
* Outputs headers to prevent caching in browser (and on the way).
*
* @return nothing
*/
function PMA_no_cache_header()
{
header('Expires: ' . date(DATE_RFC1123)); // rfc2616 - Section 14.21
header('Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0'); // HTTP/1.1
if (PMA_USR_BROWSER_AGENT == 'IE') {
/* FIXME: Why is this speecial case for IE needed? */
header('Pragma: public');
} else {
header('Pragma: no-cache'); // HTTP/1.0
// test case: exporting a database into a .gz file with Safari
// would produce files not having the current time
// (added this header for Safari but should not harm other browsers)
header('Last-Modified: ' . date(DATE_RFC1123));
}
}
/**
* Sends header indicating file download.
*
* @param string $filename Filename to include in headers if empty,
* none Content-Disposition header will be sent.
* @param string $mimetype MIME type to include in headers.
* @param int $length Length of content (optional)
* @param bool $no_cache Whether to include no-caching headers.
*
* @return nothing
*/
function PMA_download_header($filename, $mimetype, $length = 0, $no_cache = true)
{
if ($no_cache) {
PMA_no_cache_header();
}
/* Replace all possibly dangerous chars in filename */
$filename = str_replace(array(';', '"', "\n", "\r"), '-', $filename);
if (!empty($filename)) {
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="' . $filename . '"');
}
header('Content-Type: ' . $mimetype);
header('Content-Transfer-Encoding: binary');
if ($length > 0) {
header('Content-Length: ' . $length);
}
}
/**
* Returns value of an element in $array given by $path.
* $path is a string describing position of an element in an associative array,
* eg. Servers/1/host refers to $array[Servers][1][host]
*
* @param string $path
* @param array $array
* @param mixed $default
* @return mixed array element or $default
*/
function PMA_array_read($path, $array, $default = null)
{
$keys = explode('/', $path);
$value =& $array;
foreach ($keys as $key) {
if (! isset($value[$key])) {
return $default;
}
$value =& $value[$key];
}
return $value;
}
/**
* Stores value in an array
*
* @param string $path
* @param array &$array
* @param mixed $value
*/
function PMA_array_write($path, &$array, $value)
{
$keys = explode('/', $path);
$last_key = array_pop($keys);
$a =& $array;
foreach ($keys as $key) {
if (! isset($a[$key])) {
$a[$key] = array();
}
$a =& $a[$key];
}
$a[$last_key] = $value;
}
/**
* Removes value from an array
*
* @param string $path
* @param array &$array
* @param mixed $value
*/
function PMA_array_remove($path, &$array)
{
$keys = explode('/', $path);
$keys_last = array_pop($keys);
$path = array();
$depth = 0;
$path[0] =& $array;
$found = true;
// go as deep as required or possible
foreach ($keys as $key) {
if (! isset($path[$depth][$key])) {
$found = false;
break;
}
$depth++;
$path[$depth] =& $path[$depth-1][$key];
}
// if element found, remove it
if ($found) {
unset($path[$depth][$keys_last]);
$depth--;
}
// remove empty nested arrays
for (; $depth >= 0; $depth--) {
if (! isset($path[$depth+1]) || count($path[$depth+1]) == 0) {
unset($path[$depth][$keys[$depth]]);
} else {
break;
}
}
}
/**
* Returns link to (possibly) external site using defined redirector.
*
* @param string $url URL where to go.
*
* @return string URL for a link.
*/
function PMA_linkURL($url)
{
if (!preg_match('#^https?://#', $url) || defined('PMA_SETUP')) {
return $url;
} else {
if (!function_exists('PMA_generate_common_url')) {
include_once './libraries/url_generating.lib.php';
}
$params = array();
$params['url'] = $url;
return './url.php' . PMA_generate_common_url($params);
}
}
/**
* Returns HTML code to include javascript file.
*
* @param string $url Location of javascript, relative to js/ folder.
*
* @return string HTML code for javascript inclusion.
*/
function PMA_includeJS($url)
{
if (strpos($url, '?') === false) {
return '<script src="./js/' . $url . '?ts=' . filemtime('./js/' . $url) . '" type="text/javascript"></script>' . "\n";
} else {
return '<script src="./js/' . $url . '" type="text/javascript"></script>' . "\n";
}
}
/**
* Adds JS code snippets to be displayed by header.inc.php. Adds a
* newline to each snippet.
*
* @param string $str Js code to be added (e.g. "token=1234;")
*
*/
function PMA_AddJSCode($str)
{
$GLOBALS['js_script'][] = $str;
}
/**
* Adds JS code snippet for variable assignment to be displayed by header.inc.php.
*
* @param string $key Name of value to set
* @param mixed $value Value to set, can be either string or array of strings
* @param bool $escape Whether to escape value or keep it as it is (for inclusion of js code)
*
*/
function PMA_AddJSVar($key, $value, $escape = true)
{
PMA_AddJsCode(PMA_getJsValue($key, $value, $escape));
}
?>

View File

@ -0,0 +1,163 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
*
*/
$GLOBALS['data_dictionary_relations'] = array(
'CHARACTER_SETS' => array(
'DEFAULT_COLLATE_NAME' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'COLLATIONS',
'foreign_field' => 'COLLATION_NAME'
)
),
'COLLATIONS' => array(
'CHARACTER_SET_NAME' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'CHARACTER_SETS',
'foreign_field' => 'CHARACTER_SET_NAME'
)
),
'COLUMNS' => array(
'TABLE_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
),
'COLLATION_NAME' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'COLLATIONS',
'foreign_field' => 'COLLATION_NAME'
)
),
'INDEXES' => array(
'TABLE_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
)
),
'INDEX_PARTS' => array(
'TABLE_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
)
),
'INNODB_LOCKS' => array(
'LOCK_TRX_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_TRX',
'foreign_field' => 'TRX_ID'
)
),
'INNODB_LOCK_WAITS' => array(
'REQUESTING_TRX_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_TRX',
'foreign_field' => 'TRX_ID'
),
'REQUESTED_LOCK_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_LOCKS',
'foreign_field' => 'LOCK_ID'
),
'BLOCKING_TRX_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_TRX',
'foreign_field' => 'TRX_ID'
),
'BLOCKING_LOCK_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_LOCKS',
'foreign_field' => 'LOCK_ID'
)
),
'INNODB_SYS_COLUMNS' => array(
'TABLE_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_SYS_TABLES',
'foreign_field' => 'TABLE_ID'
)
),
'INNODB_SYS_FIELDS' => array(
'INDEX_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_SYS_INDEXES',
'foreign_field' => 'INDEX_ID'
)
),
'INNODB_SYS_INDEXES' => array(
'TABLE_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_SYS_TABLES',
'foreign_field' => 'TABLE_ID'
)
),
'INNODB_SYS_TABLESTATS' => array(
'TABLE_ID' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'INNODB_SYS_TABLES',
'foreign_field' => 'TABLE_ID'
)
),
'PLUGINS' => array(
'MODULE_NAME' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'MODULES',
'foreign_field' => 'MODULE_NAME'
)
),
'SCHEMAS' => array(
'DEFAULT_COLLATION_NAME' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'COLLATIONS',
'foreign_field' => 'COLLATION_NAME'
)
),
'TABLES' => array(
'TABLE_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
),
'TABLE_COLLATION' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'COLLATIONS',
'foreign_field' => 'COLLATION_NAME'
)
),
'TABLE_CACHE' => array(
'TABLE_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
)
),
'TABLE_CONSTRAINTS' => array(
'CONSTRAINT_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
),
'TABLE_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
)
),
'TABLE_DEFINITION_CACHE' => array(
'TABLE_SCHEMA' => array(
'foreign_db' => 'data_dictionary',
'foreign_table' => 'SCHEMAS',
'foreign_field' => 'SCHEMA_NAME'
)
)
);
?>

View File

@ -0,0 +1,225 @@
<?php
/**
* Column types and functions supported by Drizzle
*
* @package PhpMyAdmin
*/
$auto_column_types = empty($cfg['ColumnTypes']);
// VARCHAR, TINYINT, TEXT and DATE are listed first, based on estimated popularity
$cfg['ColumnTypes'] = !empty($cfg['ColumnTypes']) ? $cfg['ColumnTypes'] : array(
// most used
'INTEGER',
'VARCHAR',
'TEXT',
'DATE',
// numeric
'NUMERIC' => array(
'INTEGER',
'BIGINT',
'-',
'DECIMAL',
'DOUBLE',
'-',
'BOOLEAN',
'SERIAL',
'UUID',
),
// Date/Time
'DATE and TIME' => array(
'DATE',
'DATETIME',
'TIMESTAMP',
'TIME',
),
// Text
'STRING' => array(
'VARCHAR',
'TEXT',
'-',
'VARBINARY',
'BLOB',
'-',
'ENUM',
),
);
if ($auto_column_types && PMA_MYSQL_INT_VERSION >= 20120130) {
$cfg['ColumnTypes']['STRING'][] = '-';
$cfg['ColumnTypes']['STRING'][] = 'IPV6';
}
unset($auto_column_types);
$cfg['AttributeTypes'] = !empty($cfg['AttributeTypes']) ? $cfg['AttributeTypes'] : array(
'',
'on update CURRENT_TIMESTAMP',
);
if ($cfg['ShowFunctionFields']) {
$cfg['RestrictColumnTypes'] = !empty($cfg['RestrictColumnTypes']) ? $cfg['RestrictColumnTypes'] : array(
'INTEGER' => 'FUNC_NUMBER',
'BIGINT' => 'FUNC_NUMBER',
'DECIMAL' => 'FUNC_NUMBER',
'DOUBLE' => 'FUNC_NUMBER',
'BOOLEAN' => 'FUNC_NUMBER',
'SERIAL' => 'FUNC_NUMBER',
'DATE' => 'FUNC_DATE',
'DATETIME' => 'FUNC_DATE',
'TIMESTAMP' => 'FUNC_DATE',
'TIME' => 'FUNC_DATE',
'VARCHAR' => 'FUNC_CHAR',
'TEXT' => 'FUNC_CHAR',
'VARBINARY' => 'FUNC_CHAR',
'BLOB' => 'FUNC_CHAR',
'UUID' => 'FUNC_UUID',
'ENUM' => '',
);
$restrict_functions = array(
'FUNC_CHAR' => array(
'BIN',
'CHAR',
'CURRENT_USER',
'COMPRESS',
'DATABASE',
'DAYNAME',
'HEX',
'LOAD_FILE',
'LOWER',
'LTRIM',
'MD5',
'MONTHNAME',
'QUOTE',
'REVERSE',
'RTRIM',
'SCHEMA',
'SPACE',
'TRIM',
'UNCOMPRESS',
'UNHEX',
'UPPER',
'USER',
'UUID',
'VERSION',
),
'FUNC_UUID' => array(
'UUID',
),
'FUNC_DATE' => array(
'CURRENT_DATE',
'CURRENT_TIME',
'DATE',
'FROM_DAYS',
'FROM_UNIXTIME',
'LAST_DAY',
'NOW',
'SYSDATE',
//'TIME', // https://bugs.launchpad.net/drizzle/+bug/804571
'TIMESTAMP',
'UTC_DATE',
'UTC_TIME',
'UTC_TIMESTAMP',
'YEAR',
),
'FUNC_NUMBER' => array(
'ABS',
'ACOS',
'ASCII',
'ASIN',
'ATAN',
'BIT_COUNT',
'CEILING',
'CHAR_LENGTH',
'CONNECTION_ID',
'COS',
'COT',
'CRC32',
'DAYOFMONTH',
'DAYOFWEEK',
'DAYOFYEAR',
'DEGREES',
'EXP',
'FLOOR',
'HOUR',
'LENGTH',
'LN',
'LOG',
'LOG2',
'LOG10',
'MICROSECOND',
'MINUTE',
'MONTH',
'OCT',
'ORD',
'PI',
'QUARTER',
'RADIANS',
'RAND',
'ROUND',
'SECOND',
'SIGN',
'SIN',
'SQRT',
'TAN',
'TO_DAYS',
'TIME_TO_SEC',
'UNCOMPRESSED_LENGTH',
'UNIX_TIMESTAMP',
//'WEEK', // same as TIME
'WEEKDAY',
'WEEKOFYEAR',
'YEARWEEK',
),
);
$cfg_default_restrict_funcs = empty($cfg['RestrictFunctions']);
if ($cfg_default_restrict_funcs) {
$cfg['RestrictFunctions'] = $restrict_functions;
}
if (empty($cfg['Functions'])) {
// build a list of functions based on $restrict_functions
$cfg['Functions'] = array();
foreach ($restrict_functions as $cat => $functions) {
$cfg['Functions'] = array_merge($cfg['Functions'], $functions);
}
// check for some functions known to be in modules
$functions = array(
'MYSQL_PASSWORD' => 'FUNC_CHAR',
'ROT13' => 'FUNC_CHAR',
);
// add new functions
$sql = "SELECT upper(plugin_name) f
FROM data_dictionary.plugins
WHERE plugin_name IN ('" . implode("','", array_keys($functions)) . "')
AND plugin_type = 'Function'
AND is_active";
$drizzle_functions = PMA_DBI_fetch_result($sql, 'f', 'f');
$cfg['Functions'] = array_merge($cfg['Functions'], $drizzle_functions);
if ($cfg_default_restrict_funcs) {
foreach ($drizzle_functions as $function) {
$category = $functions[$function];
$cfg['RestrictFunctions'][$category][] = $function;
}
foreach ($cfg['RestrictFunctions'] as &$v) {
sort($v);
}
unset($v);
}
sort($cfg['Functions']);
}
unset($restrict_functions);
} // end if
?>

View File

@ -0,0 +1,286 @@
<?php
/**
* Column types and functions supported by MySQL
*
* @package PhpMyAdmin
*/
// VARCHAR, TINYINT, TEXT and DATE are listed first, based on estimated popularity
$cfg['ColumnTypes'] = !empty($cfg['ColumnTypes']) ? $cfg['ColumnTypes'] : array(
// most used
'INT',
'VARCHAR',
'TEXT',
'DATE',
// numeric
'NUMERIC' => array(
'TINYINT',
'SMALLINT',
'MEDIUMINT',
'INT',
'BIGINT',
'-',
'DECIMAL',
'FLOAT',
'DOUBLE',
'REAL',
'-',
'BIT',
'BOOLEAN',
'SERIAL',
),
// Date/Time
'DATE and TIME' => array(
'DATE',
'DATETIME',
'TIMESTAMP',
'TIME',
'YEAR',
),
// Text
'STRING' => array(
'CHAR',
'VARCHAR',
'-',
'TINYTEXT',
'TEXT',
'MEDIUMTEXT',
'LONGTEXT',
'-',
'BINARY',
'VARBINARY',
'-',
'TINYBLOB',
'MEDIUMBLOB',
'BLOB',
'LONGBLOB',
'-',
'ENUM',
'SET',
),
'SPATIAL' => array(
'GEOMETRY',
'POINT',
'LINESTRING',
'POLYGON',
'MULTIPOINT',
'MULTILINESTRING',
'MULTIPOLYGON',
'GEOMETRYCOLLECTION',
),
);
$cfg['AttributeTypes'] = !empty($cfg['AttributeTypes']) ? $cfg['AttributeTypes'] : array(
'',
'BINARY',
'UNSIGNED',
'UNSIGNED ZEROFILL',
'on update CURRENT_TIMESTAMP',
);
if ($cfg['ShowFunctionFields']) {
$cfg['RestrictColumnTypes'] = !empty($cfg['RestrictColumnTypes']) ? $cfg['RestrictColumnTypes'] : array(
'TINYINT' => 'FUNC_NUMBER',
'SMALLINT' => 'FUNC_NUMBER',
'MEDIUMINT' => 'FUNC_NUMBER',
'INT' => 'FUNC_NUMBER',
'BIGINT' => 'FUNC_NUMBER',
'DECIMAL' => 'FUNC_NUMBER',
'FLOAT' => 'FUNC_NUMBER',
'DOUBLE' => 'FUNC_NUMBER',
'REAL' => 'FUNC_NUMBER',
'BIT' => 'FUNC_NUMBER',
'BOOLEAN' => 'FUNC_NUMBER',
'SERIAL' => 'FUNC_NUMBER',
'DATE' => 'FUNC_DATE',
'DATETIME' => 'FUNC_DATE',
'TIMESTAMP' => 'FUNC_DATE',
'TIME' => 'FUNC_DATE',
'YEAR' => 'FUNC_DATE',
'CHAR' => 'FUNC_CHAR',
'VARCHAR' => 'FUNC_CHAR',
'TINYTEXT' => 'FUNC_CHAR',
'TEXT' => 'FUNC_CHAR',
'MEDIUMTEXT' => 'FUNC_CHAR',
'LONGTEXT' => 'FUNC_CHAR',
'BINARY' => 'FUNC_CHAR',
'VARBINARY' => 'FUNC_CHAR',
'TINYBLOB' => 'FUNC_CHAR',
'MEDIUMBLOB' => 'FUNC_CHAR',
'BLOB' => 'FUNC_CHAR',
'LONGBLOB' => 'FUNC_CHAR',
'ENUM' => '',
'SET' => '',
'GEOMETRY' => 'FUNC_SPATIAL',
'POINT' => 'FUNC_SPATIAL',
'LINESTRING' => 'FUNC_SPATIAL',
'POLYGON' => 'FUNC_SPATIAL',
'MULTIPOINT' => 'FUNC_SPATIAL',
'MULTILINESTRING' => 'FUNC_SPATIAL',
'MULTIPOLYGON' => 'FUNC_SPATIAL',
'GEOMETRYCOLLECTION' => 'FUNC_SPATIAL',
);
$restrict_functions = array(
'FUNC_CHAR' => array(
'BIN',
'CHAR',
'CURRENT_USER',
'COMPRESS',
'DATABASE',
'DAYNAME',
'DES_DECRYPT',
'DES_ENCRYPT',
'ENCRYPT',
'HEX',
'INET_NTOA',
'LOAD_FILE',
'LOWER',
'LTRIM',
'MD5',
'MONTHNAME',
'OLD_PASSWORD',
'PASSWORD',
'QUOTE',
'REVERSE',
'RTRIM',
'SHA1',
'SOUNDEX',
'SPACE',
'TRIM',
'UNCOMPRESS',
'UNHEX',
'UPPER',
'USER',
'UUID',
'VERSION',
),
'FUNC_DATE' => array(
'CURRENT_DATE',
'CURRENT_TIME',
'DATE',
'FROM_DAYS',
'FROM_UNIXTIME',
'LAST_DAY',
'NOW',
'SEC_TO_TIME',
'SYSDATE',
'TIME',
'TIMESTAMP',
'UTC_DATE',
'UTC_TIME',
'UTC_TIMESTAMP',
'YEAR',
),
'FUNC_NUMBER' => array(
'ABS',
'ACOS',
'ASCII',
'ASIN',
'ATAN',
'BIT_LENGTH',
'BIT_COUNT',
'CEILING',
'CHAR_LENGTH',
'CONNECTION_ID',
'COS',
'COT',
'CRC32',
'DAYOFMONTH',
'DAYOFWEEK',
'DAYOFYEAR',
'DEGREES',
'EXP',
'FLOOR',
'HOUR',
'INET_ATON',
'LENGTH',
'LN',
'LOG',
'LOG2',
'LOG10',
'MICROSECOND',
'MINUTE',
'MONTH',
'OCT',
'ORD',
'PI',
'QUARTER',
'RADIANS',
'RAND',
'ROUND',
'SECOND',
'SIGN',
'SIN',
'SQRT',
'TAN',
'TO_DAYS',
'TO_SECONDS',
'TIME_TO_SEC',
'UNCOMPRESSED_LENGTH',
'UNIX_TIMESTAMP',
'UUID_SHORT',
'WEEK',
'WEEKDAY',
'WEEKOFYEAR',
'YEARWEEK',
),
'FUNC_SPATIAL' => array(
'GeomFromText',
'GeomFromWKB',
'GeomCollFromText',
'LineFromText',
'MLineFromText',
'PointFromText',
'MPointFromText',
'PolyFromText',
'MPolyFromText',
'GeomCollFromWKB',
'LineFromWKB',
'MLineFromWKB',
'PointFromWKB',
'MPointFromWKB',
'PolyFromWKB',
'MPolyFromWKB',
),
);
// $restrict_functions holds all known functions, remove these that are unavailable on current server
if (PMA_MYSQL_INT_VERSION < 50500) {
$restrict_functions['FUNC_NUMBER'] = array_diff($restrict_functions['FUNC_NUMBER'], array('TO_SECONDS'));
}
if (PMA_MYSQL_INT_VERSION < 50120) {
$restrict_functions['FUNC_NUMBER'] = array_diff($restrict_functions['FUNC_NUMBER'], array('UUID_SHORT'));
}
if (empty($cfg['RestrictFunctions'])) {
$cfg['RestrictFunctions'] = $restrict_functions;
}
if (empty($cfg['Functions'])) {
// build a list of functions based on $restrict_functions
$cfg['Functions'] = array();
foreach ($restrict_functions as $cat => $functions) {
if ($cat != 'FUNC_SPATIAL') {
$cfg['Functions'] = array_merge($cfg['Functions'], $functions);
}
}
sort($cfg['Functions']);
}
unset($restrict_functions);
} // end if
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,82 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Gets some core libraries
*/
require_once './libraries/common.inc.php';
require_once './libraries/bookmark.lib.php';
PMA_checkParameters(array('db'));
$is_show_stats = $cfg['ShowStats'];
$db_is_information_schema = PMA_is_system_schema($db);
if ($db_is_information_schema) {
$is_show_stats = false;
}
/**
* Defines the urls to return to in case of error in a sql statement
*/
$err_url_0 = 'main.php?' . PMA_generate_common_url();
$err_url = $cfg['DefaultTabDatabase'] . '?' . PMA_generate_common_url($db);
/**
* Ensures the database exists (else move to the "parent" script) and displays
* headers
*/
if (! isset($is_db) || ! $is_db) {
if (strlen($db)) {
$is_db = PMA_DBI_select_db($db);
// This "Command out of sync" 2014 error may happen, for example
// after calling a MySQL procedure; at this point we can't select
// the db but it's not necessarily wrong
if (PMA_DBI_getError() && $GLOBALS['errno'] == 2014) {
$is_db = true;
unset($GLOBALS['errno']);
}
}
// Not a valid db name -> back to the welcome page
if (! strlen($db) || ! $is_db) {
PMA_sendHeaderLocation($cfg['PmaAbsoluteUri'] . 'main.php?' . PMA_generate_common_url('', '', '&') . (isset($message) ? '&message=' . urlencode($message) : '') . '&reload=1');
exit;
}
} // end if (ensures db exists)
/**
* Changes database charset if requested by the user
*/
if (isset($submitcollation) && !empty($db_collation)) {
list($db_charset) = explode('_', $db_collation);
$sql_query = 'ALTER DATABASE ' . PMA_backquote($db) . ' DEFAULT' . PMA_generateCharsetQueryPart($db_collation);
$result = PMA_DBI_query($sql_query);
$message = PMA_Message::success();
unset($db_charset, $db_collation);
/**
* If we are in an Ajax request, let us stop the execution here. Necessary for
* db charset change action on db_operations.php. If this causes a bug on
* other pages, we might have to move this to a different location.
*/
if ( $GLOBALS['is_ajax_request'] == true) {
PMA_ajaxResponse($message, $message->isSuccess());
};
}
require_once './libraries/header.inc.php';
/**
* Set parameters for links
*/
$url_query = PMA_generate_common_url($db);
?>

View File

@ -0,0 +1,266 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Gets the list of the table in the current db and informations about these
* tables if possible
*
* fills tooltip arrays and provides $tables, $num_tables, $is_show_stats
* and $db_is_information_schema
*
* speedup view on locked tables
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* requirements
*/
require_once './libraries/common.inc.php';
/**
* limits for table list
*/
if (! isset($_SESSION['tmp_user_values']['table_limit_offset']) || $_SESSION['tmp_user_values']['table_limit_offset_db'] != $db) {
$_SESSION['tmp_user_values']['table_limit_offset'] = 0;
$_SESSION['tmp_user_values']['table_limit_offset_db'] = $db;
}
if (isset($_REQUEST['pos'])) {
$_SESSION['tmp_user_values']['table_limit_offset'] = (int) $_REQUEST['pos'];
}
$pos = $_SESSION['tmp_user_values']['table_limit_offset'];
/**
* fills given tooltip arrays
*
* @param array $tooltip_truename tooltip data
* @param array $tooltip_aliasname tooltip data
* @param array $table tabledata
*/
function PMA_fillTooltip(&$tooltip_truename, &$tooltip_aliasname, $table)
{
if (strstr($table['Comment'], '; InnoDB free') === false) {
if (!strstr($table['Comment'], 'InnoDB free') === false) {
// here we have just InnoDB generated part
$table['Comment'] = '';
}
} else {
// remove InnoDB comment from end, just the minimal part (*? is non greedy)
$table['Comment'] = preg_replace('@; InnoDB free:.*?$@', '', $table['Comment']);
}
// views have VIEW as comment so it's not a real comment put by a user
if ('VIEW' == $table['Comment']) {
$table['Comment'] = '';
}
if (empty($table['Comment'])) {
$table['Comment'] = $table['Name'];
} else {
// why?
$table['Comment'] .= ' ';
}
if ($GLOBALS['cfg']['ShowTooltipAliasTB']
&& $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested') {
$tooltip_truename[$table['Name']] = $table['Comment'];
$tooltip_aliasname[$table['Name']] = $table['Name'];
} else {
$tooltip_truename[$table['Name']] = $table['Name'];
$tooltip_aliasname[$table['Name']] = $table['Comment'];
}
if (isset($table['Create_time']) && !empty($table['Create_time'])) {
$tooltip_aliasname[$table['Name']] .= ', ' . __('Creation')
. ': ' . PMA_localisedDate(strtotime($table['Create_time']));
}
if (! empty($table['Update_time'])) {
$tooltip_aliasname[$table['Name']] .= ', ' . __('Last update')
. ': ' . PMA_localisedDate(strtotime($table['Update_time']));
}
if (! empty($table['Check_time'])) {
$tooltip_aliasname[$table['Name']] .= ', ' . __('Last check')
. ': ' . PMA_localisedDate(strtotime($table['Check_time']));
}
}
PMA_checkParameters(array('db'));
/**
* @global bool whether to display extended stats
*/
$is_show_stats = $cfg['ShowStats'];
/**
* @global bool whether selected db is information_schema
*/
$db_is_information_schema = false;
if (PMA_is_system_schema($db)) {
$is_show_stats = false;
$db_is_information_schema = true;
}
/**
* @global array information about tables in db
*/
$tables = array();
// When used in Nested table group mode, only show tables matching the given groupname
if (PMA_isValid($tbl_group) && !$cfg['ShowTooltipAliasTB']) {
$tbl_group_sql = ' LIKE "' . PMA_escape_mysql_wildcards($tbl_group) . '%"';
} else {
$tbl_group_sql = '';
}
if ($cfg['ShowTooltip']) {
$tooltip_truename = array();
$tooltip_aliasname = array();
}
// Special speedup for newer MySQL Versions (in 4.0 format changed)
if (true === $cfg['SkipLockedTables']) {
$db_info_result = PMA_DBI_query('SHOW OPEN TABLES FROM ' . PMA_backquote($db) . ';');
// Blending out tables in use
if ($db_info_result && PMA_DBI_num_rows($db_info_result) > 0) {
while ($tmp = PMA_DBI_fetch_row($db_info_result)) {
// if in use memorize tablename
if (preg_match('@in_use=[1-9]+@i', $tmp[1])) {
$sot_cache[$tmp[0]] = true;
}
}
PMA_DBI_free_result($db_info_result);
if (isset($sot_cache)) {
$db_info_result = PMA_DBI_query(
'SHOW TABLES FROM ' . PMA_backquote($db) . $tbl_group_sql . ';',
null, PMA_DBI_QUERY_STORE);
if ($db_info_result && PMA_DBI_num_rows($db_info_result) > 0) {
while ($tmp = PMA_DBI_fetch_row($db_info_result)) {
if (! isset($sot_cache[$tmp[0]])) {
$sts_result = PMA_DBI_query(
'SHOW TABLE STATUS FROM ' . PMA_backquote($db)
. ' LIKE \'' . PMA_sqlAddSlashes($tmp[0], true) . '\';');
$sts_tmp = PMA_DBI_fetch_assoc($sts_result);
PMA_DBI_free_result($sts_result);
unset($sts_result);
if (! isset($sts_tmp['Type']) && isset($sts_tmp['Engine'])) {
$sts_tmp['Type'] =& $sts_tmp['Engine'];
}
if (!empty($tbl_group) && $cfg['ShowTooltipAliasTB']
&& !preg_match('@' . preg_quote($tbl_group, '@') . '@i', $sts_tmp['Comment'])) {
continue;
}
if ($cfg['ShowTooltip']) {
PMA_fillTooltip($tooltip_truename, $tooltip_aliasname, $sts_tmp);
}
$tables[$sts_tmp['Name']] = $sts_tmp;
} else { // table in use
$tables[$tmp[0]] = array('Name' => $tmp[0]);
}
}
if ($GLOBALS['cfg']['NaturalOrder']) {
uksort($tables, 'strnatcasecmp');
}
$sot_ready = true;
} elseif ($db_info_result) {
PMA_DBI_free_result($db_info_result);
}
unset($sot_cache);
}
unset($tmp);
} elseif ($db_info_result) {
PMA_DBI_free_result($db_info_result);
}
}
if (! isset($sot_ready)) {
// Set some sorting defaults
$sort = 'Name';
$sort_order = 'ASC';
if (isset($_REQUEST['sort'])) {
$sortable_name_mappings = array(
'table' => 'Name',
'records' => 'Rows',
'type' => 'Engine',
'collation' => 'Collation',
'size' => 'Data_length',
'overhead' => 'Data_free'
);
// Make sure the sort type is implemented
if (isset($sortable_name_mappings[$_REQUEST['sort']])) {
$sort = $sortable_name_mappings[$_REQUEST['sort']];
if ($_REQUEST['sort_order'] == 'DESC') {
$sort_order = 'DESC';
}
}
}
if (! empty($tbl_group) && ! $cfg['ShowTooltipAliasTB']) {
// only tables for selected group
$tables = PMA_DBI_get_tables_full($db, $tbl_group, true, null, 0, false, $sort, $sort_order);
} elseif (! empty($tbl_group) && $cfg['ShowTooltipAliasTB']) {
// only tables for selected group,
// but grouping is done on comment ...
$tables = PMA_DBI_get_tables_full($db, $tbl_group, 'comment', null, 0, false, $sort, $sort_order);
} else {
// all tables in db
// - get the total number of tables
// (needed for proper working of the MaxTableList feature)
$tables = PMA_DBI_get_tables($db);
$total_num_tables = count($tables);
if (isset($sub_part) && $sub_part == '_export') {
// (don't fetch only a subset if we are coming from db_export.php,
// because I think it's too risky to display only a subset of the
// table names when exporting a db)
/**
*
* @todo Page selector for table names?
*/
$tables = PMA_DBI_get_tables_full($db, false, false, null, 0, false, $sort, $sort_order);
} else {
// fetch the details for a possible limited subset
$tables = PMA_DBI_get_tables_full($db, false, false, null, $pos, true, $sort, $sort_order);
}
}
if ($cfg['ShowTooltip']) {
foreach ($tables as $each_table) {
PMA_fillTooltip($tooltip_truename, $tooltip_aliasname, $each_table);
}
}
}
/**
* @global int count of tables in db
*/
$num_tables = count($tables);
// (needed for proper working of the MaxTableList feature)
if (! isset($total_num_tables)) {
$total_num_tables = $num_tables;
}
/**
* cleanup
*/
unset($each_table, $tbl_group_sql, $db_info_result);
/**
* Displays top menu links
* If in an Ajax request, we do not need to show this
*/
if ($GLOBALS['is_ajax_request'] != true) {
include './libraries/db_links.inc.php';
}
?>

View File

@ -0,0 +1,158 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
require_once './libraries/common.inc.php';
/**
* Gets the relation settings
*/
$cfgRelation = PMA_getRelationsParam();
/**
* If coming from a Show MySQL link on the home page,
* put something in $sub_part
*/
if (empty($sub_part)) {
$sub_part = '_structure';
}
/**
* Checks for superuser privileges
*/
$is_superuser = PMA_isSuperuser();
/**
* Prepares links
*/
/**
* export, search and qbe links if there is at least one table
*/
if ($num_tables == 0) {
$tab_qbe['warning'] = __('Database seems to be empty!');
$tab_search['warning'] = __('Database seems to be empty!');
$tab_export['warning'] = __('Database seems to be empty!');
}
$tab_structure['link'] = 'db_structure.php';
$tab_structure['text'] = __('Structure');
$tab_structure['icon'] = 'b_props.png';
$tab_sql['link'] = 'db_sql.php';
$tab_sql['args']['db_query_force'] = 1;
$tab_sql['text'] = __('SQL');
$tab_sql['icon'] = 'b_sql.png';
$tab_export['text'] = __('Export');
$tab_export['icon'] = 'b_export.png';
$tab_export['link'] = 'db_export.php';
$tab_search['text'] = __('Search');
$tab_search['icon'] = 'b_search.png';
$tab_search['link'] = 'db_search.php';
if (PMA_Tracker::isActive()) {
$tab_tracking['text'] = __('Tracking');
$tab_tracking['icon'] = 'eye.png';
$tab_tracking['link'] = 'db_tracking.php';
}
$tab_qbe['text'] = __('Query');
$tab_qbe['icon'] = 's_db.png';
$tab_qbe['link'] = 'db_qbe.php';
if ($cfgRelation['designerwork']) {
$tab_designer['text'] = __('Designer');
$tab_designer['icon'] = 'b_relations.png';
$tab_designer['link'] = 'pmd_general.php';
}
if (! $db_is_information_schema) {
$tab_import['link'] = 'db_import.php';
$tab_import['text'] = __('Import');
$tab_import['icon'] = 'b_import.png';
$tab_operation['link'] = 'db_operations.php';
$tab_operation['text'] = __('Operations');
$tab_operation['icon'] = 'b_tblops.png';
if ($is_superuser && !PMA_DRIZZLE) {
$tab_privileges['link'] = 'server_privileges.php';
$tab_privileges['args']['checkprivs'] = $db;
// stay on database view
$tab_privileges['args']['viewing_mode'] = 'db';
$tab_privileges['text'] = __('Privileges');
$tab_privileges['icon'] = 's_rights.png';
}
$tab_routines['link'] = 'db_routines.php';
$tab_routines['text'] = __('Routines');
$tab_routines['icon'] = 'b_routines.png';
$tab_events['link'] = 'db_events.php';
$tab_events['text'] = __('Events');
$tab_events['icon'] = 'b_events.png';
$tab_triggers['link'] = 'db_triggers.php';
$tab_triggers['text'] = __('Triggers');
$tab_triggers['icon'] = 'b_triggers.png';
}
/**
* Displays tab links
*/
$tabs = array();
$tabs[] =& $tab_structure;
$tabs[] =& $tab_sql;
$tabs[] =& $tab_search;
$tabs[] =& $tab_qbe;
$tabs[] =& $tab_export;
if (! $db_is_information_schema) {
$tabs[] =& $tab_import;
$tabs[] =& $tab_operation;
if ($is_superuser && !PMA_DRIZZLE) {
$tabs[] =& $tab_privileges;
}
if (!PMA_DRIZZLE) {
$tabs[] =& $tab_routines;
}
if (PMA_MYSQL_INT_VERSION >= 50106 && ! PMA_DRIZZLE) {
if (PMA_currentUserHasPrivilege('EVENT', $db)) {
$tabs[] =& $tab_events;
}
}
if (!PMA_DRIZZLE) {
if (PMA_currentUserHasPrivilege('TRIGGER', $db)) {
$tabs[] =& $tab_triggers;
}
}
}
if (PMA_Tracker::isActive()) {
$tabs[] =& $tab_tracking;
}
if (! $db_is_information_schema) {
if ($cfgRelation['designerwork']) {
$tabs[] =& $tab_designer;
}
}
$url_params['db'] = $db;
echo PMA_generate_html_tabs($tabs, $url_params);
unset($tabs);
/**
* Displays a message
*/
if (!empty($message)) {
PMA_showMessage($message);
unset($message);
}
?>

View File

@ -0,0 +1,125 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
// Display function
/**
* void PMA_TableHeader([bool $db_is_information_schema = false])
* display table header (<table><thead>...</thead><tbody>)
*
* @param boolean $db_is_information_schema
* @param boolean $replication
*/
function PMA_TableHeader($db_is_information_schema = false, $replication = false)
{
$cnt = 0; // Let's count the columns...
if ($db_is_information_schema) {
$action_colspan = 3;
} else {
$action_colspan = 6;
}
echo '<table class="data">' . "\n"
.'<thead>' . "\n"
.'<tr><th></th>' . "\n"
.' <th>' . PMA_SortableTableHeader(__('Table'), 'table') . '</th>' . "\n";
if ($replication) {
echo ' <th>' . "\n"
.' ' . __('Replication') . "\n"
.' </th>';
}
echo ' <th colspan="' . $action_colspan . '">' . "\n"
.' ' . __('Action') . "\n"
.' </th>'
// larger values are more interesting so default sort order is DESC
.' <th>' . PMA_SortableTableHeader(__('Rows'), 'records', 'DESC')
.PMA_showHint(PMA_sanitize(__('May be approximate. See [a@./Documentation.html#faq3_11@Documentation]FAQ 3.11[/a]'))) . "\n"
.' </th>' . "\n";
if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
echo ' <th>' . PMA_SortableTableHeader(__('Type'), 'type') . '</th>' . "\n";
$cnt++;
echo ' <th>' . PMA_SortableTableHeader(__('Collation'), 'collation') . '</th>' . "\n";
$cnt++;
}
if ($GLOBALS['is_show_stats']) {
// larger values are more interesting so default sort order is DESC
echo ' <th>' . PMA_SortableTableHeader(__('Size'), 'size', 'DESC') . '</th>' . "\n"
// larger values are more interesting so default sort order is DESC
. ' <th>' . PMA_SortableTableHeader(__('Overhead'), 'overhead', 'DESC') . '</th>' . "\n";
$cnt += 2;
}
echo '</tr>' . "\n";
echo '</thead>' . "\n";
echo '<tbody>' . "\n";
$GLOBALS['colspan_for_structure'] = $cnt + $action_colspan + 3;
} // end function PMA_TableHeader()
/**
* Creates a clickable column header for table information
*
* @param string $title title to use for the link
* @param string $sort corresponds to sortable data name mapped in libraries/db_info.inc.php
* @param string $initial_sort_order
* @return string link to be displayed in the table header
*/
function PMA_SortableTableHeader($title, $sort, $initial_sort_order = 'ASC')
{
// Set some defaults
$requested_sort = 'table';
$requested_sort_order = $future_sort_order = $initial_sort_order;
// If the user requested a sort
if (isset($_REQUEST['sort'])) {
$requested_sort = $_REQUEST['sort'];
if (isset($_REQUEST['sort_order'])) {
$requested_sort_order = $_REQUEST['sort_order'];
}
}
$order_img = '';
$order_link_params = array();
$order_link_params['title'] = __('Sort');
// If this column was requested to be sorted.
if ($requested_sort == $sort) {
if ($requested_sort_order == 'ASC') {
$future_sort_order = 'DESC';
// current sort order is ASC
$order_img = ' ' . PMA_getImage('s_asc.png', __('Ascending'), array('class' => 'sort_arrow', 'title' => ''));
$order_img .= ' ' . PMA_getImage('s_desc.png', __('Descending'), array('class' => 'sort_arrow hide', 'title' => ''));
// but on mouse over, show the reverse order (DESC)
$order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
// on mouse out, show current sort order (ASC)
$order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
} else {
$future_sort_order = 'ASC';
// current sort order is DESC
$order_img = ' ' . PMA_getImage('s_asc.png', __('Ascending'), array('class' => 'sort_arrow hide', 'title' => ''));
$order_img .= ' ' . PMA_getImage('s_desc.png', __('Descending'), array('class' => 'sort_arrow', 'title' => ''));
// but on mouse over, show the reverse order (ASC)
$order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
// on mouse out, show current sort order (DESC)
$order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
}
}
$_url_params = array(
'db' => $_REQUEST['db'],
);
$url = 'db_structure.php'.PMA_generate_common_url($_url_params);
// We set the position back to 0 every time they sort.
$url .= "&amp;pos=0&amp;sort=$sort&amp;sort_order=$future_sort_order";
return PMA_linkOrButton($url, $title . $order_img, $order_link_params);
} // end function PMA_SortableTableHeader()
?>

View File

@ -0,0 +1,86 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Ensure the database and the table exist (else move to the "parent" script)
* and display headers
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
if (empty($is_db)) {
if (strlen($db)) {
$is_db = @PMA_DBI_select_db($db);
} else {
$is_db = false;
}
if (! $is_db) {
// not a valid db name -> back to the welcome page
if (! defined('IS_TRANSFORMATION_WRAPPER')) {
$url_params = array('reload' => 1);
if (isset($message)) {
$url_params['message'] = $message;
}
if (! empty($sql_query)) {
$url_params['sql_query'] = $sql_query;
}
if (isset($show_as_php)) {
$url_params['show_as_php'] = $show_as_php;
}
PMA_sendHeaderLocation(
$cfg['PmaAbsoluteUri'] . 'main.php'
. PMA_generate_common_url($url_params, '&'));
}
exit;
}
} // end if (ensures db exists)
if (empty($is_table) && !defined('PMA_SUBMIT_MULT') && ! defined('TABLE_MAY_BE_ABSENT')) {
// Not a valid table name -> back to the db_sql.php
if (strlen($table)) {
$is_table = isset(PMA_Table::$cache[$db][$table]);
if (! $is_table) {
$_result = PMA_DBI_try_query(
'SHOW TABLES LIKE \'' . PMA_sqlAddSlashes($table, true) . '\';',
null, PMA_DBI_QUERY_STORE);
$is_table = @PMA_DBI_num_rows($_result);
PMA_DBI_free_result($_result);
}
} else {
$is_table = false;
}
if (! $is_table) {
if (! defined('IS_TRANSFORMATION_WRAPPER')) {
if (strlen($table)) {
// SHOW TABLES doesn't show temporary tables, so try select
// (as it can happen just in case temporary table, it should be
// fast):
/**
* @todo should this check really only happen if IS_TRANSFORMATION_WRAPPER?
*/
$_result = PMA_DBI_try_query(
'SELECT COUNT(*) FROM ' . PMA_backquote($table) . ';',
null, PMA_DBI_QUERY_STORE);
$is_table = ($_result && @PMA_DBI_num_rows($_result));
PMA_DBI_free_result($_result);
}
if (! $is_table) {
include './db_sql.php';
exit;
}
}
if (! $is_table) {
exit;
}
}
} // end if (ensures table exists)
?>

View File

@ -0,0 +1,442 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Wrappers for Drizzle extension classes
*
* Drizzle extension exposes libdrizzle functions and requires user to have it in mind while using them.
* This wrapper is not complete and hides a lot of original functionality, but allows for easy usage
* of the drizzle PHP extension.
*
* @package PhpMyAdmin-DBI-Drizzle
*/
// TODO: drizzle module segfaults while freeing resources, often. This allows at least for some development
function _drizzle_shutdown_flush() {
flush();
}
register_shutdown_function('_drizzle_shutdown_flush');
function _dlog_argstr($args)
{
$r = array();
foreach ($args as $arg) {
if (is_object($arg)) {
$r[] = get_class($arg);
} elseif (is_bool($arg)) {
$r[] = $arg ? 'true' : 'false';
} elseif (is_null($arg)) {
$r[] = 'null';
} else {
$r[] = $arg;
}
}
return implode(', ', $r);
}
function _dlog($end = false)
{
/*
static $fp = null;
if (!$fp) {
$fp = fopen('./drizzle_log.log', 'a');
flock($fp, LOCK_EX);
fwrite($fp, "\r\n[" . date('H:i:s') . "]\t" . $_SERVER['REQUEST_URI'] . "\r\n");
register_shutdown_function(function() use ($fp) {
fwrite($fp, '[' . date('H:i:s') . "]\tEND\r\n\r\n");
});
}
if ($end) {
fwrite($fp, '[' . date('H:i:s') . "]\tok\r\n");
} else {
$bt = debug_backtrace(true);
$caller = (isset($bt[1]['class']) ? $bt[1]['class'] . '::' : '') . $bt[1]['function'];
if ($bt[1]['function'] == '__call') {
$caller .= '^' . $bt[1]['args'][0];
$args = _dlog_argstr($bt[1]['args'][1]);
} else {
$args = _dlog_argstr($bt[1]['args']);
}
fwrite($fp, '[' . date('H:i:s') . "]\t" . $caller . "\t" . $args . "\r\n");
for ($i = 2; $i <= count($bt)-1; $i++) {
if (!isset($bt[$i])) {
break;
}
$caller = (isset($bt[$i]['class']) ? $bt[$i]['class'] . '::' : '') . $bt[$i]['function'];
$caller .= ' (' . $bt[$i]['file'] . ':' . $bt[$i]['line'] . ')';
fwrite($fp, str_repeat(' ', 20) . $caller . "\r\n");
}
}
//*/
}
/**
* Wrapper for Drizzle class
*/
class PMA_Drizzle extends Drizzle
{
/**
* Fetch mode: result rows contain column names
*/
const FETCH_ASSOC = 1;
/**
* Fetch mode: result rows contain only numeric indices
*/
const FETCH_NUM = 2;
/**
* Fetch mode: result rows have both column names and numeric indices
*/
const FETCH_BOTH = 3;
/**
* Result buffering: entire result set is buffered upon execution
*/
const BUFFER_RESULT = 1;
/**
* Result buffering: buffering occurs only on row level
*/
const BUFFER_ROW = 2;
/**
* Constructor
*/
public function __construct()
{_dlog();
parent::__construct();
}
/**
* Creates a new database conection using TCP
*
* @param $host
* @param $port
* @param $user
* @param $password
* @param $db
* @param $options
* @return PMA_DrizzleCon
*/
public function addTcp($host, $port, $user, $password, $db, $options)
{_dlog();
$dcon = parent::addTcp($host, $port, $user, $password, $db, $options);
return $dcon instanceof DrizzleCon
? new PMA_DrizzleCon($dcon)
: $dcon;
}
/**
* Creates a new connection using unix domain socket
*
* @param $uds
* @param $user
* @param $password
* @param $db
* @param $options
* @return PMA_DrizzleCon
*/
public function addUds($uds, $user, $password, $db, $options)
{_dlog();
$dcon = parent::addUds($uds, $user, $password, $db, $options);
return $dcon instanceof DrizzleCon
? new PMA_DrizzleCon($dcon)
: $dcon;
}
}
/**
* Wrapper around DrizzleCon class
*
* Its main task is to wrap results with PMA_DrizzleResult class
*/
class PMA_DrizzleCon
{
/**
* Instance of DrizzleCon class
* @var DrizzleCon
*/
private $dcon;
/**
* Result of the most recent query
* @var PMA_DrizzleResult
*/
private $lastResult;
/**
* Constructor
*
* @param DrizzleCon $dcon
*/
public function __construct(DrizzleCon $dcon)
{_dlog();
$this->dcon = $dcon;
}
/**
* Executes given query. Opens database connection if not already done.
*
* @param string $query
* @param int $bufferMode PMA_Drizzle::BUFFER_RESULT, PMA_Drizzle::BUFFER_ROW
* @param int $fetchMode PMA_Drizzle::FETCH_ASSOC, PMA_Drizzle::FETCH_NUM or PMA_Drizzle::FETCH_BOTH
* @return PMA_DrizzleResult
*/
public function query($query, $bufferMode = PMA_Drizzle::BUFFER_RESULT, $fetchMode = PMA_Drizzle::FETCH_ASSOC)
{_dlog();
$result = $this->dcon->query($query);
if ($result instanceof DrizzleResult) {
_dlog(true);
$this->lastResult = new PMA_DrizzleResult($result, $bufferMode, $fetchMode);
return $this->lastResult;
}
return $result;
}
/**
* Returns the number of rows affected by last query
*
* @return int|false
*/
public function affectedRows()
{
return $this->lastResult
? $this->lastResult->affectedRows()
: false;
}
/**
* Pass calls of undefined methods to DrizzleCon object
*
* @param $method
* @param $args
* @return mixed
*/
public function __call($method, $args)
{_dlog();
return call_user_func_array(array($this->dcon, $method), $args);
}
/**
* Returns original Drizzle connection object
*
* @return DrizzleCon
*/
public function getConnectionObject()
{_dlog();
return $this->dcon;
}
}
/**
* Wrapper around DrizzleResult. Allows for reading result rows as an associative array
* and hides complexity behind buffering.
*/
class PMA_DrizzleResult
{
/**
* Instamce of DrizzleResult class
* @var DrizzleResult
*/
private $dresult;
/**
* Fetch mode
* @var int
*/
private $fetchMode;
/**
* Buffering mode
* @var int
*/
private $bufferMode;
/**
* Cached column data
* @var DrizzleColumn[]
*/
private $columns = null;
/**
* Cached column names
* @var string[]
*/
private $columnNames = null;
/**
* Constructor
*
* @param DrizzleResult $dresult
* @param int $bufferMode
* @param int $fetchMode
*/
public function __construct(DrizzleResult $dresult, $bufferMode, $fetchMode)
{_dlog();
$this->dresult = $dresult;
$this->bufferMode = $bufferMode;
$this->fetchMode = $fetchMode;
if ($this->bufferMode == PMA_Drizzle::BUFFER_RESULT) {
$this->dresult->buffer();
}
}
/**
* Sets fetch mode
*
* @param int $fetchMode
*/
public function setFetchMode($fetchMode)
{_dlog();
$this->fetchMode = $fetchMode;
}
/**
* Reads information about columns contained in current result set into {@see $columns} and {@see $columnNames} arrays
*/
private function _readColumns()
{_dlog();
$this->columns = array();
$this->columnNames = array();
if ($this->bufferMode == PMA_Drizzle::BUFFER_RESULT) {
while (($column = $this->dresult->columnNext()) !== null) {
$this->columns[] = $column;
$this->columnNames[] = $column->name();
}
} else {
while (($column = $this->dresult->columnRead()) !== null) {
$this->columns[] = $column;
$this->columnNames[] = $column->name();
}
}
}
/**
* Returns columns in current result
*
* @return DrizzleColumn[]
*/
public function getColumns()
{_dlog();
if (!$this->columns) {
$this->_readColumns();
}
return $this->columns;
}
/**
* Returns number if columns in result
*
* @return int
*/
public function numColumns()
{_dlog();
return $this->dresult->columnCount();
}
/**
* Transforms result row to conform to current fetch mode
*
* @param mixed &$row
* @param int $fetchMode
*/
private function _transformResultRow(&$row, $fetchMode)
{
if (!$row) {
return;
}
switch ($fetchMode) {
case PMA_Drizzle::FETCH_ASSOC:
$row = array_combine($this->columnNames, $row);
break;
case PMA_Drizzle::FETCH_BOTH:
$length = count($row);
for ($i = 0; $i < $length; $i++) {
$row[$this->columnNames[$i]] = $row[$i];
}
break;
default:
break;
}
}
/**
* Fetches next for from this result set
*
* @param int $fetchMode fetch mode to use, if none given the default one is used
* @return array|null
*/
public function fetchRow($fetchMode = null)
{_dlog();
// read column names on first fetch, only buffered results allow for reading it later
if (!$this->columns) {
$this->_readColumns();
}
if ($fetchMode === null) {
$fetchMode = $this->fetchMode;
}
$row = null;
switch ($this->bufferMode) {
case PMA_Drizzle::BUFFER_RESULT:
$row = $this->dresult->rowNext();
break;
case PMA_Drizzle::BUFFER_ROW:
$row = $this->dresult->rowBuffer();
break;
}
$this->_transformResultRow($row, $fetchMode);
return $row;
}
/**
* Adjusts the result pointer to an arbitrary row in buffered result
*
* @param $row_index
* @return bool
*/
public function seek($row_index)
{_dlog();
if ($this->bufferMode != PMA_Drizzle::BUFFER_RESULT) {
trigger_error("Can't seek in an unbuffered result set", E_USER_WARNING);
return false;
}
// rowSeek always returns NULL (drizzle extension v.0.5, API v.7)
if ($row_index >= 0 && $row_index < $this->dresult->rowCount()) {
$this->dresult->rowSeek($row_index);
return true;
}
return false;
}
/**
* Returns the number of rows in buffered result set
*
* @return int|false
*/
public function numRows()
{_dlog();
if ($this->bufferMode != PMA_Drizzle::BUFFER_RESULT) {
trigger_error("Can't count rows in an unbuffered result set", E_USER_WARNING);
return false;
}
return $this->dresult->rowCount();
}
/**
* Returns the number of rows affected by query
*
* @return int|false
*/
public function affectedRows()
{_dlog();
return $this->dresult->affectedRows();
}
/**
* Frees resources taken by this result
*/
public function free()
{_dlog();
unset($this->columns);
unset($this->columnNames);
drizzle_result_free($this->dresult);
unset($this->dresult);
}
}

View File

@ -0,0 +1,603 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Interface to the Drizzle extension
*
* WARNING - EXPERIMENTAL, never use in production, drizzle module segfaults often and when you least expect it to
*
* TODO: This file and drizzle-wrappers.lib.php should be devoid of any segault related hacks.
* TODO: Crashing versions of drizzle module and/or libdrizzle should be blacklisted
*
* @package PhpMyAdmin-DBI-Drizzle
*/
if (! defined('PHPMYADMIN')) {
exit;
}
require_once './libraries/logging.lib.php';
require_once './libraries/dbi/drizzle-wrappers.lib.php';
/**
* MySQL client API
*/
if (!defined('PMA_MYSQL_CLIENT_API')) {
define('PMA_MYSQL_CLIENT_API', (int)drizzle_version());
}
/**
* Helper function for connecting to the database server
*
* @param PMA_Drizzle $drizzle
* @param string $host
* @param int $port
* @param string $uds
* @param string $user
* @param string $password
* @param string $db
* @param int $options
* @return PMA_DrizzleCon
*/
function PMA_DBI_real_connect($drizzle, $host, $port, $uds, $user, $password, $db = null, $options = DRIZZLE_CON_NONE)
{
if ($uds) {
$con = $drizzle->addUds($uds, $user, $password, $db, $options);
} else {
$con = $drizzle->addTcp($host, $port, $user, $password, $db, $options);
}
return $con;
}
/**
* connects to the database server
*
* @param string $user drizzle user name
* @param string $password drizzle user password
* @param bool $is_controluser
* @param array $server host/port/socket
* @param bool $auxiliary_connection (when true, don't go back to login if connection fails)
* @return mixed false on error or a mysqli object on success
*/
function PMA_DBI_connect($user, $password, $is_controluser = false, $server = null, $auxiliary_connection = false)
{
global $cfg;
if ($server) {
$server_port = (empty($server['port']))
? false
: (int)$server['port'];
$server_socket = (empty($server['socket']))
? ''
: $server['socket'];
$server['host'] = (empty($server['host']))
? 'localhost'
: $server['host'];
} else {
$server_port = (empty($cfg['Server']['port']))
? false
: (int) $cfg['Server']['port'];
$server_socket = (empty($cfg['Server']['socket']))
? null
: $cfg['Server']['socket'];
}
if (strtolower($GLOBALS['cfg']['Server']['connect_type']) == 'tcp') {
$GLOBALS['cfg']['Server']['socket'] = '';
}
$drizzle = new PMA_Drizzle();
$client_flags = 0;
/* Optionally compress connection */
if ($GLOBALS['cfg']['Server']['compress']) {
$client_flags |= DRIZZLE_CAPABILITIES_COMPRESS;
}
/* Optionally enable SSL */
if ($GLOBALS['cfg']['Server']['ssl']) {
$client_flags |= DRIZZLE_CAPABILITIES_SSL;
}
if (!$server) {
$link = @PMA_DBI_real_connect($drizzle, $cfg['Server']['host'], $server_port, $server_socket, $user, $password, false, $client_flags);
// Retry with empty password if we're allowed to
if ($link == false && isset($cfg['Server']['nopassword']) && $cfg['Server']['nopassword'] && !$is_controluser) {
$link = @PMA_DBI_real_connect($drizzle, $cfg['Server']['host'], $server_port, $server_socket, $user, null, false, $client_flags);
}
} else {
$link = @PMA_DBI_real_connect($drizzle, $server['host'], $server_port, $server_socket, $user, $password);
}
if ($link == false) {
if ($is_controluser) {
trigger_error(__('Connection for controluser as defined in your configuration failed.'), E_USER_WARNING);
return false;
}
// we could be calling PMA_DBI_connect() to connect to another
// server, for example in the Synchronize feature, so do not
// go back to main login if it fails
if (! $auxiliary_connection) {
PMA_log_user($user, 'drizzle-denied');
PMA_auth_fails();
} else {
return false;
}
} else {
PMA_DBI_postConnect($link, $is_controluser);
}
return $link;
}
/**
* selects given database
*
* @param string $dbname database name to select
* @param PMA_DrizzleCom $link connection object
* @return bool
*/
function PMA_DBI_select_db($dbname, $link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return $link->selectDb($dbname);
}
/**
* runs a query and returns the result
*
* @param string $query query to execute
* @param PMA_DrizzleCon $link connection object
* @param int $options
* @return PMA_DrizzleResult
*/
function PMA_DBI_real_query($query, $link, $options)
{
$buffer_mode = $options & PMA_DBI_QUERY_UNBUFFERED
? PMA_Drizzle::BUFFER_ROW
: PMA_Drizzle::BUFFER_RESULT;
$res = $link->query($query, $buffer_mode);
return $res;
}
/**
* returns array of rows with associative and numeric keys from $result
*
* @param PMA_DrizzleResult $result
* @return array
*/
function PMA_DBI_fetch_array($result)
{
return $result->fetchRow(PMA_Drizzle::FETCH_BOTH);
}
/**
* returns array of rows with associative keys from $result
*
* @param PMA_DrizzleResult $result
* @return array
*/
function PMA_DBI_fetch_assoc($result)
{
return $result->fetchRow(PMA_Drizzle::FETCH_ASSOC);
}
/**
* returns array of rows with numeric keys from $result
*
* @param PMA_DrizzleResult $result
* @return array
*/
function PMA_DBI_fetch_row($result)
{
return $result->fetchRow(PMA_Drizzle::FETCH_NUM);
}
/**
* Adjusts the result pointer to an arbitrary row in the result
*
* @param PMA_DrizzleResult $result
* @param int $offset
* @return boolean true on success, false on failure
*/
function PMA_DBI_data_seek($result, $offset)
{
return $result->seek($offset);
}
/**
* Frees memory associated with the result
*
* @param PMA_DrizzleResult $result
*/
function PMA_DBI_free_result($result)
{
if ($result instanceof PMA_DrizzleResult) {
$result->free();
}
}
/**
* Check if there are any more query results from a multi query
*
* @return bool false
*/
function PMA_DBI_more_results() {
// N.B.: PHP's 'mysql' extension does not support
// multi_queries so this function will always
// return false. Use the 'mysqli' extension, if
// you need support for multi_queries.
return false;
}
/**
* Prepare next result from multi_query
*
* @return bool false
*/
function PMA_DBI_next_result() {
// N.B.: PHP's 'mysql' extension does not support
// multi_queries so this function will always
// return false. Use the 'mysqli' extension, if
// you need support for multi_queries.
return false;
}
/**
* Returns a string representing the type of connection used
* @param PMA_DrizzleCon $link connection object
* @return string type of connection used
*/
function PMA_DBI_get_host_info($link = null)
{
if (null === $link) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
$str = $link->port()
? $link->host() . ':' . $link->port() . ' via TCP/IP'
: 'Localhost via UNIX socket';
return $str;
}
/**
* Returns the version of the Drizzle protocol used
* @param PMA_DrizzleCon $link connection object
* @return int version of the Drizzle protocol used
*/
function PMA_DBI_get_proto_info($link = null)
{
if (null === $link) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return $link->protocolVersion();
}
/**
* returns a string that represents the client library version
* @return string Drizzle client library version
*/
function PMA_DBI_get_client_info()
{
return 'libdrizzle (Drizzle ' . drizzle_version() . ')';
}
/**
* returns last error message or false if no errors occured
*
* @param PMA_DrizzleCon $link connection object
* @return string|bool $error or false
*/
function PMA_DBI_getError($link = null)
{
$GLOBALS['errno'] = 0;
/* Treat false same as null because of controllink */
if ($link === false) {
$link = null;
}
if (null === $link && isset($GLOBALS['userlink'])) {
$link =& $GLOBALS['userlink'];
// Do not stop now. We still can get the error code
// with mysqli_connect_errno()
// } else {
// return false;
}
if (null !== $link) {
$error_number = drizzle_con_errno($link->getConnectionObject());
$error_message = drizzle_con_error($link->getConnectionObject());
} else {
$error_number = drizzle_errno();
$error_message = drizzle_error();
}
if (0 == $error_number) {
return false;
}
// keep the error number for further check after the call to PMA_DBI_getError()
$GLOBALS['errno'] = $error_number;
return PMA_DBI_formatError($error_number, $error_message);
}
/**
* returns the number of rows returned by last query
*
* @param PMA_DrizzleResult $result
* @return string|int
*/
function PMA_DBI_num_rows($result)
{
// see the note for PMA_DBI_try_query();
if (!is_bool($result)) {
return @$result->numRows();
} else {
return 0;
}
}
/**
* returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
*
* @param PMA_DrizzleCon $link connection object
* @return string|int
*/
function PMA_DBI_insert_id($link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
// copied from mysql and mysqli
// When no controluser is defined, using mysqli_insert_id($link)
// does not always return the last insert id due to a mixup with
// the tracking mechanism, but this works:
return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
// Curiously, this problem does not happen with the mysql extension but
// there is another problem with BIGINT primary keys so PMA_DBI_insert_id()
// in the mysql extension also uses this logic.
}
/**
* returns the number of rows affected by last query
*
* @param PMA_DrizzleResult $link connection object
* @param bool $get_from_cache
* @return string|int
*/
function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
if ($get_from_cache) {
return $GLOBALS['cached_affected_rows'];
} else {
return $link->affectedRows();
}
}
/**
* returns metainfo for fields in $result
*
* @param PMA_DrizzleResult $result
* @return array meta info for fields in $result
*/
function PMA_DBI_get_fields_meta($result)
{
// Build an associative array for a type look up
$typeAr = array();
/*$typeAr[DRIZZLE_COLUMN_TYPE_DECIMAL] = 'real';
$typeAr[DRIZZLE_COLUMN_TYPE_NEWDECIMAL] = 'real';
$typeAr[DRIZZLE_COLUMN_TYPE_BIT] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_TINY] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_SHORT] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_LONG] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_FLOAT] = 'real';
$typeAr[DRIZZLE_COLUMN_TYPE_DOUBLE] = 'real';
$typeAr[DRIZZLE_COLUMN_TYPE_NULL] = 'null';
$typeAr[DRIZZLE_COLUMN_TYPE_TIMESTAMP] = 'timestamp';
$typeAr[DRIZZLE_COLUMN_TYPE_LONGLONG] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_INT24] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_DATE] = 'date';
$typeAr[DRIZZLE_COLUMN_TYPE_TIME] = 'date';
$typeAr[DRIZZLE_COLUMN_TYPE_DATETIME] = 'datetime';
$typeAr[DRIZZLE_COLUMN_TYPE_YEAR] = 'year';
$typeAr[DRIZZLE_COLUMN_TYPE_NEWDATE] = 'date';
$typeAr[DRIZZLE_COLUMN_TYPE_ENUM] = 'unknown';
$typeAr[DRIZZLE_COLUMN_TYPE_SET] = 'unknown';
$typeAr[DRIZZLE_COLUMN_TYPE_VIRTUAL] = 'unknown';
$typeAr[DRIZZLE_COLUMN_TYPE_TINY_BLOB] = 'blob';
$typeAr[DRIZZLE_COLUMN_TYPE_MEDIUM_BLOB] = 'blob';
$typeAr[DRIZZLE_COLUMN_TYPE_LONG_BLOB] = 'blob';
$typeAr[DRIZZLE_COLUMN_TYPE_BLOB] = 'blob';
$typeAr[DRIZZLE_COLUMN_TYPE_VAR_STRING] = 'string';
$typeAr[DRIZZLE_COLUMN_TYPE_VARCHAR] = 'string';
$typeAr[DRIZZLE_COLUMN_TYPE_STRING] = 'string';
$typeAr[DRIZZLE_COLUMN_TYPE_GEOMETRY] = 'geometry';*/
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB] = 'blob';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATE] = 'date';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATETIME] = 'datetime';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DOUBLE] = 'real';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_ENUM] = 'unknown';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONG] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONGLONG] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX] = 'unknown';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_NULL] = 'null';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TIMESTAMP] = 'timestamp';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TINY] = 'int';
$typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR] = 'string';
// array of DrizzleColumn
$columns = $result->getColumns();
// columns in a standarized format
$std_columns = array();
foreach ($columns as $k => $column) {
$c = new stdClass();
$c->name = $column->name();
$c->orgname = $column->origName();
$c->table = $column->table();
$c->orgtable = $column->origTable();
$c->def = $column->defaultValue();
$c->db = $column->db();
$c->catalog = $column->catalog();
// $column->maxSize() returns always 0 while size() seems
// to return a correct value (drizzle extension v.0.5, API v.7)
$c->max_length = $column->size();
$c->decimals = $column->decimals();
$c->charsetnr = $column->charset();
$c->type = $typeAr[$column->typeDrizzle()];
$c->_type = $column->type();
$c->flags = PMA_DBI_field_flags($result, $k);
$c->_flags = $column->flags();
$c->multiple_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY);
$c->primary_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_PRI_KEY);
$c->unique_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY);
$c->not_null = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NOT_NULL);
$c->unsigned = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNSIGNED);
$c->zerofill = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_ZEROFILL);
$c->numeric = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NUM);
$c->blob = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_BLOB);
$std_columns[] = $c;
}
return $std_columns;
}
/**
* return number of fields in given $result
*
* @param PMA_DrizzleResult $result
* @return int field count
*/
function PMA_DBI_num_fields($result)
{
return $result->numColumns();
}
/**
* returns the length of the given field $i in $result
*
* @param PMA_DrizzleResult $result
* @param int $i field
* @return int length of field
*/
function PMA_DBI_field_len($result, $i)
{
$colums = $result->getColumns();
return $colums[$i]->size();
}
/**
* returns name of $i. field in $result
*
* @param PMA_DrizzleResult $result
* @param int $i field
* @return string name of $i. field in $result
*/
function PMA_DBI_field_name($result, $i)
{
$colums = $result->getColumns();
return $colums[$i]->name();
}
/**
* returns concatenated string of human readable field flags
*
* @param PMA_DrizzleResult $result
* @param int $i field
* @return string field flags
*/
function PMA_DBI_field_flags($result, $i)
{
$columns = $result->getColumns();
$f = $columns[$i];
$type = $f->typeDrizzle();
$charsetnr = $f->charset();
$f = $f->flags();
$flags = '';
if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) {
$flags .= 'unique ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_NUM) {
$flags .= 'num ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_PART_KEY) {
$flags .= 'part_key ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_SET) {
$flags .= 'set ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_TIMESTAMP) {
$flags .= 'timestamp ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_AUTO_INCREMENT) {
$flags .= 'auto_increment ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_ENUM) {
$flags .= 'enum ';
}
// See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html:
// to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG
// but instead the charsetnr member of the MYSQL_FIELD
// structure. Watch out: some types like DATE returns 63 in charsetnr
// so we have to check also the type.
// Unfortunately there is no equivalent in the mysql extension.
if (($type == DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB || $type == DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR) && 63 == $charsetnr) {
$flags .= 'binary ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_ZEROFILL) {
$flags .= 'zerofill ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_UNSIGNED) {
$flags .= 'unsigned ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_BLOB) {
$flags .= 'blob ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY) {
$flags .= 'multiple_key ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY) {
$flags .= 'unique_key ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_PRI_KEY) {
$flags .= 'primary_key ';
}
if ($f & DRIZZLE_COLUMN_FLAGS_NOT_NULL) {
$flags .= 'not_null ';
}
return trim($flags);
}
?>

View File

@ -0,0 +1,476 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Interface to the classic MySQL extension
*
* @package PhpMyAdmin-DBI-MySQL
*/
if (! defined('PHPMYADMIN')) {
exit;
}
require_once './libraries/logging.lib.php';
/**
* MySQL client API
*/
if (! defined('PMA_MYSQL_CLIENT_API')) {
$client_api = explode('.', mysql_get_client_info());
define('PMA_MYSQL_CLIENT_API', (int)sprintf('%d%02d%02d', $client_api[0], $client_api[1], intval($client_api[2])));
unset($client_api);
}
/**
* Helper function for connecting to the database server
*
* @param string $server
* @param string $user
* @param string $password
* @param int $client_flags
* @param bool $persistent
* @return mixed false on error or a mysql connection resource on success
*/
function PMA_DBI_real_connect($server, $user, $password, $client_flags, $persistent = false)
{
global $cfg;
if (empty($client_flags)) {
if ($cfg['PersistentConnections'] || $persistent) {
$link = @mysql_pconnect($server, $user, $password);
} else {
$link = @mysql_connect($server, $user, $password);
}
} else {
if ($cfg['PersistentConnections'] || $persistent) {
$link = @mysql_pconnect($server, $user, $password, $client_flags);
} else {
$link = @mysql_connect($server, $user, $password, false, $client_flags);
}
}
return $link;
}
/**
* connects to the database server
*
* @param string $user mysql user name
* @param string $password mysql user password
* @param bool $is_controluser
* @param array $server host/port/socket/persistent
* @param bool $auxiliary_connection (when true, don't go back to login if connection fails)
* @return mixed false on error or a mysqli object on success
*/
function PMA_DBI_connect($user, $password, $is_controluser = false, $server = null, $auxiliary_connection = false)
{
global $cfg;
if ($server) {
$server_port = (empty($server['port']))
? ''
: ':' . (int)$server['port'];
$server_socket = (empty($server['socket']))
? ''
: ':' . $server['socket'];
} else {
$server_port = (empty($cfg['Server']['port']))
? ''
: ':' . (int)$cfg['Server']['port'];
$server_socket = (empty($cfg['Server']['socket']))
? ''
: ':' . $cfg['Server']['socket'];
}
$client_flags = 0;
// always use CLIENT_LOCAL_FILES as defined in mysql_com.h
// for the case where the client library was not compiled
// with --enable-local-infile
$client_flags |= 128;
/* Optionally compress connection */
if (defined('MYSQL_CLIENT_COMPRESS') && $cfg['Server']['compress']) {
$client_flags |= MYSQL_CLIENT_COMPRESS;
}
/* Optionally enable SSL */
if (defined('MYSQL_CLIENT_SSL') && $cfg['Server']['ssl']) {
$client_flags |= MYSQL_CLIENT_SSL;
}
if (!$server) {
$link = PMA_DBI_real_connect($cfg['Server']['host'] . $server_port . $server_socket, $user, $password, empty($client_flags) ? null : $client_flags);
// Retry with empty password if we're allowed to
if (empty($link) && $cfg['Server']['nopassword'] && !$is_controluser) {
$link = PMA_DBI_real_connect($cfg['Server']['host'] . $server_port . $server_socket, $user, '', empty($client_flags) ? null : $client_flags);
}
} else {
if (!isset($server['host'])) {
$link = PMA_DBI_real_connect($server_socket, $user, $password, null);
} else {
$link = PMA_DBI_real_connect($server['host'] . $server_port . $server_socket, $user, $password, null);
}
}
if (empty($link)) {
if ($is_controluser) {
trigger_error(__('Connection for controluser as defined in your configuration failed.'), E_USER_WARNING);
return false;
}
// we could be calling PMA_DBI_connect() to connect to another
// server, for example in the Synchronize feature, so do not
// go back to main login if it fails
if (! $auxiliary_connection) {
PMA_log_user($user, 'mysql-denied');
PMA_auth_fails();
} else {
return false;
}
} // end if
if (! $server) {
PMA_DBI_postConnect($link, $is_controluser);
}
return $link;
}
/**
* selects given database
*
* @param string $dbname name of db to select
* @param resource $link mysql link resource
* @return bool
*/
function PMA_DBI_select_db($dbname, $link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysql_select_db($dbname, $link);
}
/**
* runs a query and returns the result
*
* @param string $query query to run
* @param resource $link mysql link resource
* @param int $options
* @return mixed
*/
function PMA_DBI_real_query($query, $link, $options)
{
if ($options == ($options | PMA_DBI_QUERY_STORE)) {
return mysql_query($query, $link);
} elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED)) {
return mysql_unbuffered_query($query, $link);
} else {
return mysql_query($query, $link);
}
}
/**
* returns array of rows with associative and numeric keys from $result
*
* @param resource $result
* @return array
*/
function PMA_DBI_fetch_array($result)
{
return mysql_fetch_array($result, MYSQL_BOTH);
}
/**
* returns array of rows with associative keys from $result
*
* @param resource $result
* @return array
*/
function PMA_DBI_fetch_assoc($result)
{
return mysql_fetch_array($result, MYSQL_ASSOC);
}
/**
* returns array of rows with numeric keys from $result
*
* @param resource $result
* @return array
*/
function PMA_DBI_fetch_row($result)
{
return mysql_fetch_array($result, MYSQL_NUM);
}
/**
* Adjusts the result pointer to an arbitrary row in the result
*
* @param $result
* @param $offset
* @return bool true on success, false on failure
*/
function PMA_DBI_data_seek($result, $offset)
{
return mysql_data_seek($result, $offset);
}
/**
* Frees memory associated with the result
*
* @param resource $result
*/
function PMA_DBI_free_result($result)
{
if (is_resource($result) && get_resource_type($result) === 'mysql result') {
mysql_free_result($result);
}
}
/**
* Check if there are any more query results from a multi query
*
* @return bool false
*/
function PMA_DBI_more_results()
{
// N.B.: PHP's 'mysql' extension does not support
// multi_queries so this function will always
// return false. Use the 'mysqli' extension, if
// you need support for multi_queries.
return false;
}
/**
* Prepare next result from multi_query
*
* @return boo false
*/
function PMA_DBI_next_result()
{
// N.B.: PHP's 'mysql' extension does not support
// multi_queries so this function will always
// return false. Use the 'mysqli' extension, if
// you need support for multi_queries.
return false;
}
/**
* Returns a string representing the type of connection used
*
* @param resource $link mysql link
* @return string type of connection used
*/
function PMA_DBI_get_host_info($link = null)
{
if (null === $link) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysql_get_host_info($link);
}
/**
* Returns the version of the MySQL protocol used
*
* @param resource $link mysql link
* @return int version of the MySQL protocol used
*/
function PMA_DBI_get_proto_info($link = null)
{
if (null === $link) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysql_get_proto_info($link);
}
/**
* returns a string that represents the client library version
*
* @return string MySQL client library version
*/
function PMA_DBI_get_client_info()
{
return mysql_get_client_info();
}
/**
* returns last error message or false if no errors occured
*
* @param resource $link mysql link
* @return string|bool $error or false
*/
function PMA_DBI_getError($link = null)
{
$GLOBALS['errno'] = 0;
/* Treat false same as null because of controllink */
if ($link === false) {
$link = null;
}
if (null === $link && isset($GLOBALS['userlink'])) {
$link =& $GLOBALS['userlink'];
// Do not stop now. On the initial connection, we don't have a $link,
// we don't have a $GLOBALS['userlink'], but we can catch the error code
// } else {
// return false;
}
if (null !== $link && false !== $link) {
$error_number = mysql_errno($link);
$error_message = mysql_error($link);
} else {
$error_number = mysql_errno();
$error_message = mysql_error();
}
if (0 == $error_number) {
return false;
}
// keep the error number for further check after the call to PMA_DBI_getError()
$GLOBALS['errno'] = $error_number;
return PMA_DBI_formatError($error_number, $error_message);
}
/**
* returns the number of rows returned by last query
*
* @param resource $result
* @return string|int
*/
function PMA_DBI_num_rows($result)
{
if (!is_bool($result)) {
return mysql_num_rows($result);
} else {
return 0;
}
}
/**
* returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
*
* @param resource $link the mysql object
* @return string|int
*/
function PMA_DBI_insert_id($link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
// If the primary key is BIGINT we get an incorrect result
// (sometimes negative, sometimes positive)
// and in the present function we don't know if the PK is BIGINT
// so better play safe and use LAST_INSERT_ID()
//
return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
}
/**
* returns the number of rows affected by last query
*
* @param resource $link the mysql object
* @param bool $get_from_cache
* @return string|int
*/
function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
if ($get_from_cache) {
return $GLOBALS['cached_affected_rows'];
} else {
return mysql_affected_rows($link);
}
}
/**
* returns metainfo for fields in $result
*
* @todo add missing keys like in mysqli_query (decimals)
* @param resource $result
* @return array meta info for fields in $result
*/
function PMA_DBI_get_fields_meta($result)
{
$fields = array();
$num_fields = mysql_num_fields($result);
for ($i = 0; $i < $num_fields; $i++) {
$field = mysql_fetch_field($result, $i);
$field->flags = mysql_field_flags($result, $i);
$field->orgtable = mysql_field_table($result, $i);
$field->orgname = mysql_field_name($result, $i);
$fields[] = $field;
}
return $fields;
}
/**
* return number of fields in given $result
*
* @param resource $result
* @return int field count
*/
function PMA_DBI_num_fields($result)
{
return mysql_num_fields($result);
}
/**
* returns the length of the given field $i in $result
*
* @param resource $result
* @param int $i field
* @return int length of field
*/
function PMA_DBI_field_len($result, $i)
{
return mysql_field_len($result, $i);
}
/**
* returns name of $i. field in $result
*
* @param resource $result
* @param int $i field
* @return string name of $i. field in $result
*/
function PMA_DBI_field_name($result, $i)
{
return mysql_field_name($result, $i);
}
/**
* returns concatenated string of human readable field flags
*
* @param resource $result
* @param int $i field
* @return string field flags
*/
function PMA_DBI_field_flags($result, $i)
{
return mysql_field_flags($result, $i);
}
?>

View File

@ -0,0 +1,679 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Interface to the improved MySQL extension (MySQLi)
*
* @package PhpMyAdmin-DBI-MySQLi
*/
if (! defined('PHPMYADMIN')) {
exit;
}
require_once './libraries/logging.lib.php';
/**
* MySQL client API
*/
if (!defined('PMA_MYSQL_CLIENT_API')) {
$client_api = explode('.', mysqli_get_client_info());
define('PMA_MYSQL_CLIENT_API', (int)sprintf('%d%02d%02d', $client_api[0], $client_api[1], intval($client_api[2])));
unset($client_api);
}
/**
* some PHP versions are reporting extra messages like "No index used in query"
*/
mysqli_report(MYSQLI_REPORT_OFF);
/**
* some older mysql client libs are missing these constants ...
*/
if (! defined('MYSQLI_BINARY_FLAG')) {
define('MYSQLI_BINARY_FLAG', 128);
}
/**
* @see http://bugs.php.net/36007
*/
if (! defined('MYSQLI_TYPE_NEWDECIMAL')) {
define('MYSQLI_TYPE_NEWDECIMAL', 246);
}
if (! defined('MYSQLI_TYPE_BIT')) {
define('MYSQLI_TYPE_BIT', 16);
}
// for Drizzle
if (! defined('MYSQLI_TYPE_VARCHAR')) {
define('MYSQLI_TYPE_VARCHAR', 15);
}
/**
* Helper function for connecting to the database server
*
* @param mysqli $link
* @param string $host
* @param string $user
* @param string $password
* @param string $dbname
* @param int $server_port
* @param string $server_socket
* @param int $client_flags
* @param bool $persistent
* @return bool
*/
function PMA_DBI_real_connect($link, $host, $user, $password, $dbname, $server_port, $server_socket, $client_flags = null, $persistent = false)
{
global $cfg;
// mysqli persistent connections only on PHP 5.3+
if (PMA_PHP_INT_VERSION >= 50300) {
if ($cfg['PersistentConnections'] || $persistent) {
$host = 'p:' . $host;
}
}
if ($client_flags === null) {
return @mysqli_real_connect(
$link,
$host,
$user,
$password,
$dbname,
$server_port,
$server_socket
);
} else {
return @mysqli_real_connect(
$link,
$host,
$user,
$password,
$dbname,
$server_port,
$server_socket,
$client_flags
);
}
}
/**
* connects to the database server
*
* @param string $user mysql user name
* @param string $password mysql user password
* @param bool $is_controluser
* @param array $server host/port/socket
* @param bool $auxiliary_connection (when true, don't go back to login if connection fails)
* @return mixed false on error or a mysqli object on success
*/
function PMA_DBI_connect($user, $password, $is_controluser = false, $server = null, $auxiliary_connection = false)
{
global $cfg;
if ($server) {
$server_port = (empty($server['port']))
? false
: (int)$server['port'];
$server_socket = (empty($server['socket']))
? ''
: $server['socket'];
$server['host'] = (empty($server['host']))
? 'localhost'
: $server['host'];
} else {
$server_port = (empty($cfg['Server']['port']))
? false
: (int) $cfg['Server']['port'];
$server_socket = (empty($cfg['Server']['socket']))
? null
: $cfg['Server']['socket'];
}
// NULL enables connection to the default socket
$link = mysqli_init();
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
$client_flags = 0;
/* Optionally compress connection */
if ($cfg['Server']['compress'] && defined('MYSQLI_CLIENT_COMPRESS')) {
$client_flags |= MYSQLI_CLIENT_COMPRESS;
}
/* Optionally enable SSL */
if ($cfg['Server']['ssl'] && defined('MYSQLI_CLIENT_SSL')) {
$client_flags |= MYSQLI_CLIENT_SSL;
}
if (!$server) {
$return_value = @PMA_DBI_real_connect(
$link,
$cfg['Server']['host'],
$user,
$password,
false,
$server_port,
$server_socket,
$client_flags
);
// Retry with empty password if we're allowed to
if ($return_value == false && isset($cfg['Server']['nopassword']) && $cfg['Server']['nopassword'] && !$is_controluser) {
$return_value = @PMA_DBI_real_connect(
$link,
$cfg['Server']['host'],
$user,
'',
false,
$server_port,
$server_socket,
$client_flags
);
}
} else {
$return_value = @PMA_DBI_real_connect(
$link,
$server['host'],
$user,
$password,
false,
$server_port,
$server_socket
);
}
if ($return_value == false) {
if ($is_controluser) {
trigger_error(
__('Connection for controluser as defined in your configuration failed.'),
E_USER_WARNING
);
return false;
}
// we could be calling PMA_DBI_connect() to connect to another
// server, for example in the Synchronize feature, so do not
// go back to main login if it fails
if (! $auxiliary_connection) {
PMA_log_user($user, 'mysql-denied');
PMA_auth_fails();
} else {
return false;
}
} else {
PMA_DBI_postConnect($link, $is_controluser);
}
return $link;
}
/**
* selects given database
*
* @param string $dbname database name to select
* @param mysqli $link the mysqli object
* @return boolean
*/
function PMA_DBI_select_db($dbname, $link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysqli_select_db($link, $dbname);
}
/**
* runs a query and returns the result
*
* @param string $query query to execute
* @param mysqli $link mysqli object
* @param int $options
* @return mysqli_result|bool
*/
function PMA_DBI_real_query($query, $link, $options)
{
if ($options == ($options | PMA_DBI_QUERY_STORE)) {
$method = MYSQLI_STORE_RESULT;
} elseif ($options == ($options | PMA_DBI_QUERY_UNBUFFERED)) {
$method = MYSQLI_USE_RESULT;
} else {
$method = 0;
}
return mysqli_query($link, $query, $method);
}
/**
* returns array of rows with associative and numeric keys from $result
*
* @param mysqli_result $result
* @return array
*/
function PMA_DBI_fetch_array($result)
{
return mysqli_fetch_array($result, MYSQLI_BOTH);
}
/**
* returns array of rows with associative keys from $result
*
* @param mysqli_result $result
* @return array
*/
function PMA_DBI_fetch_assoc($result)
{
return mysqli_fetch_array($result, MYSQLI_ASSOC);
}
/**
* returns array of rows with numeric keys from $result
*
* @param mysqli_result $result
* @return array
*/
function PMA_DBI_fetch_row($result)
{
return mysqli_fetch_array($result, MYSQLI_NUM);
}
/**
* Adjusts the result pointer to an arbitrary row in the result
*
* @param $result
* @param $offset
* @return bool true on success, false on failure
*/
function PMA_DBI_data_seek($result, $offset)
{
return mysqli_data_seek($result, $offset);
}
/**
* Frees memory associated with the result
*
* @param mysqli_result $result
*/
function PMA_DBI_free_result($result)
{
if ($result instanceof mysqli_result) {
mysqli_free_result($result);
}
}
/**
* Check if there are any more query results from a multi query
*
* @param mysqli $link the mysqli object
* @return bool true or false
*/
function PMA_DBI_more_results($link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysqli_more_results($link);
}
/**
* Prepare next result from multi_query
*
* @param mysqli $link the mysqli object
* @return bool true or false
*/
function PMA_DBI_next_result($link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysqli_next_result($link);
}
/**
* Returns a string representing the type of connection used
*
* @param resource $link mysql link
* @return string type of connection used
*/
function PMA_DBI_get_host_info($link = null)
{
if (null === $link) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysqli_get_host_info($link);
}
/**
* Returns the version of the MySQL protocol used
*
* @param resource $link mysql link
* @return integer version of the MySQL protocol used
*/
function PMA_DBI_get_proto_info($link = null)
{
if (null === $link) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
return mysqli_get_proto_info($link);
}
/**
* returns a string that represents the client library version
*
* @return string MySQL client library version
*/
function PMA_DBI_get_client_info()
{
return mysqli_get_client_info();
}
/**
* returns last error message or false if no errors occured
*
* @param resource $link mysql link
* @return string|bool $error or false
*/
function PMA_DBI_getError($link = null)
{
$GLOBALS['errno'] = 0;
/* Treat false same as null because of controllink */
if ($link === false) {
$link = null;
}
if (null === $link && isset($GLOBALS['userlink'])) {
$link =& $GLOBALS['userlink'];
// Do not stop now. We still can get the error code
// with mysqli_connect_errno()
// } else {
// return false;
}
if (null !== $link) {
$error_number = mysqli_errno($link);
$error_message = mysqli_error($link);
} else {
$error_number = mysqli_connect_errno();
$error_message = mysqli_connect_error();
}
if (0 == $error_number) {
return false;
}
// keep the error number for further check after the call to PMA_DBI_getError()
$GLOBALS['errno'] = $error_number;
return PMA_DBI_formatError($error_number, $error_message);
}
/**
* returns the number of rows returned by last query
*
* @param mysqli_result $result
* @return string|int
*/
function PMA_DBI_num_rows($result)
{
// see the note for PMA_DBI_try_query();
if (!is_bool($result)) {
return @mysqli_num_rows($result);
} else {
return 0;
}
}
/**
* returns last inserted auto_increment id for given $link or $GLOBALS['userlink']
*
* @param mysqli $link the mysqli object
* @return string|int
*/
function PMA_DBI_insert_id($link = null)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
// When no controluser is defined, using mysqli_insert_id($link)
// does not always return the last insert id due to a mixup with
// the tracking mechanism, but this works:
return PMA_DBI_fetch_value('SELECT LAST_INSERT_ID();', 0, 0, $link);
// Curiously, this problem does not happen with the mysql extension but
// there is another problem with BIGINT primary keys so PMA_DBI_insert_id()
// in the mysql extension also uses this logic.
}
/**
* returns the number of rows affected by last query
*
* @param mysqli $link the mysqli object
* @param boolean $get_from_cache
* @return string|int
*/
function PMA_DBI_affected_rows($link = null, $get_from_cache = true)
{
if (empty($link)) {
if (isset($GLOBALS['userlink'])) {
$link = $GLOBALS['userlink'];
} else {
return false;
}
}
if ($get_from_cache) {
return $GLOBALS['cached_affected_rows'];
} else {
return mysqli_affected_rows($link);
}
}
/**
* returns metainfo for fields in $result
*
* @param mysqli_result $result
* @return array meta info for fields in $result
*/
function PMA_DBI_get_fields_meta($result)
{
// Build an associative array for a type look up
$typeAr = array();
$typeAr[MYSQLI_TYPE_DECIMAL] = 'real';
$typeAr[MYSQLI_TYPE_NEWDECIMAL] = 'real';
$typeAr[MYSQLI_TYPE_BIT] = 'int';
$typeAr[MYSQLI_TYPE_TINY] = 'int';
$typeAr[MYSQLI_TYPE_SHORT] = 'int';
$typeAr[MYSQLI_TYPE_LONG] = 'int';
$typeAr[MYSQLI_TYPE_FLOAT] = 'real';
$typeAr[MYSQLI_TYPE_DOUBLE] = 'real';
$typeAr[MYSQLI_TYPE_NULL] = 'null';
$typeAr[MYSQLI_TYPE_TIMESTAMP] = 'timestamp';
$typeAr[MYSQLI_TYPE_LONGLONG] = 'int';
$typeAr[MYSQLI_TYPE_INT24] = 'int';
$typeAr[MYSQLI_TYPE_DATE] = 'date';
$typeAr[MYSQLI_TYPE_TIME] = 'time';
$typeAr[MYSQLI_TYPE_DATETIME] = 'datetime';
$typeAr[MYSQLI_TYPE_YEAR] = 'year';
$typeAr[MYSQLI_TYPE_NEWDATE] = 'date';
$typeAr[MYSQLI_TYPE_ENUM] = 'unknown';
$typeAr[MYSQLI_TYPE_SET] = 'unknown';
$typeAr[MYSQLI_TYPE_TINY_BLOB] = 'blob';
$typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = 'blob';
$typeAr[MYSQLI_TYPE_LONG_BLOB] = 'blob';
$typeAr[MYSQLI_TYPE_BLOB] = 'blob';
$typeAr[MYSQLI_TYPE_VAR_STRING] = 'string';
$typeAr[MYSQLI_TYPE_STRING] = 'string';
$typeAr[MYSQLI_TYPE_VARCHAR] = 'string'; // for Drizzle
// MySQL returns MYSQLI_TYPE_STRING for CHAR
// and MYSQLI_TYPE_CHAR === MYSQLI_TYPE_TINY
// so this would override TINYINT and mark all TINYINT as string
// https://sf.net/tracker/?func=detail&aid=1532111&group_id=23067&atid=377408
//$typeAr[MYSQLI_TYPE_CHAR] = 'string';
$typeAr[MYSQLI_TYPE_GEOMETRY] = 'geometry';
$typeAr[MYSQLI_TYPE_BIT] = 'bit';
$fields = mysqli_fetch_fields($result);
// this happens sometimes (seen under MySQL 4.0.25)
if (!is_array($fields)) {
return false;
}
foreach ($fields as $k => $field) {
$fields[$k]->_type = $field->type;
$fields[$k]->type = $typeAr[$field->type];
$fields[$k]->_flags = $field->flags;
$fields[$k]->flags = PMA_DBI_field_flags($result, $k);
// Enhance the field objects for mysql-extension compatibilty
//$flags = explode(' ', $fields[$k]->flags);
//array_unshift($flags, 'dummy');
$fields[$k]->multiple_key
= (int) (bool) ($fields[$k]->_flags & MYSQLI_MULTIPLE_KEY_FLAG);
$fields[$k]->primary_key
= (int) (bool) ($fields[$k]->_flags & MYSQLI_PRI_KEY_FLAG);
$fields[$k]->unique_key
= (int) (bool) ($fields[$k]->_flags & MYSQLI_UNIQUE_KEY_FLAG);
$fields[$k]->not_null
= (int) (bool) ($fields[$k]->_flags & MYSQLI_NOT_NULL_FLAG);
$fields[$k]->unsigned
= (int) (bool) ($fields[$k]->_flags & MYSQLI_UNSIGNED_FLAG);
$fields[$k]->zerofill
= (int) (bool) ($fields[$k]->_flags & MYSQLI_ZEROFILL_FLAG);
$fields[$k]->numeric
= (int) (bool) ($fields[$k]->_flags & MYSQLI_NUM_FLAG);
$fields[$k]->blob
= (int) (bool) ($fields[$k]->_flags & MYSQLI_BLOB_FLAG);
}
return $fields;
}
/**
* return number of fields in given $result
*
* @param mysqli_result $result
* @return int field count
*/
function PMA_DBI_num_fields($result)
{
return mysqli_num_fields($result);
}
/**
* returns the length of the given field $i in $result
*
* @param mysqli_result $result
* @param int $i field
* @return int length of field
*/
function PMA_DBI_field_len($result, $i)
{
return mysqli_fetch_field_direct($result, $i)->length;
}
/**
* returns name of $i. field in $result
*
* @param mysqli_result $result
* @param int $i field
* @return string name of $i. field in $result
*/
function PMA_DBI_field_name($result, $i)
{
return mysqli_fetch_field_direct($result, $i)->name;
}
/**
* returns concatenated string of human readable field flags
*
* @param mysqli_result $result
* @param int $i field
* @return string field flags
*/
function PMA_DBI_field_flags($result, $i)
{
// This is missing from PHP 5.2.5, see http://bugs.php.net/bug.php?id=44846
if (! defined('MYSQLI_ENUM_FLAG')) {
define('MYSQLI_ENUM_FLAG', 256); // see MySQL source include/mysql_com.h
}
$f = mysqli_fetch_field_direct($result, $i);
$type = $f->type;
$charsetnr = $f->charsetnr;
$f = $f->flags;
$flags = '';
if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
$flags .= 'unique ';
}
if ($f & MYSQLI_NUM_FLAG) {
$flags .= 'num ';
}
if ($f & MYSQLI_PART_KEY_FLAG) {
$flags .= 'part_key ';
}
if ($f & MYSQLI_SET_FLAG) {
$flags .= 'set ';
}
if ($f & MYSQLI_TIMESTAMP_FLAG) {
$flags .= 'timestamp ';
}
if ($f & MYSQLI_AUTO_INCREMENT_FLAG) {
$flags .= 'auto_increment ';
}
if ($f & MYSQLI_ENUM_FLAG) {
$flags .= 'enum ';
}
// See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html:
// to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG
// but instead the charsetnr member of the MYSQL_FIELD
// structure. Watch out: some types like DATE returns 63 in charsetnr
// so we have to check also the type.
// Unfortunately there is no equivalent in the mysql extension.
if (($type == MYSQLI_TYPE_TINY_BLOB || $type == MYSQLI_TYPE_BLOB || $type == MYSQLI_TYPE_MEDIUM_BLOB || $type == MYSQLI_TYPE_LONG_BLOB || $type == MYSQLI_TYPE_VAR_STRING || $type == MYSQLI_TYPE_STRING) && 63 == $charsetnr) {
$flags .= 'binary ';
}
if ($f & MYSQLI_ZEROFILL_FLAG) {
$flags .= 'zerofill ';
}
if ($f & MYSQLI_UNSIGNED_FLAG) {
$flags .= 'unsigned ';
}
if ($f & MYSQLI_BLOB_FLAG) {
$flags .= 'blob ';
}
if ($f & MYSQLI_MULTIPLE_KEY_FLAG) {
$flags .= 'multiple_key ';
}
if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
$flags .= 'unique_key ';
}
if ($f & MYSQLI_PRI_KEY_FLAG) {
$flags .= 'primary_key ';
}
if ($f & MYSQLI_NOT_NULL_FLAG) {
$flags .= 'not_null ';
}
return trim($flags);
}
?>

View File

@ -0,0 +1,74 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Displays form for password change
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* autocomplete feature of IE kills the "onchange" event handler and it
* must be replaced by the "onpropertychange" one in this case
*/
$chg_evt_handler = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER >= 5)
? 'onpropertychange'
: 'onchange';
// Displays the form
?>
<form method="post" id="change_password_form" action="<?php echo $GLOBALS['PMA_PHP_SELF']; ?>" name="chgPassword" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? 'class="ajax" ' : ''); ?> onsubmit="return checkPassword(this)">
<?php echo PMA_generate_common_hidden_inputs();
if (strpos($GLOBALS['PMA_PHP_SELF'], 'server_privileges') !== false) {
echo '<input type="hidden" name="username" value="' . htmlspecialchars($username) . '" />' . "\n"
. '<input type="hidden" name="hostname" value="' . htmlspecialchars($hostname) . '" />' . "\n";
}?>
<fieldset id="fieldset_change_password">
<legend><?php echo __('Change password'); ?></legend>
<table class="data noclick">
<tr class="odd">
<td colspan="2">
<input type="radio" name="nopass" value="1" id="nopass_1" onclick="pma_pw.value = ''; pma_pw2.value = ''; this.checked = true" />
<label for="nopass_1"><?php echo __('No Password') . "\n"; ?></label>
</td>
</tr>
<tr class="even">
<td>
<input type="radio" name="nopass" value="0" id="nopass_0" onclick="document.getElementById('text_pma_pw').focus();" checked="checked " />
<label for="nopass_0"><?php echo __('Password'); ?>:&nbsp;</label>
</td>
<td>
<input type="password" name="pma_pw" id="text_pma_pw" size="10" class="textfield" <?php echo $chg_evt_handler; ?>="nopass[1].checked = true" />
&nbsp;&nbsp;
<?php echo __('Re-type'); ?>:&nbsp;
<input type="password" name="pma_pw2" id="text_pma_pw2" size="10" class="textfield" <?php echo $chg_evt_handler; ?>="nopass[1].checked = true" />
</td>
</tr>
<tr>
<td>
<?php echo __('Password Hashing'); ?>:
</td>
<td>
<input type="radio" name="pw_hash" id="radio_pw_hash_new" value="new" checked="checked" />
<label for="radio_pw_hash_new">
MySQL&nbsp;4.1+
</label>
</td>
</tr>
<tr id="tr_element_before_generate_password">
<td>&nbsp;</td>
<td>
<input type="radio" name="pw_hash" id="radio_pw_hash_old" value="old" />
<label for="radio_pw_hash_old">
<?php echo __('MySQL 4.0 compatible'); ?>
</label>
</td>
</tr>
</table>
</fieldset>
<fieldset id="fieldset_change_password_footer" class="tblFooters">
<input type="submit" name="change_pw" value="<?php echo(__('Go')); ?>" />
</fieldset>
</form>

View File

@ -0,0 +1,45 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Displays form for creating database (if user has privileges for that)
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
require_once './libraries/check_user_privileges.lib.php';
if ($is_create_db_priv) {
// The user is allowed to create a db
?>
<form method="post" action="db_create.php" id="create_database_form" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? 'class="ajax" ' : ''); ?>><strong>
<?php echo '<label for="text_create_db">' . __('Create database') . '</label>&nbsp;' . PMA_showMySQLDocu('SQL-Syntax', 'CREATE_DATABASE'); ?></strong><br />
<?php echo PMA_generate_common_hidden_inputs('', '', 5); ?>
<input type="hidden" name="reload" value="1" />
<input type="text" name="new_db" value="<?php echo $db_to_create; ?>" maxlength="64" class="textfield" id="text_create_db"/>
<?php
include_once './libraries/mysql_charsets.lib.php';
echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION, 'db_collation', null, null, true, 5);
if (! empty($dbstats)) {
echo '<input type="hidden" name="dbstats" value="1" />';
}
?>
<input type="submit" value="<?php echo __('Create'); ?>" id="buttonGo" />
</form>
<?php
} else {
?>
<!-- db creation no privileges message -->
<strong><?php echo __('Create database') . ':&nbsp;' . PMA_showMySQLDocu('SQL-Syntax', 'CREATE_DATABASE'); ?></strong><br />
<?php
echo '<span class="noPrivileges">'
. ($cfg['ErrorIconic'] ? PMA_getImage('s_error2.png', '', array('hspace' => 2, 'border' => 0, 'align' => 'middle')) : '')
. '' . __('No Privileges') .'</span>';
} // end create db form or message
?>

View File

@ -0,0 +1,63 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Displays form for creating a table (if user has privileges for that)
*
* for MySQL >= 4.1.0, we should be able to detect if user has a CREATE
* privilege by looking at SHOW GRANTS output;
* for < 4.1.0, it could be more difficult because the logic tries to
* detect the current host and it might be expressed in many ways; also
* on a shared server, the user might be unable to define a controluser
* that has the proper rights to the "mysql" db;
* so we give up and assume that user has the right to create a table
*
* Note: in this case we could even skip the following "foreach" logic
*
* Addendum, 2006-01-19: ok, I give up. We got some reports about servers
* where the hostname field in mysql.user is not the same as the one
* in mysql.db for a user. In this case, SHOW GRANTS does not return
* the db-specific privileges. And probably, those users are on a shared
* server, so can't set up a control user with rights to the "mysql" db.
* We cannot reliably detect the db-specific privileges, so no more
* warnings about the lack of privileges for CREATE TABLE. Tested
* on MySQL 5.0.18.
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
require_once './libraries/check_user_privileges.lib.php';
$is_create_table_priv = true;
?>
<form id="create_table_form_minimal" method="post" action="tbl_create.php"<?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?>>
<fieldset>
<legend>
<?php
if ($GLOBALS['cfg']['PropertiesIconic']) {
echo PMA_getImage('b_newtbl.png');
}
echo __('Create table');
?>
</legend>
<?php echo PMA_generate_common_hidden_inputs($db); ?>
<div class="formelement">
<?php echo __('Name'); ?>:
<input type="text" name="table" maxlength="64" size="30" />
</div>
<div class="formelement">
<?php echo __('Number of columns'); ?>:
<input type="text" name="num_fields" size="2" />
</div>
<div class="clearfloat"></div>
</fieldset>
<fieldset class="tblFooters">
<input type="submit" value="<?php echo __('Go'); ?>" />
</fieldset>
</form>

View File

@ -0,0 +1,351 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
// Get relations & co. status
$cfgRelation = PMA_getRelationsParam();
require_once './libraries/file_listing.php';
require_once './libraries/plugin_interface.lib.php';
function PMA_exportCheckboxCheck($str)
{
if (isset($GLOBALS['cfg']['Export'][$str]) && $GLOBALS['cfg']['Export'][$str]) {
echo ' checked="checked"';
}
}
function PMA_exportIsActive($what, $val)
{
if (isset($GLOBALS['cfg']['Export'][$what]) && $GLOBALS['cfg']['Export'][$what] == $val) {
echo ' checked="checked"';
}
}
/* Scan for plugins */
$export_list = PMA_getPlugins('./libraries/export/', array('export_type' => $export_type, 'single_table' => isset($single_table)));
/* Fail if we didn't find any plugin */
if (empty($export_list)) {
PMA_Message::error( __('Could not load export plugins, please check your installation!'))->display();
include './libraries/footer.inc.php';
}
?>
<form method="post" action="export.php" name="dump">
<?php
if ($export_type == 'server') {
echo PMA_generate_common_hidden_inputs('', '', 1);
} elseif ($export_type == 'database') {
echo PMA_generate_common_hidden_inputs($db, '', 1);
} else {
echo PMA_generate_common_hidden_inputs($db, $table, 1);
}
// just to keep this value for possible next display of this form after saving on server
if (isset($single_table)) {
echo '<input type="hidden" name="single_table" value="TRUE" />' . "\n";
}
echo '<input type="hidden" name="export_type" value="' . $export_type . '" />' . "\n";
// If the export method was not set, the default is quick
if (isset($_GET['export_method'])) {
$cfg['Export']['method'] = $_GET['export_method'];
} elseif (! isset($cfg['Export']['method'])) {
$cfg['Export']['method'] = 'quick';
}
// The export method (quick, custom or custom-no-form)
echo '<input type="hidden" name="export_method" value="' . htmlspecialchars($cfg['Export']['method']) . '" />';
if (isset($_GET['sql_query'])) {
echo '<input type="hidden" name="sql_query" value="' . htmlspecialchars($_GET['sql_query']) . '" />' . "\n";
} elseif (! empty($sql_query)) {
echo '<input type="hidden" name="sql_query" value="' . htmlspecialchars($sql_query) . '" />' . "\n";
}
?>
<div class="exportoptions" id="header">
<h2>
<?php echo PMA_getImage('b_export.png', __('Export')); ?>
<?php
if ($export_type == 'server') {
echo __('Exporting databases from the current server');
} elseif ($export_type == 'database') {
printf(__('Exporting tables from "%s" database'), htmlspecialchars($db));
} else {
printf(__('Exporting rows from "%s" table'), htmlspecialchars($table));
}?>
</h2>
</div>
<div class="exportoptions" id="quick_or_custom">
<h3><?php echo __('Export Method:'); ?></h3>
<ul>
<li>
<?php echo '<input type="radio" name="quick_or_custom" value="quick" id="radio_quick_export"';
if (isset($_GET['quick_or_custom'])) {
$export_method = $_GET['quick_or_custom'];
if ($export_method == 'custom' || $export_method == 'custom_no_form') {
echo ' />';
} else {
echo ' checked="checked" />';
}
} elseif ($cfg['Export']['method'] == 'custom' || $cfg['Export']['method'] == 'custom-no-form') {
echo ' />';
} else {
echo ' checked="checked" />';
}
echo '<label for ="radio_quick_export">' . __('Quick - display only the minimal options') . '</label>'; ?>
</li>
<li>
<?php echo '<input type="radio" name="quick_or_custom" value="custom" id="radio_custom_export"';
if (isset($_GET['quick_or_custom'])) {
$export_method = $_GET['quick_or_custom'];
if ($export_method == 'custom' || $export_method == 'custom_no_form') {
echo ' checked="checked" />';
} else {
echo ' />';
}
} elseif ($cfg['Export']['method'] == 'custom' || $cfg['Export']['method'] == 'custom-no-form') {
echo ' checked="checked" />';
} else {
echo ' />';
}
echo '<label for="radio_custom_export">' . __('Custom - display all possible options') . '</label>';?>
</li>
</ul>
</div>
<div class="exportoptions" id="databases_and_tables">
<?php
if ($export_type == 'server') {
echo '<h3>' . __('Database(s):') . '</h3>';
} else if ($export_type == 'database') {
echo '<h3>' . __('Table(s):') . '</h3>';
}
if (! empty($multi_values)) {
echo $multi_values;
}
?>
</div>
<?php if (strlen($table) && ! isset($num_tables) && ! PMA_Table::isMerge($db, $table)) { ?>
<div class="exportoptions" id="rows">
<h3><?php echo __('Rows:'); ?></h3>
<ul>
<li>
<?php if (isset($_GET['allrows']) && $_GET['allrows'] == 1) {
echo '<input type="radio" name="allrows" value="0" id="radio_allrows_0" />';
} else {
echo '<input type="radio" name="allrows" value="0" id="radio_allrows_0" checked="checked" />';
}
echo '<label for ="radio_allrows_0">' . __('Dump some row(s)') . '</label>'; ?>
<ul>
<li><label for="limit_to"><?php echo __('Number of rows:') . '</label> <input type="text" id="limit_to" name="limit_to" size="5" value="'
. ((isset($_GET['limit_to'])) ? htmlspecialchars($_GET['limit_to']) : ((isset($unlim_num_rows) ? $unlim_num_rows : PMA_Table::countRecords($db, $table))))
. '" onfocus="this.select()" />' ?></li>
<li><label for="limit_from"><?php echo __('Row to begin at:') . '</label> <input type="text" id="limit_from" name="limit_from" value="'
. ((isset($_GET['limit_from'])) ? htmlspecialchars($_GET['limit_from']) : '0')
. '" size="5" onfocus="this.select()" />'; ?></li>
</ul>
</li>
<li>
<?php if (isset($_GET['allrows']) && $_GET['allrows'] == 0) {
echo '<input type="radio" name="allrows" value="1" id="radio_allrows_1" />';
} else {
echo '<input type="radio" name="allrows" value="1" id="radio_allrows_1" checked="checked" />';
}
echo ' <label for="radio_allrows_1">' . __('Dump all rows') . '</label>';?>
</li>
</ul>
</div>
<?php } ?>
<?php if (isset($cfg['SaveDir']) && !empty($cfg['SaveDir'])) { ?>
<div class="exportoptions" id="output_quick_export">
<h3><?php echo __('Output:'); ?></h3>
<ul>
<li>
<input type="checkbox" name="quick_export_onserver" value="saveit"
id="checkbox_quick_dump_onserver"
<?php PMA_exportCheckboxCheck('quick_export_onserver'); ?> />
<label for="checkbox_quick_dump_onserver">
<?php echo sprintf(__('Save on server in the directory <b>%s</b>'), htmlspecialchars(PMA_userDir($cfg['SaveDir']))); ?>
</label>
</li>
<li>
<input type="checkbox" name="quick_export_onserverover" value="saveitover"
id="checkbox_quick_dump_onserverover"
<?php PMA_exportCheckboxCheck('quick_export_onserver_overwrite'); ?> />
<label for="checkbox_quick_dump_onserverover"><?php echo __('Overwrite existing file(s)'); ?></label>
</li>
</ul>
</div>
<?php } ?>
<div class="exportoptions" id="output">
<h3><?php echo __('Output:'); ?></h3>
<ul id="ul_output">
<li>
<input type="radio" name="output_format" value="sendit" id="radio_dump_asfile" <?php isset($_GET['repopulate']) ? '' : PMA_exportCheckboxCheck('asfile'); ?> />
<label for="radio_dump_asfile"><?php echo __('Save output to a file'); ?></label>
<ul id="ul_save_asfile">
<?php if (isset($cfg['SaveDir']) && !empty($cfg['SaveDir'])) { ?>
<li>
<input type="checkbox" name="onserver" value="saveit"
id="checkbox_dump_onserver"
<?php PMA_exportCheckboxCheck('onserver'); ?> />
<label for="checkbox_dump_onserver">
<?php echo sprintf(__('Save on server in the directory <b>%s</b>'), htmlspecialchars(PMA_userDir($cfg['SaveDir']))); ?>
</label>
</li>
<li>
<input type="checkbox" name="onserverover" value="saveitover"
id="checkbox_dump_onserverover"
<?php PMA_exportCheckboxCheck('onserver_overwrite'); ?> />
<label for="checkbox_dump_onserverover"><?php echo __('Overwrite existing file(s)'); ?></label>
</li>
<?php } ?>
<li>
<label for="filename_template" class="desc">
<?php
echo __('File name template:');
$trans = new PMA_Message;
$trans->addMessage(__('@SERVER@ will become the server name'));
if ($export_type == 'database' || $export_type == 'table') {
$trans->addMessage(__(', @DATABASE@ will become the database name'));
if ($export_type == 'table') {
$trans->addMessage(__(', @TABLE@ will become the table name'));
}
}
$message = new PMA_Message(__('This value is interpreted using %1$sstrftime%2$s, so you can use time formatting strings. Additionally the following transformations will happen: %3$s. Other text will be kept as is. See the %4$sFAQ%5$s for details.'));
$message->addParam('<a href="' . PMA_linkURL(PMA_getPHPDocLink('function.strftime.php')). '" target="documentation" title="'
. __('Documentation') . '">', false);
$message->addParam('</a>', false);
$message->addParam($trans);
$message->addParam('<a href="Documentation.html#faq6_27" target="documentation">', false);
$message->addParam('</a>', false);
echo PMA_showHint($message);
?>
</label>
<input type="text" name="filename_template" id="filename_template"
<?php
echo ' value="';
if (isset($_GET['filename_template'])) {
echo htmlspecialchars($_GET['filename_template']);
} else {
if ($export_type == 'database') {
echo htmlspecialchars($GLOBALS['PMA_Config']->getUserValue(
'pma_db_filename_template',
$GLOBALS['cfg']['Export']['file_template_database']));
} elseif ($export_type == 'table') {
echo htmlspecialchars($GLOBALS['PMA_Config']->getUserValue(
'pma_table_filename_template',
$GLOBALS['cfg']['Export']['file_template_table']));
} else {
echo htmlspecialchars($GLOBALS['PMA_Config']->getUserValue(
'pma_server_filename_template',
$GLOBALS['cfg']['Export']['file_template_server']));
}
}
echo '"';
?>
/>
<input type="checkbox" name="remember_template"
id="checkbox_remember_template"
<?php PMA_exportCheckboxCheck('remember_file_template'); ?> />
<label for="checkbox_remember_template">
<?php echo __('use this for future exports'); ?></label>
</li>
<?php
// charset of file
if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE) {
echo ' <li><label for="select_charset_of_file" class="desc">'
. __('Character set of the file:') . '</label>' . "\n";
reset($cfg['AvailableCharsets']);
echo '<select id="select_charset_of_file" name="charset_of_file" size="1">';
foreach ($cfg['AvailableCharsets'] as $temp_charset) {
echo '<option value="' . $temp_charset . '"';
if (isset($_GET['charset_of_file']) && ($_GET['charset_of_file'] != $temp_charset)) {
echo '';
} elseif ((empty($cfg['Export']['charset']) && $temp_charset == 'utf-8')
|| $temp_charset == $cfg['Export']['charset']) {
echo ' selected="selected"';
}
echo '>' . $temp_charset . '</option>';
} // end foreach
echo '</select></li>';
} // end if
?>
<?php
if (isset($_GET['compression'])) {
$selected_compression = $_GET['compression'];
} elseif (isset($cfg['Export']['compression'])) {
$selected_compression = $cfg['Export']['compression'];
} else {
$selected_compression = "none";
}
// zip, gzip and bzip2 encode features
$is_zip = ($cfg['ZipDump'] && @function_exists('gzcompress'));
$is_gzip = ($cfg['GZipDump'] && @function_exists('gzencode'));
$is_bzip2 = ($cfg['BZipDump'] && @function_exists('bzcompress'));
if ($is_zip || $is_gzip || $is_bzip2) { ?>
<li>
<label for="compression" class="desc"><?php echo __('Compression:'); ?></label>
<select id="compression" name="compression">
<option value="none"><?php echo __('None'); ?></option>
<?php if ($is_zip) { ?>
<option value="zip" <?php echo ($selected_compression == "zip") ? 'selected="selected"' : ''; ?>><?php echo __('zipped'); ?></option>
<?php } if ($is_gzip) { ?>
<option value="gzip" <?php echo ($selected_compression == "gzip") ? 'selected="selected"' : ''; ?>><?php echo __('gzipped'); ?></option>
<?php } if ($is_bzip2) { ?>
<option value="bzip2" <?php echo ($selected_compression == "bzip2") ? 'selected="selected"' : ''; ?>><?php echo __('bzipped'); ?></option>
<?php } ?>
</select>
</li>
<?php } else { ?>
<input type="hidden" name="compression" value="<?php echo $selected_compression; ?>" />
<?php } ?>
</ul>
</li>
<li><input type="radio" id="radio_view_as_text" name="output_format" value="astext" <?php echo (isset($_GET['repopulate']) || $GLOBALS['cfg']['Export']['asfile'] == false) ? 'checked="checked"' : '' ?>/><label for="radio_view_as_text"><?php echo __('View output as text'); ?></label></li>
</ul>
</div>
<div class="exportoptions" id="format">
<h3><?php echo __('Format:'); ?></h3>
<?php echo PMA_pluginGetChoice('Export', 'what', $export_list, 'format'); ?>
</div>
<div class="exportoptions" id="format_specific_opts">
<h3><?php echo __('Format-specific options:'); ?></h3>
<p class="no_js_msg" id="scroll_to_options_msg"><?php echo __('Scroll down to fill in the options for the selected format and ignore the options for other formats.'); ?></p>
<?php echo PMA_pluginGetOptions('Export', $export_list); ?>
</div>
<?php if (function_exists('PMA_set_enc_form')) { ?>
<!-- Encoding setting form appended by Y.Kawada -->
<!-- Japanese encoding setting -->
<div class="exportoptions" id="kanji_encoding">
<h3><?php echo __('Encoding Conversion:'); ?></h3>
<?php echo PMA_set_enc_form(' '); ?>
</div>
<?php } ?>
<div class="exportoptions" id="submit">
<?php PMA_externalBug(__('SQL compatibility mode'), 'mysql', '50027', '14515'); ?>
<input type="submit" value="<?php echo __('Go'); ?>" id="buttonGo" />
</div>
</form>

View File

@ -0,0 +1,269 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
require_once './libraries/file_listing.php';
require_once './libraries/plugin_interface.lib.php';
require_once './libraries/display_import_ajax.lib.php';
/* Scan for plugins */
$import_list = PMA_getPlugins('./libraries/import/', $import_type);
/* Fail if we didn't find any plugin */
if (empty($import_list)) {
PMA_Message::error(__('Could not load import plugins, please check your installation!'))->display();
include './libraries/footer.inc.php';
}
?>
<iframe id="import_upload_iframe" name="import_upload_iframe" width="1" height="1" style="display: none;"></iframe>
<div id="import_form_status" style="display: none;"></div>
<div id="importmain">
<img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" alt="ajax clock" style="display: none;" />
<script type="text/javascript">
//<![CDATA[
$(document).ready( function() {
// add event when user click on "Go" button
$('#buttonGo').bind('click', function() {
$('#upload_form_form').css("display", "none"); // hide form
$('#upload_form_status').css("display", "inline"); // show progress bar
$('#upload_form_status_info').css("display", "inline"); // - || -
<?php
if ($_SESSION[$SESSION_KEY]["handler"]!="noplugin") {
?>
$('#upload_form_status').html('<div class="upload_progress_bar_outer"><div id="status" class="upload_progress_bar_inner"></div></div>'); // add the progress bar
var finished = false;
var percent = 0.0;
var total = 0;
var complete = 0;
var perform_upload;
var periodical_upload;
var request_upload = [];
perform_upload = function () {
new $.getJSON(
'import_status.php?id=<?php echo $upload_id ; ?>&<?php echo PMA_generate_common_url(); ?>',
{},
function(response) {
finished = response.finished;
percent = response.percent;
total = response.total;
complete = response.complete;
if (total==0 && complete==0 && percent==0) {
$('#upload_form_status_info').html('<img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" alt="ajax clock" /> <?php echo PMA_jsFormat(__('The file being uploaded is probably larger than the maximum allowed size or this is a known bug in webkit based (Safari, Google Chrome, Arora etc.) browsers.'), false); ?>');
$('#upload_form_status').css("display", "none");
} else {
$('#upload_form_status_info').html(' '+Math.round(percent)+'%, '+complete+'/'+total);
$('#status').animate({width: Math.round(percent)*2+'px'},150);
} // else
if (finished==true) {
$('#importmain').css('display', 'none');
$('#import_form_status').css('display', 'inline');
$('#import_form_status').html('<img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" alt="ajax clock" /> <?php echo PMA_jsFormat(__('The file is being processed, please be patient.'), false); ?> ');
$('#import_form_status').load('import_status.php?message=true&<?php echo PMA_generate_common_url(); ?>'); // loads the message, either success or mysql error
<?php
// reload the left sidebar when the import is finished
$GLOBALS['reload']=true;
PMA_reloadNavigation(true);
?>
} // if finished
else {
window.setTimeout(perform_upload, 1000);
}
}
);
}
window.setTimeout(perform_upload, 1000);
<?php
} else { // no plugin available
?>
$('#upload_form_status_info').html('<img src="<?php echo $GLOBALS['pmaThemeImage'];?>ajax_clock_small.gif" alt="ajax clock" /> <?php echo PMA_jsFormat(__('Please be patient, the file is being uploaded. Details about the upload are not available.'), false) . PMA_showDocu('faq2_9'); ?>');
$('#upload_form_status').css("display", "none");
<?php
} // else
?>
}); // onclick
}); // domready
document.write('<form action="import.php" method="post" enctype="multipart/form-data" name="import"<?php if ($_SESSION[$SESSION_KEY]["handler"]!="noplugin") echo ' target="import_upload_iframe"'; ?>>');
//]]>
</script>
<noscript>
<form action="import.php" method="post" enctype="multipart/form-data" name="import">
</noscript>
<input type="hidden" name="<?php echo $ID_KEY; ?>" value="<?php echo $upload_id ; ?>" />
<?php
if ($import_type == 'server') {
echo PMA_generate_common_hidden_inputs('', '', 1);
} elseif ($import_type == 'database') {
echo PMA_generate_common_hidden_inputs($db, '', 1);
} else {
echo PMA_generate_common_hidden_inputs($db, $table, 1);
}
echo ' <input type="hidden" name="import_type" value="' . $import_type . '" />'."\n";
?>
<div class="exportoptions" id="header">
<h2>
<?php echo PMA_getImage('b_import.png', __('Import')); ?>
<?php
if ($import_type == 'server') {
echo __('Importing into the current server');
} elseif ($import_type == 'database') {
printf(__('Importing into the database "%s"'), htmlspecialchars($db));
} else {
printf(__('Importing into the table "%s"'), htmlspecialchars($table));
}?>
</h2>
</div>
<div class="importoptions">
<h3><?php echo __('File to Import:'); ?></h3>
<?php
// zip, gzip and bzip2 encode features
$compressions = array();
if ($cfg['GZipDump'] && @function_exists('gzopen')) {
$compressions[] = 'gzip';
}
if ($cfg['BZipDump'] && @function_exists('bzopen')) {
$compressions[] = 'bzip2';
}
if ($cfg['ZipDump'] && @function_exists('zip_open')) {
$compressions[] = 'zip';
}
// We don't have show anything about compression, when no supported
if ($compressions != array()) {
echo '<div class="formelementrow" id="compression_info">';
printf(__('File may be compressed (%s) or uncompressed.'), implode(", ", $compressions));
echo '<br />';
echo __('A compressed file\'s name must end in <b>.[format].[compression]</b>. Example: <b>.sql.zip</b>');
echo '</div>';
}?>
<div class="formelementrow" id="upload_form">
<?php if ($GLOBALS['is_upload'] && !empty($cfg['UploadDir'])) { ?>
<ul>
<li>
<input type="radio" name="file_location" id="radio_import_file" />
<?php PMA_browseUploadFile($max_upload_size); ?>
</li>
<li>
<input type="radio" name="file_location" id="radio_local_import_file" />
<?php PMA_selectUploadFile($import_list, $cfg['UploadDir']); ?>
</li>
</ul>
<?php } else if ($GLOBALS['is_upload']) {
$uid = uniqid("");
PMA_browseUploadFile($max_upload_size);
} else if (!$GLOBALS['is_upload']) {
PMA_Message::notice(__('File uploads are not allowed on this server.'))->display();
} else if (!empty($cfg['UploadDir'])) {
PMA_selectUploadFile($import_list, $cfg['UploadDir']);
} // end if (web-server upload directory)
?>
</div>
<div class="formelementrow" id="charaset_of_file">
<?php // charset of file
if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE) {
echo '<label for="charset_of_file">' . __('Character set of the file:') . '</label>';
reset($cfg['AvailableCharsets']);
echo '<select id="charset_of_file" name="charset_of_file" size="1">';
foreach ($cfg['AvailableCharsets'] as $temp_charset) {
echo '<option value="' . htmlentities($temp_charset) . '"';
if ((empty($cfg['Import']['charset']) && $temp_charset == 'utf-8')
|| $temp_charset == $cfg['Import']['charset']) {
echo ' selected="selected"';
}
echo '>' . htmlentities($temp_charset) . '</option>';
}
echo ' </select><br />';
} else {
echo '<label for="charset_of_file">' . __('Character set of the file:') . '</label>' . "\n";
echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_CHARSET, 'charset_of_file', 'charset_of_file', 'utf8', false);
} // end if (recoding)
?>
</div>
</div>
<div class="importoptions">
<h3><?php echo __('Partial Import:'); ?></h3>
<?php
if (isset($timeout_passed) && $timeout_passed) {
echo '<div class="formelementrow">' . "\n";
echo '<input type="hidden" name="skip" value="' . $offset . '" />';
echo sprintf(__('Previous import timed out, after resubmitting will continue from position %d.'), $offset) . '';
echo '</div>' . "\n";
}
?>
<div class="formelementrow">
<input type="checkbox" name="allow_interrupt" value="yes"
id="checkbox_allow_interrupt" <?php echo PMA_pluginCheckboxCheck('Import', 'allow_interrupt'); ?>/>
<label for="checkbox_allow_interrupt"><?php echo __('Allow the interruption of an import in case the script detects it is close to the PHP timeout limit. <i>(This might be good way to import large files, however it can break transactions.)</i>'); ?></label><br />
</div>
<?php
if (! (isset($timeout_passed) && $timeout_passed)) {
?>
<div class="formelementrow">
<label for="text_skip_queries"><?php echo __('Number of rows to skip, starting from the first row:'); ?></label>
<input type="text" name="skip_queries" value="<?php echo PMA_pluginGetDefault('Import', 'skip_queries');?>" id="text_skip_queries" />
</div>
<?php
} else {
// If timeout has passed,
// do not show the Skip dialog to avoid the risk of someone
// entering a value here that would interfere with "skip"
?>
<input type="hidden" name="skip_queries" value="<?php echo PMA_pluginGetDefault('Import', 'skip_queries');?>" id="text_skip_queries" />
<?php
}
?>
</div>
<div class="importoptions">
<h3><?php echo __('Format:'); ?></h3>
<?php echo PMA_pluginGetChoice('Import', 'format', $import_list); ?>
<div id="import_notification"></div>
</div>
<div class="importoptions" id="format_specific_opts">
<h3><?php echo __('Format-Specific Options:'); ?></h3>
<p class="no_js_msg" id="scroll_to_options_msg">Scroll down to fill in the options for the selected format and ignore the options for other formats.</p>
<?php echo PMA_pluginGetOptions('Import', $import_list); ?>
</div>
<div class="clearfloat"></div>
</div>
<?php
// Encoding setting form appended by Y.Kawada
if (function_exists('PMA_set_enc_form')) { ?>
<div class="importoptions" id="kanji_encoding">
<h3><?php echo __('Encoding Conversion:'); ?></h3>
<?php echo PMA_set_enc_form(' '); ?>
</div>
<?php }
echo "\n";
?>
<div class="importoptions" id="submit">
<input type="submit" value="<?php echo __('Go'); ?>" id="buttonGo" />
</div>
</form>

View File

@ -0,0 +1,91 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
if (!defined('PHPMYADMIN')) {
exit;
}
/**
* constant for differenciating array in $_SESSION variable
*/
$SESSION_KEY = '__upload_status';
/**
* sets default plugin for handling the import process
*/
$_SESSION[$SESSION_KEY]["handler"] = "";
/**
* unique ID for each upload
*/
$upload_id = uniqid("");
/**
* list of available plugins
*/
$plugins = array(
"uploadprogress",
"apc",
"noplugin"
); // available plugins. Each plugin has own checkfunction in display_import_ajax.lib.php and own file with functions in upload_#KEY#.php
// select available plugin
foreach ($plugins as $plugin) {
$check = "PMA_import_" . $plugin . "Check";
if ($check()) {
$_SESSION[$SESSION_KEY]["handler"] = $plugin;
include_once "import/upload/" . $plugin . ".php";
break;
}
}
/**
* Checks if APC bar extension is available and configured correctly.
*
* @return true if APC extension is available and if rfc1867 is enabled, false if it is not
*/
function PMA_import_apcCheck()
{
if (! extension_loaded('apc') || ! function_exists('apc_fetch') || ! function_exists('getallheaders')) {
return false;
}
return (ini_get('apc.enabled') && ini_get('apc.rfc1867'));
}
/**
* Checks if UploadProgress bar extension is available.
*
* @return true if UploadProgress extension is available, false if it is not
*/
function PMA_import_uploadprogressCheck()
{
if (! function_exists("uploadprogress_get_info") || ! function_exists('getallheaders')) {
return false;
}
return true;
}
/**
* Default plugin for handling import. If no other plugin is available, noplugin is used.
*
* @return true
*/
function PMA_import_nopluginCheck()
{
return true;
}
/**
* The function outputs json encoded status of uploaded. It uses PMA_getUploadStatus, which is defined in plugin's file.
*
* @param $id - ID of transfer, usually $upload_id from display_import_ajax.lib.php
*/
function PMA_importAjaxStatus($id)
{
header('Content-type: application/json');
echo json_encode(PMA_getUploadStatus($id));
}
?>

View File

@ -0,0 +1,103 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Code for displaying language selection
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Sorts available languages by their true english names
*
* @param array the array to be sorted
* @param mixed a required parameter
* @return the sorted array
* @access private
*/
function PMA_language_cmp(&$a, &$b)
{
return (strcmp($a[1], $b[1]));
} // end of the 'PMA_language_cmp()' function
/**
* Displays for for language selection
*
* @access public
*/
function PMA_select_language($use_fieldset = false, $show_doc = true)
{
global $cfg, $lang;
?>
<form method="post" action="index.php" target="_parent">
<?php
$_form_params = array(
'db' => $GLOBALS['db'],
'table' => $GLOBALS['table'],
);
echo PMA_generate_common_hidden_inputs($_form_params);
// For non-English, display "Language" with emphasis because it's
// not a proper word in the current language; we show it to help
// people recognize the dialog
$language_title = __('Language')
. (__('Language') != 'Language' ? ' - <em>Language</em>' : '');
if ($show_doc) {
$language_title .= PMA_showDocu('faq7_2');
}
if ($use_fieldset) {
echo '<fieldset><legend xml:lang="en" dir="ltr">' . $language_title . '</legend>';
} else {
echo '<bdo xml:lang="en" dir="ltr">' . $language_title . ':</bdo>';
}
?>
<select name="lang" class="autosubmit" xml:lang="en" dir="ltr">
<?php
uasort($GLOBALS['available_languages'], 'PMA_language_cmp');
foreach ($GLOBALS['available_languages'] as $id => $tmplang) {
$lang_name = PMA_langName($tmplang);
//Is current one active?
if ($lang == $id) {
$selected = ' selected="selected"';
} else {
$selected = '';
}
echo ' ';
echo '<option value="' . $id . '"' . $selected . '>' . $lang_name
. '</option>' . "\n";
}
?>
</select>
<?php
if ($use_fieldset) {
echo '</fieldset>';
}
?>
<noscript>
<?php
if ($use_fieldset) {
echo '<fieldset class="tblFooters">';
}
?>
<input type="submit" value="Go" />
<?php
if ($use_fieldset) {
echo '</fieldset>';
}
?>
</noscript>
</form>
<?php
} // End of function PMA_select_language
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
*
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_bdb extends PMA_StorageEngine
{
/**
* @return array variable names
*/
function getVariables()
{
return array(
'version_bdb' => array(
'title' => __('Version information'),
),
'bdb_cache_size' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'bdb_home' => array(
),
'bdb_log_buffer_size' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'bdb_logdir' => array(
),
'bdb_max_lock' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'bdb_shared_data' => array(
),
'bdb_tmpdir' => array(
),
'bdb_data_direct' => array(
),
'bdb_lock_detect' => array(
),
'bdb_log_direct' => array(
),
'bdb_no_recover' => array(
),
'bdb_no_sync' => array(
),
'skip_sync_bdb_logs' => array(
),
'sync_bdb_logs' => array(
),
);
}
/**
* @return string LIKE pattern
*/
function getVariablesLikePattern()
{
return '%bdb%';
}
/**
* returns string with filename for the MySQL helppage
* about this storage engne
*
* @return string mysql helppage filename
*/
function getMysqlHelpPage()
{
return 'bdb';
}
}
?>

View File

@ -0,0 +1,20 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
* Load BDB class.
*/
require_once './libraries/engines/bdb.lib.php';
/**
* This is same as BDB.
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_berkeleydb extends PMA_StorageEngine_bdb
{
}
?>

View File

@ -0,0 +1,25 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
*
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_binlog extends PMA_StorageEngine
{
/**
* returns string with filename for the MySQL helppage
* about this storage engne
*
* @return string mysql helppage filename
*/
function getMysqlHelpPage()
{
return 'binary-log';
}
}
?>

View File

@ -0,0 +1,20 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin-Engines
*/
/**
*
*/
require_once './libraries/engines/innodb.lib.php';
/**
*
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_innobase extends PMA_StorageEngine_innodb
{
}
?>

View File

@ -0,0 +1,350 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
*
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_innodb extends PMA_StorageEngine
{
/**
* @return array
*/
function getVariables()
{
return array(
'innodb_data_home_dir' => array(
'title' => __('Data home directory'),
'desc' => __('The common part of the directory path for all InnoDB data files.'),
),
'innodb_data_file_path' => array(
'title' => __('Data files'),
),
'innodb_autoextend_increment' => array(
'title' => __('Autoextend increment'),
'desc' => __('The increment size for extending the size of an autoextending tablespace when it becomes full.'),
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_buffer_pool_size' => array(
'title' => __('Buffer pool size'),
'desc' => __('The size of the memory buffer InnoDB uses to cache data and indexes of its tables.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'innodb_additional_mem_pool_size' => array(
'title' => 'innodb_additional_mem_pool_size',
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'innodb_buffer_pool_awe_mem_mb' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'innodb_checksums' => array(
),
'innodb_commit_concurrency' => array(
),
'innodb_concurrency_tickets' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_doublewrite' => array(
),
'innodb_fast_shutdown' => array(
),
'innodb_file_io_threads' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_file_per_table' => array(
),
'innodb_flush_log_at_trx_commit' => array(
),
'innodb_flush_method' => array(
),
'innodb_force_recovery' => array(
),
'innodb_lock_wait_timeout' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_locks_unsafe_for_binlog' => array(
),
'innodb_log_arch_dir' => array(
),
'innodb_log_archive' => array(
),
'innodb_log_buffer_size' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'innodb_log_file_size' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'innodb_log_files_in_group' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_log_group_home_dir' => array(
),
'innodb_max_dirty_pages_pct' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_max_purge_lag' => array(
),
'innodb_mirrored_log_groups' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_open_files' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_support_xa' => array(
),
'innodb_sync_spin_loops' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_table_locks' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_BOOLEAN,
),
'innodb_thread_concurrency' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'innodb_thread_sleep_delay' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
);
}
/**
* @return string SQL query LIKE pattern
*/
function getVariablesLikePattern()
{
return 'innodb\\_%';
}
/**
* @return array detail pages
*/
function getInfoPages()
{
if ($this->support < PMA_ENGINE_SUPPORT_YES) {
return array();
}
$pages = array();
$pages['Bufferpool'] = __('Buffer Pool');
$pages['Status'] = __('InnoDB Status');
return $pages;
}
/**
* returns html tables with stats over inno db buffer pool
*
* @return string html table with stats
*/
function getPageBufferpool()
{
// The following query is only possible because we know
// that we are on MySQL 5 here (checked above)!
// side note: I love MySQL 5 for this. :-)
$sql = '
SHOW STATUS
WHERE Variable_name LIKE \'Innodb\\_buffer\\_pool\\_%\'
OR Variable_name = \'Innodb_page_size\';';
$status = PMA_DBI_fetch_result($sql, 0, 1);
$output = '<table class="data" id="table_innodb_bufferpool_usage">' . "\n"
. ' <caption class="tblHeaders">' . "\n"
. ' ' . __('Buffer Pool Usage') . "\n"
. ' </caption>' . "\n"
. ' <tfoot>' . "\n"
. ' <tr>' . "\n"
. ' <th colspan="2">' . "\n"
. ' ' . __('Total') . "\n"
. ' : ' . PMA_formatNumber(
$status['Innodb_buffer_pool_pages_total'], 0)
. '&nbsp;' . __('pages')
. ' / '
. join('&nbsp;',
PMA_formatByteDown($status['Innodb_buffer_pool_pages_total'] * $status['Innodb_page_size'])) . "\n"
. ' </th>' . "\n"
. ' </tr>' . "\n"
. ' </tfoot>' . "\n"
. ' <tbody>' . "\n"
. ' <tr class="odd">' . "\n"
. ' <th>' . __('Free pages') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_pages_free'], 0)
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="even">' . "\n"
. ' <th>' . __('Dirty pages') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_pages_dirty'], 0)
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="odd">' . "\n"
. ' <th>' . __('Pages containing data') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_pages_data'], 0) . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="even">' . "\n"
. ' <th>' . __('Pages to be flushed') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_pages_flushed'], 0) . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="odd">' . "\n"
. ' <th>' . __('Busy pages') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_pages_misc'], 0) . "\n"
. '</td>' . "\n"
. ' </tr>';
// not present at least since MySQL 5.1.40
if (isset($status['Innodb_buffer_pool_pages_latched'])) {
$output .= ' <tr class="even">'
. ' <th>' . __('Latched pages') . '</th>'
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_pages_latched'], 0)
. '</td>'
. ' </tr>';
}
$output .= ' </tbody>' . "\n"
. '</table>' . "\n\n"
. '<table class="data" id="table_innodb_bufferpool_activity">' . "\n"
. ' <caption class="tblHeaders">' . "\n"
. ' ' . __('Buffer Pool Activity') . "\n"
. ' </caption>' . "\n"
. ' <tbody>' . "\n"
. ' <tr class="odd">' . "\n"
. ' <th>' . __('Read requests') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_read_requests'], 0) . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="even">' . "\n"
. ' <th>' . __('Write requests') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_write_requests'], 0) . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="odd">' . "\n"
. ' <th>' . __('Read misses') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_reads'], 0) . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="even">' . "\n"
. ' <th>' . __('Write waits') . '</th>' . "\n"
. ' <td class="value">'
. PMA_formatNumber($status['Innodb_buffer_pool_wait_free'], 0) . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="odd">' . "\n"
. ' <th>' . __('Read misses in %') . '</th>' . "\n"
. ' <td class="value">'
. ($status['Innodb_buffer_pool_read_requests'] == 0
? '---'
: htmlspecialchars(PMA_formatNumber($status['Innodb_buffer_pool_reads'] * 100 / $status['Innodb_buffer_pool_read_requests'], 3, 2)) . ' %') . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' <tr class="even">' . "\n"
. ' <th>' . __('Write waits in %') . '</th>' . "\n"
. ' <td class="value">'
. ($status['Innodb_buffer_pool_write_requests'] == 0
? '---'
: htmlspecialchars(PMA_formatNumber($status['Innodb_buffer_pool_wait_free'] * 100 / $status['Innodb_buffer_pool_write_requests'], 3, 2)) . ' %') . "\n"
. '</td>' . "\n"
. ' </tr>' . "\n"
. ' </tbody>' . "\n"
. '</table>' . "\n";
return $output;
}
/**
* returns InnoDB status
*
* @return string result of SHOW INNODB STATUS inside pre tags
*/
function getPageStatus()
{
return '<pre id="pre_innodb_status">' . "\n"
. htmlspecialchars(PMA_DBI_fetch_value('SHOW INNODB STATUS;', 0, 'Status')) . "\n"
. '</pre>' . "\n";
}
/**
* returns content for page $id
*
* @param string $id page id
* @return string html output
*/
function getPage($id)
{
if (! array_key_exists($id, $this->getInfoPages())) {
return false;
}
$id = 'getPage' . $id;
return $this->$id();
}
/**
* returns string with filename for the MySQL helppage
* about this storage engne
*
* @return string mysql helppage filename
*/
function getMysqlHelpPage()
{
return 'innodb';
}
/**
*
* Gets the InnoDB plugin version number
* http://www.innodb.com/products/innodb_plugin
* (do not confuse this with phpMyAdmin's storage engine plugins!)
*
* @return string the version number, or empty if not running as a plugin
*/
function getInnodbPluginVersion()
{
return PMA_DBI_fetch_value('SELECT @@innodb_version;');
}
/**
*
* Gets the InnoDB file format
* (works only for the InnoDB plugin)
* http://www.innodb.com/products/innodb_plugin
* (do not confuse this with phpMyAdmin's storage engine plugins!)
*
* @return string the InnoDB file format
*/
function getInnodbFileFormat()
{
return PMA_DBI_fetch_value("SHOW GLOBAL VARIABLES LIKE 'innodb_file_format';", 0, 1);
}
/**
*
* Verifies if this server supports the innodb_file_per_table feature
* (works only for the InnoDB plugin)
* http://www.innodb.com/products/innodb_plugin
* (do not confuse this with phpMyAdmin's storage engine plugins!)
*
* @return boolean whether this feature is supported or not
*/
function supportsFilePerTable()
{
$innodb_file_per_table = PMA_DBI_fetch_value("SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';", 0, 1);
if ($innodb_file_per_table == 'ON') {
return true;
} else {
return false;
}
}
}
?>

View File

@ -0,0 +1,28 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
* the MEMORY (HEAP) storage engine
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_memory extends PMA_StorageEngine
{
/**
* returns array with variable names dedicated to MyISAM storage engine
*
* @return array variable names
*/
function getVariables()
{
return array(
'max_heap_table_size' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
);
}
}
?>

View File

@ -0,0 +1,15 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
*
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_merge extends PMA_StorageEngine
{
}
?>

View File

@ -0,0 +1,30 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
*
*/
require_once './libraries/engines/merge.lib.php';
/**
*
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_mrg_myisam extends PMA_StorageEngine_merge
{
/**
* returns string with filename for the MySQL helppage
* about this storage engne
*
* @return string mysql helppage filename
*/
function getMysqlHelpPage()
{
return 'merge';
}
}
?>

View File

@ -0,0 +1,63 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
* the MyISAM storage engine
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_myisam extends PMA_StorageEngine
{
/**
* returns array with variable names dedicated to MyISAM storage engine
*
* @return array variable names
*/
function getVariables()
{
return array(
'myisam_data_pointer_size' => array(
'title' => __('Data pointer size'),
'desc' => __('The default pointer size in bytes, to be used by CREATE TABLE for MyISAM tables when no MAX_ROWS option is specified.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'myisam_recover_options' => array(
'title' => __('Automatic recovery mode'),
'desc' => __('The mode for automatic recovery of crashed MyISAM tables, as set via the --myisam-recover server startup option.'),
),
'myisam_max_sort_file_size' => array(
'title' => __('Maximum size for temporary sort files'),
'desc' => __('The maximum size of the temporary file MySQL is allowed to use while re-creating a MyISAM index (during REPAIR TABLE, ALTER TABLE, or LOAD DATA INFILE).'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'myisam_max_extra_sort_file_size' => array(
'title' => __('Maximum size for temporary files on index creation'),
'desc' => __('If the temporary file used for fast MyISAM index creation would be larger than using the key cache by the amount specified here, prefer the key cache method.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'myisam_repair_threads' => array(
'title' => __('Repair threads'),
'desc' => __('If this value is greater than 1, MyISAM table indexes are created in parallel (each index in its own thread) during the repair by sorting process.'),
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
),
'myisam_sort_buffer_size' => array(
'title' => __('Sort buffer size'),
'desc' => __('The buffer that is allocated when sorting MyISAM indexes during a REPAIR TABLE or when creating indexes with CREATE INDEX or ALTER TABLE.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'myisam_stats_method' => array(
),
'delay_key_write' => array(
),
'bulk_insert_buffer_size' => array(
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
),
'skip_external_locking' => array(
),
);
}
}
?>

View File

@ -0,0 +1,44 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
*
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_ndbcluster extends PMA_StorageEngine
{
/**
* @return array
*/
function getVariables()
{
return array(
'ndb_connectstring' => array(
),
);
}
/**
* @return string SQL query LIKE pattern
*/
function getVariablesLikePattern()
{
return 'ndb\\_%';
}
/**
* returns string with filename for the MySQL helppage
* about this storage engne
*
* @return string mysql helppage filename
*/
function getMysqlHelpPage()
{
return 'ndbcluster';
}
}
?>

View File

@ -0,0 +1,106 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
* the PBMS daemon
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_pbms extends PMA_StorageEngine
{
/**
* returns array with variable names dedicated to PBMS daemon
*
* @return array variable names
*/
function engine_init()
{
$this->engine = "PBMS";
$this->title = "PrimeBase Media Streaming Daemon";
$this->comment = "Provides BLOB streaming service for storage engines,";
$this->support = PMA_ENGINE_SUPPORT_YES;
}
function getVariables()
{
return array(
'pbms_garbage_threshold' => array(
'title' => __('Garbage Threshold'),
'desc' => __('The percentage of garbage in a repository file before it is compacted.'),
'type' => PMA_ENGINE_DETAILS_TYPE_PLAINTEXT
),
'pbms_port' => array(
'title' => __('Port'),
'desc' => __('The port for the PBMS stream-based communications. Setting this value to 0 will disable HTTP communication with the daemon.'),
'type' => PMA_ENGINE_DETAILS_TYPE_PLAINTEXT
),
'pbms_repository_threshold' => array(
'title' => __('Repository Threshold'),
'desc' => __('The maximum size of a BLOB repository file. You may use Kb, MB or GB to indicate the unit of the value. A value in bytes is assumed when no unit is specified.'),
'type' => PMA_ENGINE_DETAILS_TYPE_PLAINTEXT
),
'pbms_temp_blob_timeout' => array(
'title' => __('Temp Blob Timeout'),
'desc' => __('The timeout, in seconds, for temporary BLOBs. Uploaded BLOB data is removed after this time, unless they are referenced by a record in the database.'),
'type' => PMA_ENGINE_DETAILS_TYPE_PLAINTEXT
),
'pbms_temp_log_threshold' => array(
'title' => __('Temp Log Threshold'),
'desc' => __('The maximum size of a temporary BLOB log file. You may use Kb, MB or GB to indicate the unit of the value. A value in bytes is assumed when no unit is specified.'),
'type' => PMA_ENGINE_DETAILS_TYPE_PLAINTEXT
),
'pbms_max_keep_alive' => array(
'title' => __('Max Keep Alive'),
'desc' => __('The timeout for inactive connection with the keep-alive flag set. After this time the connection will be closed. The time-out is in milliseconds (1/1000).'),
'type' => PMA_ENGINE_DETAILS_TYPE_PLAINTEXT
),
'pbms_http_metadata_headers' => array(
'title' => __('Metadata Headers'),
'desc' => __('A ":" delimited list of metadata headers to be used to initialize the pbms_metadata_header table when a database is created.'),
'type' => PMA_ENGINE_DETAILS_TYPE_PLAINTEXT
),
);
}
//--------------------
function getInfoPages()
{
$pages = array();
$pages['Documentation'] = __('Documentation');
return $pages;
}
//--------------------
function getPage($id)
{
if (! array_key_exists($id, $this->getInfoPages())) {
return false;
}
$id = 'getPage' . $id;
return $this->$id();
}
function getPageConfigure()
{
}
function getPageDocumentation()
{
$output = '<p>'
. sprintf(__('Documentation and further information about PBMS can be found on %sThe PrimeBase Media Streaming home page%s.'), '<a href="' . PMA_linkURL('http://www.blobstreaming.org/') . '" target="_blank">', '</a>')
. '</p>' . "\n"
. '<h3>' . __('Related Links') . '</h3>' . "\n"
. '<ul>' . "\n"
. '<li><a href="' . PMA_linkURL('http://bpbdev.blogspot.com/') . '" target="_blank">' . __('The PrimeBase Media Streaming Blog by Barry Leslie') . '</a></li>' . "\n"
. '<li><a href="' . PMA_linkURL('http://www.primebase.com/xt') . '" target="_blank">' . __('PrimeBase XT Home Page') . '</a></li>' . "\n"
. '</ul>' . "\n";
return $output;
}
}
?>

View File

@ -0,0 +1,137 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin-Engines
*/
/**
* the MyISAM storage engine
* @package PhpMyAdmin-Engines
*/
class PMA_StorageEngine_pbxt extends PMA_StorageEngine
{
/**
* returns array with variable names dedicated to PBXT storage engine
*
* @return array variable names
*/
function getVariables()
{
return array(
'pbxt_index_cache_size' => array(
'title' => __('Index cache size'),
'desc' => __('This is the amount of memory allocated to the index cache. Default value is 32MB. The memory allocated here is used only for caching index pages.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_record_cache_size' => array(
'title' => __('Record cache size'),
'desc' => __('This is the amount of memory allocated to the record cache used to cache table data. The default value is 32MB. This memory is used to cache changes to the handle data (.xtd) and row pointer (.xtr) files.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_log_cache_size' => array(
'title' => __('Log cache size'),
'desc' => __('The amount of memory allocated to the transaction log cache used to cache on transaction log data. The default is 16MB.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_log_file_threshold' => array(
'title' => __('Log file threshold'),
'desc' => __('The size of a transaction log before rollover, and a new log is created. The default value is 16MB.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_transaction_buffer_size' => array(
'title' => __('Transaction buffer size'),
'desc' => __('The size of the global transaction log buffer (the engine allocates 2 buffers of this size). The default is 1MB.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_checkpoint_frequency' => array(
'title' => __('Checkpoint frequency'),
'desc' => __('The amount of data written to the transaction log before a checkpoint is performed. The default value is 24MB.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_data_log_threshold' => array(
'title' => __('Data log threshold'),
'desc' => __('The maximum size of a data log file. The default value is 64MB. PBXT can create a maximum of 32000 data logs, which are used by all tables. So the value of this variable can be increased to increase the total amount of data that can be stored in the database.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_garbage_threshold' => array(
'title' => __('Garbage threshold'),
'desc' => __('The percentage of garbage in a data log file before it is compacted. This is a value between 1 and 99. The default is 50.'),
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC
),
'pbxt_log_buffer_size' => array(
'title' => __('Log buffer size'),
'desc' => __('The size of the buffer used when writing a data log. The default is 256MB. The engine allocates one buffer per thread, but only if the thread is required to write a data log.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_data_file_grow_size' => array(
'title' => __('Data file grow size'),
'desc' => __('The grow size of the handle data (.xtd) files.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_row_file_grow_size' => array(
'title' => __('Row file grow size'),
'desc' => __('The grow size of the row pointer (.xtr) files.'),
'type' => PMA_ENGINE_DETAILS_TYPE_SIZE
),
'pbxt_log_file_count' => array(
'title' => __('Log file count'),
'desc' => __('This is the number of transaction log files (pbxt/system/xlog*.xt) the system will maintain. If the number of logs exceeds this value then old logs will be deleted, otherwise they are renamed and given the next highest number.'),
'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC
),
);
}
/**
* returns the pbxt engine specific handling for
* PMA_ENGINE_DETAILS_TYPE_SIZE variables.
*
* @param string $formatted_size the size expression (for example 8MB)
*
* @return string the formatted value and its unit
*/
function resolveTypeSize($formatted_size)
{
if (preg_match('/^[0-9]+[a-zA-Z]+$/', $formatted_size)) {
$value = PMA_extractValueFromFormattedSize($formatted_size);
} else {
$value = $formatted_size;
}
return PMA_formatByteDown($value);
}
//--------------------
function getInfoPages()
{
$pages = array();
$pages['Documentation'] = __('Documentation');
return $pages;
}
//--------------------
function getPage($id)
{
if (! array_key_exists($id, $this->getInfoPages())) {
return false;
}
$id = 'getPage' . $id;
return $this->$id();
}
function getPageDocumentation()
{
$output = '<p>'
. sprintf(__('Documentation and further information about PBXT can be found on the %sPrimeBase XT Home Page%s.'), '<a href="' . PMA_linkURL('http://www.primebase.com/xt/') . '" target="_blank">', '</a>')
. '</p>' . "\n"
. '<h3>' . __('Related Links') . '</h3>' . "\n"
. '<ul>' . "\n"
. '<li><a href="' . PMA_linkURL('http://pbxt.blogspot.com/') . '" target="_blank">' . __('The PrimeBase XT Blog by Paul McCullagh') . '</a></li>' . "\n"
. '<li><a href="' . PMA_linkURL('http://www.blobstreaming.org/') . '" target="_blank">' . __('The PrimeBase Media Streaming (PBMS) home page') . '</a></li>' . "\n"
. '</ul>' . "\n";
return $output;
}
}
?>

View File

@ -0,0 +1,57 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* phpMyAdmin fatal error display page
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
exit;
}
header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $lang; ?>" dir="<?php echo $dir; ?>">
<head>
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<title>phpMyAdmin</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
<!--
html {
padding: 0;
margin: 0;
}
body {
font-family: sans-serif;
font-size: small;
color: #000000;
background-color: #F5F5F5;
margin: 1em;
}
h1 {
margin: 0;
padding: 0.3em;
font-size: 1.4em;
font-weight: bold;
color: #ffffff;
background-color: #ff0000;
}
p {
margin: 0;
padding: 0.5em;
border: 0.1em solid red;
background-color: #ffeeee;
}
//-->
</style>
</head>
<body>
<h1>phpMyAdmin - <?php echo $error_header; ?></h1>
<p><?php echo PMA_sanitize($error_message); ?></p>
</body>
</html>

View File

@ -0,0 +1,334 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build NHibernate dumps of tables
*
* @package PhpMyAdmin-Export
* @subpackage Codegen
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* This gets executed twice so avoid a notice
*/
if (! defined('CG_FORMAT_NHIBERNATE_CS')) {
define("CG_FORMAT_NHIBERNATE_CS", "NHibernate C# DO");
define("CG_FORMAT_NHIBERNATE_XML", "NHibernate XML");
define("CG_HANDLER_NHIBERNATE_CS_BODY", "handleNHibernateCSBody");
define("CG_HANDLER_NHIBERNATE_XML_BODY", "handleNHibernateXMLBody");
}
$CG_FORMATS = array(CG_FORMAT_NHIBERNATE_CS, CG_FORMAT_NHIBERNATE_XML);
$CG_HANDLERS = array(CG_HANDLER_NHIBERNATE_CS_BODY, CG_HANDLER_NHIBERNATE_XML_BODY);
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['codegen'] = array(
'text' => 'CodeGen',
'extension' => 'cs',
'mime_type' => 'text/cs',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'hidden', 'name' => 'structure_or_data'),
array('type' => 'select', 'name' => 'format', 'text' => __('Format:'), 'values' => $CG_FORMATS),
array('type' => 'end_group')
),
'options_text' => __('Options'),
);
} else {
/**
* Set of functions used to build exports of tables
*/
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table in NHibernate format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
global $CG_FORMATS, $CG_HANDLERS, $what;
$format = $GLOBALS[$what . '_format'];
if (isset($CG_FORMATS[$format])) {
return PMA_exportOutputHandler($CG_HANDLERS[$format]($db, $table, $crlf));
}
return PMA_exportOutputHandler(sprintf("%s is not supported.", $format));
}
/**
*
* @package PhpMyAdmin-Export
* @subpackage Codegen
*/
class TableProperty
{
public $name;
public $type;
public $nullable;
public $key;
public $defaultValue;
public $ext;
function __construct($row)
{
$this->name = trim($row[0]);
$this->type = trim($row[1]);
$this->nullable = trim($row[2]);
$this->key = trim($row[3]);
$this->defaultValue = trim($row[4]);
$this->ext = trim($row[5]);
}
function getPureType()
{
$pos=strpos($this->type, "(");
if ($pos > 0)
return substr($this->type, 0, $pos);
return $this->type;
}
function isNotNull()
{
return $this->nullable == "NO" ? "true" : "false";
}
function isUnique()
{
return $this->key == "PRI" || $this->key == "UNI" ? "true" : "false";
}
function getDotNetPrimitiveType()
{
if (strpos($this->type, "int") === 0) return "int";
if (strpos($this->type, "long") === 0) return "long";
if (strpos($this->type, "char") === 0) return "string";
if (strpos($this->type, "varchar") === 0) return "string";
if (strpos($this->type, "text") === 0) return "string";
if (strpos($this->type, "longtext") === 0) return "string";
if (strpos($this->type, "tinyint") === 0) return "bool";
if (strpos($this->type, "datetime") === 0) return "DateTime";
return "unknown";
}
function getDotNetObjectType()
{
if (strpos($this->type, "int") === 0) return "Int32";
if (strpos($this->type, "long") === 0) return "Long";
if (strpos($this->type, "char") === 0) return "String";
if (strpos($this->type, "varchar") === 0) return "String";
if (strpos($this->type, "text") === 0) return "String";
if (strpos($this->type, "longtext") === 0) return "String";
if (strpos($this->type, "tinyint") === 0) return "Boolean";
if (strpos($this->type, "datetime") === 0) return "DateTime";
return "Unknown";
}
function getIndexName()
{
if (strlen($this->key)>0)
return "index=\"" . htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8') . "\"";
return "";
}
function isPK()
{
return $this->key=="PRI";
}
function formatCs($text)
{
$text=str_replace("#name#", cgMakeIdentifier($this->name, false), $text);
return $this->format($text);
}
function formatXml($text)
{
$text=str_replace("#name#", htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8'), $text);
$text=str_replace("#indexName#", $this->getIndexName(), $text);
return $this->format($text);
}
function format($text)
{
$text=str_replace("#ucfirstName#", cgMakeIdentifier($this->name), $text);
$text=str_replace("#dotNetPrimitiveType#", $this->getDotNetPrimitiveType(), $text);
$text=str_replace("#dotNetObjectType#", $this->getDotNetObjectType(), $text);
$text=str_replace("#type#", $this->getPureType(), $text);
$text=str_replace("#notNull#", $this->isNotNull(), $text);
$text=str_replace("#unique#", $this->isUnique(), $text);
return $text;
}
}
function cgMakeIdentifier($str, $ucfirst = true)
{
// remove unsafe characters
$str = preg_replace('/[^\p{L}\p{Nl}_]/u', '', $str);
// make sure first character is a letter or _
if (!preg_match('/^\pL/u', $str)) {
$str = '_' . $str;
}
if ($ucfirst) {
$str = ucfirst($str);
}
return $str;
}
function handleNHibernateCSBody($db, $table, $crlf)
{
$lines=array();
$result=PMA_DBI_query(sprintf('DESC %s.%s', PMA_backquote($db), PMA_backquote($table)));
if ($result) {
$tableProperties=array();
while ($row = PMA_DBI_fetch_row($result)) {
$tableProperties[] = new TableProperty($row);
}
PMA_DBI_free_result($result);
$lines[] = 'using System;';
$lines[] = 'using System.Collections;';
$lines[] = 'using System.Collections.Generic;';
$lines[] = 'using System.Text;';
$lines[] = 'namespace ' . cgMakeIdentifier($db);
$lines[] = '{';
$lines[] = ' #region ' . cgMakeIdentifier($table);
$lines[] = ' public class ' . cgMakeIdentifier($table);
$lines[] = ' {';
$lines[] = ' #region Member Variables';
foreach ($tableProperties as $tablePropertie) {
$lines[] = $tablePropertie->formatCs(' protected #dotNetPrimitiveType# _#name#;');
}
$lines[] = ' #endregion';
$lines[] = ' #region Constructors';
$lines[] = ' public ' . cgMakeIdentifier($table).'() { }';
$temp = array();
foreach ($tableProperties as $tablePropertie) {
if (! $tablePropertie->isPK()) {
$temp[] = $tablePropertie->formatCs('#dotNetPrimitiveType# #name#');
}
}
$lines[] = ' public ' . cgMakeIdentifier($table) . '(' . implode(', ', $temp) . ')';
$lines[] = ' {';
foreach ($tableProperties as $tablePropertie) {
if (! $tablePropertie->isPK()) {
$lines[] = $tablePropertie->formatCs(' this._#name#=#name#;');
}
}
$lines[] = ' }';
$lines[] = ' #endregion';
$lines[] = ' #region Public Properties';
foreach ($tableProperties as $tablePropertie) {
$lines[] = $tablePropertie->formatCs(''
. ' public virtual #dotNetPrimitiveType# #ucfirstName#' . "\n"
. ' {' . "\n"
. ' get {return _#name#;}' . "\n"
. ' set {_#name#=value;}' . "\n"
. ' }'
);
}
$lines[] = ' #endregion';
$lines[] = ' }';
$lines[] = ' #endregion';
$lines[] = '}';
}
return implode("\n", $lines);
}
function handleNHibernateXMLBody($db, $table, $crlf)
{
$lines = array();
$lines[] = '<?xml version="1.0" encoding="utf-8" ?' . '>';
$lines[] = '<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" '
. 'namespace="' . cgMakeIdentifier($db) . '" '
. 'assembly="' . cgMakeIdentifier($db) . '">';
$lines[] = ' <class '
. 'name="' . cgMakeIdentifier($table) . '" '
. 'table="' . cgMakeIdentifier($table) . '">';
$result = PMA_DBI_query(sprintf("DESC %s.%s", PMA_backquote($db), PMA_backquote($table)));
if ($result) {
while ($row = PMA_DBI_fetch_row($result)) {
$tablePropertie = new TableProperty($row);
if ($tablePropertie->isPK())
$lines[] = $tablePropertie->formatXml(''
. ' <id name="#ucfirstName#" type="#dotNetObjectType#" unsaved-value="0">' . "\n"
. ' <column name="#name#" sql-type="#type#" not-null="#notNull#" unique="#unique#" index="PRIMARY"/>' . "\n"
. ' <generator class="native" />' . "\n"
. ' </id>');
else
$lines[] = $tablePropertie->formatXml(''
. ' <property name="#ucfirstName#" type="#dotNetObjectType#">' . "\n"
. ' <column name="#name#" sql-type="#type#" not-null="#notNull#" #indexName#/>' . "\n"
. ' </property>');
}
PMA_DBI_free_result($result);
}
$lines[] = ' </class>';
$lines[] = '</hibernate-mapping>';
return implode("\n", $lines);
}
}
?>

View File

@ -0,0 +1,222 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* CSV export code
*
* @package PhpMyAdmin-Export
* @subpackage CSV
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Set of functions used to build CSV dumps of tables
*/
if (isset($plugin_list)) {
$plugin_list['csv'] = array(
'text' => __('CSV'),
'extension' => 'csv',
'mime_type' => 'text/comma-separated-values',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'text', 'name' => 'separator', 'text' => __('Columns separated with:')),
array('type' => 'text', 'name' => 'enclosed', 'text' => __('Columns enclosed with:')),
array('type' => 'text', 'name' => 'escaped', 'text' => __('Columns escaped with:')),
array('type' => 'text', 'name' => 'terminated', 'text' => __('Lines terminated with:')),
array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL with:')),
array('type' => 'bool', 'name' => 'removeCRLF', 'text' => __('Remove carriage return/line feed characters within columns')),
array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row')),
array('type' => 'hidden', 'name' => 'structure_or_data'),
array('type' => 'end_group'),
),
'options_text' => __('Options'),
);
} else {
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter() {
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader() {
global $what;
global $csv_terminated;
global $csv_separator;
global $csv_enclosed;
global $csv_escaped;
// Here we just prepare some values for export
if ($what == 'excel') {
$csv_terminated = "\015\012";
switch($GLOBALS['excel_edition']) {
case 'win':
// as tested on Windows with Excel 2002 and Excel 2007
$csv_separator = ';';
break;
case 'mac_excel2003':
$csv_separator = ';';
break;
case 'mac_excel2008':
$csv_separator = ',';
break;
}
$csv_enclosed = '"';
$csv_escaped = '"';
if (isset($GLOBALS['excel_columns'])) {
$GLOBALS['csv_columns'] = 'yes';
}
} else {
if (empty($csv_terminated) || strtolower($csv_terminated) == 'auto') {
$csv_terminated = $GLOBALS['crlf'];
} else {
$csv_terminated = str_replace('\\r', "\015", $csv_terminated);
$csv_terminated = str_replace('\\n', "\012", $csv_terminated);
$csv_terminated = str_replace('\\t', "\011", $csv_terminated);
} // end if
$csv_separator = str_replace('\\t', "\011", $csv_separator);
}
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db) {
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db) {
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db) {
return true;
}
/**
* Outputs the content of a table in CSV format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) {
global $what;
global $csv_terminated;
global $csv_separator;
global $csv_enclosed;
global $csv_escaped;
// Gets the data from the database
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$fields_cnt = PMA_DBI_num_fields($result);
// If required, get fields name at the first line
if (isset($GLOBALS['csv_columns'])) {
$schema_insert = '';
for ($i = 0; $i < $fields_cnt; $i++) {
if ($csv_enclosed == '') {
$schema_insert .= stripslashes(PMA_DBI_field_name($result, $i));
} else {
$schema_insert .= $csv_enclosed
. str_replace($csv_enclosed, $csv_escaped . $csv_enclosed, stripslashes(PMA_DBI_field_name($result, $i)))
. $csv_enclosed;
}
$schema_insert .= $csv_separator;
} // end for
$schema_insert =trim(substr($schema_insert, 0, -1));
if (!PMA_exportOutputHandler($schema_insert . $csv_terminated)) {
return false;
}
} // end if
// Format the data
while ($row = PMA_DBI_fetch_row($result)) {
$schema_insert = '';
for ($j = 0; $j < $fields_cnt; $j++) {
if (!isset($row[$j]) || is_null($row[$j])) {
$schema_insert .= $GLOBALS[$what . '_null'];
} elseif ($row[$j] == '0' || $row[$j] != '') {
// always enclose fields
if ($what == 'excel') {
$row[$j] = preg_replace("/\015(\012)?/", "\012", $row[$j]);
}
// remove CRLF characters within field
if (isset($GLOBALS[$what . '_removeCRLF']) && $GLOBALS[$what . '_removeCRLF']) {
$row[$j] = str_replace("\n", "", str_replace("\r", "", $row[$j]));
}
if ($csv_enclosed == '') {
$schema_insert .= $row[$j];
} else {
// also double the escape string if found in the data
if ($csv_escaped != $csv_enclosed) {
$schema_insert .= $csv_enclosed
. str_replace($csv_enclosed, $csv_escaped . $csv_enclosed, str_replace($csv_escaped, $csv_escaped . $csv_escaped, $row[$j]))
. $csv_enclosed;
} else {
// avoid a problem when escape string equals enclose
$schema_insert .= $csv_enclosed
. str_replace($csv_enclosed, $csv_escaped . $csv_enclosed, $row[$j])
. $csv_enclosed;
}
}
} else {
$schema_insert .= '';
}
if ($j < $fields_cnt-1) {
$schema_insert .= $csv_separator;
}
} // end for
if (!PMA_exportOutputHandler($schema_insert . $csv_terminated)) {
return false;
}
} // end while
PMA_DBI_free_result($result);
return true;
} // end of the 'PMA_getTableCsv()' function
}
?>

View File

@ -0,0 +1,43 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build CSV dumps of tables for excel
*
* @package PhpMyAdmin-Export
* @subpackage CSV-Excel
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['excel'] = array(
'text' => __('CSV for MS Excel'),
'extension' => 'csv',
'mime_type' => 'text/comma-separated-values',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL with:')),
array('type' => 'bool', 'name' => 'removeCRLF', 'text' => __('Remove carriage return/line feed characters within columns')),
array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row')),
array(
'type' => 'select',
'name' => 'edition',
'values' => array(
'win' => 'Windows',
'mac_excel2003' => 'Excel 2003 / Macintosh',
'mac_excel2008' => 'Excel 2008 / Macintosh'),
'text' => __('Excel edition:')),
array('type' => 'hidden', 'name' => 'structure_or_data'),
array('type' => 'end_group'),
),
'options_text' => __('Options'),
);
} else {
/* Everything rest is coded in csv plugin */
include './libraries/export/csv.php';
}
?>

View File

@ -0,0 +1,325 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to export a set of queries to a MS Word document
*
* @package PhpMyAdmin-Export
* @subpackage HTMLWord
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['htmlword'] = array(
'text' => __('Microsoft Word 2000'),
'extension' => 'doc',
'mime_type' => 'application/vnd.ms-word',
'force_file' => true,
'options' => array(
/* what to dump (structure/data/both) */
array('type' => 'begin_group', 'name' => 'dump_what', 'text' => __('Dump table')),
array('type' => 'radio', 'name' => 'structure_or_data', 'values' => array('structure' => __('structure'), 'data' => __('data'), 'structure_and_data' => __('structure and data'))),
array('type' => 'end_group'),
/* data options */
array('type' => 'begin_group', 'name' => 'data', 'text' => __('Data dump options'), 'force' => 'structure'),
array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL with:')),
array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row')),
array('type' => 'end_group'),
),
'options_text' => __('Options'),
);
} else {
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter() {
return PMA_exportOutputHandler('</body></html>');
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader() {
global $charset_of_file;
return PMA_exportOutputHandler('<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=' . (isset($charset_of_file) ? $charset_of_file : 'utf-8') . '" />
</head>
<body>');
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db) {
return PMA_exportOutputHandler('<h1>' . __('Database') . ' ' . htmlspecialchars($db) . '</h1>');
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db) {
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db) {
return true;
}
/**
* Outputs the content of a table in HTML (Microsoft Word) format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
global $what;
if (! PMA_exportOutputHandler('<h2>' . __('Dumping data for table') . ' ' . htmlspecialchars($table) . '</h2>')) {
return false;
}
if (! PMA_exportOutputHandler('<table class="width100" cellspacing="1">')) {
return false;
}
// Gets the data from the database
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$fields_cnt = PMA_DBI_num_fields($result);
// If required, get fields name at the first line
if (isset($GLOBALS['htmlword_columns'])) {
$schema_insert = '<tr class="print-category">';
for ($i = 0; $i < $fields_cnt; $i++) {
$schema_insert .= '<td class="print"><b>' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i))) . '</b></td>';
} // end for
$schema_insert .= '</tr>';
if (! PMA_exportOutputHandler($schema_insert)) {
return false;
}
} // end if
// Format the data
while ($row = PMA_DBI_fetch_row($result)) {
$schema_insert = '<tr class="print-category">';
for ($j = 0; $j < $fields_cnt; $j++) {
if (! isset($row[$j]) || is_null($row[$j])) {
$value = $GLOBALS[$what . '_null'];
} elseif ($row[$j] == '0' || $row[$j] != '') {
$value = $row[$j];
} else {
$value = '';
}
$schema_insert .= '<td class="print">' . htmlspecialchars($value) . '</td>';
} // end for
$schema_insert .= '</tr>';
if (! PMA_exportOutputHandler($schema_insert)) {
return false;
}
} // end while
PMA_DBI_free_result($result);
if (! PMA_exportOutputHandler('</table>')) {
return false;
}
return true;
}
/**
* Outputs table's structure
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param bool $do_relation whether to include relation comments
* @param bool $do_comments whether to include the pmadb-style column comments
* as comments in the structure; this is deprecated
* but the parameter is left here because export.php
* calls PMA_exportStructure() also for other export
* types which use this parameter
* @param bool $do_mime whether to include mime comments
* @param bool $dates whether to include creation/update/check dates
* @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in'
* @param string $export_type 'server', 'database', 'table'
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type)
{
global $cfgRelation;
if (! PMA_exportOutputHandler('<h2>' . __('Table structure for table') . ' ' . htmlspecialchars($table) . '</h2>')) {
return false;
}
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = PMA_DBI_get_table_indexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
/**
* Gets fields properties
*/
PMA_DBI_select_db($db);
// Check if we can use Relations
if ($do_relation && ! empty($cfgRelation['relation'])) {
// Find which tables are related with the current one and write it in
// an array
$res_rel = PMA_getForeigners($db, $table);
if ($res_rel && count($res_rel) > 0) {
$have_rel = true;
} else {
$have_rel = false;
}
} else {
$have_rel = false;
} // end if
/**
* Displays the table structure
*/
if (! PMA_exportOutputHandler('<table class="width100" cellspacing="1">')) {
return false;
}
$columns_cnt = 4;
if ($do_relation && $have_rel) {
$columns_cnt++;
}
if ($do_comments && $cfgRelation['commwork']) {
$columns_cnt++;
}
if ($do_mime && $cfgRelation['mimework']) {
$columns_cnt++;
}
$schema_insert = '<tr class="print-category">';
$schema_insert .= '<th class="print">' . __('Column') . '</th>';
$schema_insert .= '<td class="print"><b>' . __('Type') . '</b></td>';
$schema_insert .= '<td class="print"><b>' . __('Null') . '</b></td>';
$schema_insert .= '<td class="print"><b>' . __('Default') . '</b></td>';
if ($do_relation && $have_rel) {
$schema_insert .= '<td class="print"><b>' . __('Links to') . '</b></td>';
}
if ($do_comments) {
$schema_insert .= '<td class="print"><b>' . __('Comments') . '</b></td>';
$comments = PMA_getComments($db, $table);
}
if ($do_mime && $cfgRelation['mimework']) {
$schema_insert .= '<td class="print"><b>' . htmlspecialchars('MIME') . '</b></td>';
$mime_map = PMA_getMIME($db, $table, true);
}
$schema_insert .= '</tr>';
if (! PMA_exportOutputHandler($schema_insert)) {
return false;
}
$columns = PMA_DBI_get_columns($db, $table);
foreach ($columns as $column) {
$schema_insert = '<tr class="print-category">';
$extracted_fieldspec = PMA_extractFieldSpec($column['Type']);
$type = htmlspecialchars($extracted_fieldspec['print_type']);
if (empty($type)) {
$type = '&nbsp;';
}
if (! isset($column['Default'])) {
if ($column['Null'] != 'NO') {
$column['Default'] = 'NULL';
}
}
$fmt_pre = '';
$fmt_post = '';
if (in_array($column['Field'], $unique_keys)) {
$fmt_pre = '<b>' . $fmt_pre;
$fmt_post = $fmt_post . '</b>';
}
if ($column['Key'] == 'PRI') {
$fmt_pre = '<i>' . $fmt_pre;
$fmt_post = $fmt_post . '</i>';
}
$schema_insert .= '<td class="print">' . $fmt_pre . htmlspecialchars($column['Field']) . $fmt_post . '</td>';
$schema_insert .= '<td class="print">' . htmlspecialchars($type) . '</td>';
$schema_insert .= '<td class="print">' . (($column['Null'] == '' || $column['Null'] == 'NO') ? __('No') : __('Yes')) . '</td>';
$schema_insert .= '<td class="print">' . htmlspecialchars(isset($column['Default']) ? $column['Default'] : '') . '</td>';
$field_name = $column['Field'];
if ($do_relation && $have_rel) {
$schema_insert .= '<td class="print">' . (isset($res_rel[$field_name]) ? htmlspecialchars($res_rel[$field_name]['foreign_table'] . ' (' . $res_rel[$field_name]['foreign_field'] . ')') : '') . '</td>';
}
if ($do_comments && $cfgRelation['commwork']) {
$schema_insert .= '<td class="print">' . (isset($comments[$field_name]) ? htmlspecialchars($comments[$field_name]) : '') . '</td>';
}
if ($do_mime && $cfgRelation['mimework']) {
$schema_insert .= '<td class="print">' . (isset($mime_map[$field_name]) ? htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype'])) : '') . '</td>';
}
$schema_insert .= '</tr>';
if (! PMA_exportOutputHandler($schema_insert)) {
return false;
}
} // end while
return PMA_exportOutputHandler('</table>');
}
}
?>

View File

@ -0,0 +1,173 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build dumps of tables as JSON
*
* @package PhpMyAdmin-Export
* @subpackage JSON
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['json'] = array(
'text' => 'JSON',
'extension' => 'json',
'mime_type' => 'text/plain',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array(
'type' => 'hidden',
'name' => 'structure_or_data',
),
array('type' => 'end_group')
),
'options_text' => __('Options'),
);
} else {
/**
* Set of functions used to build exports of tables
*/
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
PMA_exportOutputHandler(
'/**' . $GLOBALS['crlf']
. ' Export to JSON plugin for PHPMyAdmin' . $GLOBALS['crlf']
. ' @version 0.1' . $GLOBALS['crlf']
. ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf']
);
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
PMA_exportOutputHandler('// Database \'' . $db . '\'' . $GLOBALS['crlf'] );
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table in JSON format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$columns_cnt = PMA_DBI_num_fields($result);
for ($i = 0; $i < $columns_cnt; $i++) {
$columns[$i] = stripslashes(PMA_DBI_field_name($result, $i));
}
unset($i);
$buffer = '';
$record_cnt = 0;
while ($record = PMA_DBI_fetch_row($result)) {
$record_cnt++;
// Output table name as comment if this is the first record of the table
if ($record_cnt == 1) {
$buffer .= '// ' . $db . '.' . $table . $crlf . $crlf;
$buffer .= '[{';
} else {
$buffer .= ', {';
}
for ($i = 0; $i < $columns_cnt; $i++) {
$isLastLine = ($i + 1 >= $columns_cnt);
$column = $columns[$i];
if (is_null($record[$i])) {
$buffer .= '"' . addslashes($column) . '": null' . (! $isLastLine ? ',' : '');
} elseif (is_numeric($record[$i])) {
$buffer .= '"' . addslashes($column) . '": ' . $record[$i] . (! $isLastLine ? ',' : '');
} else {
$buffer .= '"' . addslashes($column) . '": "' . addslashes($record[$i]) . '"' . (! $isLastLine ? ',' : '');
}
}
$buffer .= '}';
}
if ($record_cnt) {
$buffer .= ']';
}
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
PMA_DBI_free_result($result);
return true;
}
}

View File

@ -0,0 +1,504 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build LaTeX dumps of tables
*
* @package PhpMyAdmin-Export
* @subpackage Latex
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/* Messages used in default captions */
$GLOBALS['strLatexContent'] = __('Content of table @TABLE@');
$GLOBALS['strLatexContinued'] = __('(continued)');
$GLOBALS['strLatexStructure'] = __('Structure of table @TABLE@');
/**
*
*/
if (isset($plugin_list)) {
$hide_structure = false;
if ($plugin_param['export_type'] == 'table' && ! $plugin_param['single_table']) {
$hide_structure = true;
}
$plugin_list['latex'] = array(
'text' => __('LaTeX'),
'extension' => 'tex',
'mime_type' => 'application/x-tex',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'bool', 'name' => 'caption', 'text' => __('Include table caption')),
array('type' => 'end_group')
),
'options_text' => __('Options'),
);
/* what to dump (structure/data/both) */
$plugin_list['latex']['options'][]
= array('type' => 'begin_group', 'name' => 'dump_what', 'text' => __('Dump table'));
$plugin_list['latex']['options'][]
= array('type' => 'radio', 'name' => 'structure_or_data', 'values' => array('structure' => __('structure'), 'data' => __('data'), 'structure_and_data' => __('structure and data')));
$plugin_list['latex']['options'][] = array('type' => 'end_group');
/* Structure options */
if (! $hide_structure) {
$plugin_list['latex']['options'][]
= array('type' => 'begin_group', 'name' => 'structure', 'text' => __('Object creation options'), 'force' => 'data');
$plugin_list['latex']['options'][]
= array('type' => 'text', 'name' => 'structure_caption', 'text' => __('Table caption'), 'doc' => 'faq6_27');
$plugin_list['latex']['options'][]
= array('type' => 'text', 'name' => 'structure_continued_caption', 'text' => __('Table caption (continued)'), 'doc' => 'faq6_27');
$plugin_list['latex']['options'][]
= array('type' => 'text', 'name' => 'structure_label', 'text' => __('Label key'), 'doc' => 'faq6_27');
if (! empty($GLOBALS['cfgRelation']['relation'])) {
$plugin_list['latex']['options'][]
= array('type' => 'bool', 'name' => 'relation', 'text' => __('Display foreign key relationships'));
}
$plugin_list['latex']['options'][]
= array('type' => 'bool', 'name' => 'comments', 'text' => __('Display comments'));
if (! empty($GLOBALS['cfgRelation']['mimework'])) {
$plugin_list['latex']['options'][]
= array('type' => 'bool', 'name' => 'mime', 'text' => __('Display MIME types'));
}
$plugin_list['latex']['options'][]
= array('type' => 'end_group');
}
/* Data */
$plugin_list['latex']['options'][]
= array('type' => 'begin_group', 'name' => 'data', 'text' => __('Data dump options'), 'force' => 'structure');
$plugin_list['latex']['options'][]
= array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row'));
$plugin_list['latex']['options'][]
= array('type' => 'text', 'name' => 'data_caption', 'text' => __('Table caption'), 'doc' => 'faq6_27');
$plugin_list['latex']['options'][]
= array('type' => 'text', 'name' => 'data_continued_caption', 'text' => __('Table caption (continued)'), 'doc' => 'faq6_27');
$plugin_list['latex']['options'][]
= array('type' => 'text', 'name' => 'data_label', 'text' => __('Label key'), 'doc' => 'faq6_27');
$plugin_list['latex']['options'][]
= array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL with:'));
$plugin_list['latex']['options'][]
= array('type' => 'end_group');
} else {
/**
* Escapes some special characters for use in TeX/LaTeX
*
* @param string $string the string to convert
*
* @return string the converted string with escape codes
*
* @access private
*/
function PMA_texEscape($string)
{
$escape = array('$', '%', '{', '}', '&', '#', '_', '^');
$cnt_escape = count($escape);
for ($k=0; $k < $cnt_escape; $k++) {
$string = str_replace($escape[$k], '\\' . $escape[$k], $string);
}
return $string;
}
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
global $crlf;
global $cfg;
$head = '% phpMyAdmin LaTeX Dump' . $crlf
. '% version ' . PMA_VERSION . $crlf
. '% http://www.phpmyadmin.net' . $crlf
. '%' . $crlf
. '% ' . __('Host') . ': ' . $cfg['Server']['host'];
if (! empty($cfg['Server']['port'])) {
$head .= ':' . $cfg['Server']['port'];
}
$head .= $crlf
. '% ' . __('Generation Time') . ': ' . PMA_localisedDate() . $crlf
. '% ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf
. '% ' . __('PHP Version') . ': ' . phpversion() . $crlf;
return PMA_exportOutputHandler($head);
}
/**
* Outputs database header
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
global $crlf;
$head = '% ' . $crlf
. '% ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf
. '% ' . $crlf;
return PMA_exportOutputHandler($head);
}
/**
* Outputs database footer
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table in LaTeX table/sideways table environment
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
$result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$columns_cnt = PMA_DBI_num_fields($result);
for ($i = 0; $i < $columns_cnt; $i++) {
$columns[$i] = PMA_DBI_field_name($result, $i);
}
unset($i);
$buffer = $crlf . '%' . $crlf . '% ' . __('Data') . ': ' . $table
. $crlf . '%' . $crlf . ' \\begin{longtable}{|';
for ($index = 0; $index < $columns_cnt; $index++) {
$buffer .= 'l|';
}
$buffer .= '} ' . $crlf ;
$buffer .= ' \\hline \\endhead \\hline \\endfoot \\hline ' . $crlf;
if (isset($GLOBALS['latex_caption'])) {
$buffer .= ' \\caption{'
. PMA_expandUserString(
$GLOBALS['latex_data_caption'],
'PMA_texEscape',
array('table' => $table, 'database' => $db)
)
. '} \\label{'
. PMA_expandUserString(
$GLOBALS['latex_data_label'],
null,
array('table' => $table, 'database' => $db)
)
. '} \\\\';
}
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
// show column names
if (isset($GLOBALS['latex_columns'])) {
$buffer = '\\hline ';
for ($i = 0; $i < $columns_cnt; $i++) {
$buffer .= '\\multicolumn{1}{|c|}{\\textbf{'
. PMA_texEscape(stripslashes($columns[$i])) . '}} & ';
}
$buffer = substr($buffer, 0, -2) . '\\\\ \\hline \hline ';
if (! PMA_exportOutputHandler($buffer . ' \\endfirsthead ' . $crlf)) {
return false;
}
if (isset($GLOBALS['latex_caption'])) {
if (! PMA_exportOutputHandler(
'\\caption{'
. PMA_expandUserString(
$GLOBALS['latex_data_continued_caption'],
'PMA_texEscape',
array('table' => $table, 'database' => $db)
)
. '} \\\\ '
)) {
return false;
}
}
if (! PMA_exportOutputHandler($buffer . '\\endhead \\endfoot' . $crlf)) {
return false;
}
} else {
if (! PMA_exportOutputHandler('\\\\ \hline')) {
return false;
}
}
// print the whole table
while ($record = PMA_DBI_fetch_assoc($result)) {
$buffer = '';
// print each row
for ($i = 0; $i < $columns_cnt; $i++) {
if (isset($record[$columns[$i]])
&& (! function_exists('is_null') || ! is_null($record[$columns[$i]]))
) {
$column_value = PMA_texEscape(stripslashes($record[$columns[$i]]));
} else {
$column_value = $GLOBALS['latex_null'];
}
// last column ... no need for & character
if ($i == ($columns_cnt - 1)) {
$buffer .= $column_value;
} else {
$buffer .= $column_value . " & ";
}
}
$buffer .= ' \\\\ \\hline ' . $crlf;
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
}
$buffer = ' \\end{longtable}' . $crlf;
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
PMA_DBI_free_result($result);
return true;
} // end getTableLaTeX
/**
* Outputs table's structure
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param bool $do_relation whether to include relation comments
* @param bool $do_comments whether to include the pmadb-style column comments
* as comments in the structure; this is deprecated
* but the parameter is left here because export.php
* calls PMA_exportStructure() also for other export
* types which use this parameter
* @param bool $do_mime whether to include mime comments
* @param bool $dates whether to include creation/update/check dates
* @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in'
* @param string $export_type 'server', 'database', 'table'
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type)
{
global $cfgRelation;
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = PMA_DBI_get_table_indexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
/**
* Gets fields properties
*/
PMA_DBI_select_db($db);
// Check if we can use Relations
if ($do_relation && ! empty($cfgRelation['relation'])) {
// Find which tables are related with the current one and write it in
// an array
$res_rel = PMA_getForeigners($db, $table);
if ($res_rel && count($res_rel) > 0) {
$have_rel = true;
} else {
$have_rel = false;
}
} else {
$have_rel = false;
} // end if
/**
* Displays the table structure
*/
$buffer = $crlf . '%' . $crlf . '% ' . __('Structure') . ': ' . $table
. $crlf . '%' . $crlf . ' \\begin{longtable}{';
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
$columns_cnt = 4;
$alignment = '|l|c|c|c|';
if ($do_relation && $have_rel) {
$columns_cnt++;
$alignment .= 'l|';
}
if ($do_comments) {
$columns_cnt++;
$alignment .= 'l|';
}
if ($do_mime && $cfgRelation['mimework']) {
$columns_cnt++;
$alignment .='l|';
}
$buffer = $alignment . '} ' . $crlf ;
$header = ' \\hline ';
$header .= '\\multicolumn{1}{|c|}{\\textbf{' . __('Column')
. '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Type')
. '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Null')
. '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Default') . '}}';
if ($do_relation && $have_rel) {
$header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Links to') . '}}';
}
if ($do_comments) {
$header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Comments') . '}}';
$comments = PMA_getComments($db, $table);
}
if ($do_mime && $cfgRelation['mimework']) {
$header .= ' & \\multicolumn{1}{|c|}{\\textbf{MIME}}';
$mime_map = PMA_getMIME($db, $table, true);
}
// Table caption for first page and label
if (isset($GLOBALS['latex_caption'])) {
$buffer .= ' \\caption{'
. PMA_expandUserString(
$GLOBALS['latex_structure_caption'],
'PMA_texEscape',
array('table' => $table, 'database' => $db)
)
. '} \\label{'
. PMA_expandUserString(
$GLOBALS['latex_structure_label'],
null,
array('table' => $table, 'database' => $db)
)
. '} \\\\' . $crlf;
}
$buffer .= $header . ' \\\\ \\hline \\hline' . $crlf . '\\endfirsthead' . $crlf;
// Table caption on next pages
if (isset($GLOBALS['latex_caption'])) {
$buffer .= ' \\caption{'
. PMA_expandUserString(
$GLOBALS['latex_structure_continued_caption'],
'PMA_texEscape',
array('table' => $table, 'database' => $db)
)
. '} \\\\ ' . $crlf;
}
$buffer .= $header . ' \\\\ \\hline \\hline \\endhead \\endfoot ' . $crlf;
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
$fields = PMA_DBI_get_columns($db, $table);
foreach ($fields as $row) {
$extracted_fieldspec = PMA_extractFieldSpec($row['Type']);
$type = $extracted_fieldspec['print_type'];
if (empty($type)) {
$type = ' ';
}
if (! isset($row['Default'])) {
if ($row['Null'] != 'NO') {
$row['Default'] = 'NULL';
}
}
$field_name = $row['Field'];
$local_buffer = $field_name . "\000" . $type . "\000"
. (($row['Null'] == '' || $row['Null'] == 'NO') ? __('No') : __('Yes'))
. "\000" . (isset($row['Default']) ? $row['Default'] : '');
if ($do_relation && $have_rel) {
$local_buffer .= "\000";
if (isset($res_rel[$field_name])) {
$local_buffer .= $res_rel[$field_name]['foreign_table'] . ' ('
. $res_rel[$field_name]['foreign_field'] . ')';
}
}
if ($do_comments && $cfgRelation['commwork']) {
$local_buffer .= "\000";
if (isset($comments[$field_name])) {
$local_buffer .= $comments[$field_name];
}
}
if ($do_mime && $cfgRelation['mimework']) {
$local_buffer .= "\000";
if (isset($mime_map[$field_name])) {
$local_buffer .= str_replace('_', '/', $mime_map[$field_name]['mimetype']);
}
}
$local_buffer = PMA_texEscape($local_buffer);
if ($row['Key']=='PRI') {
$pos=strpos($local_buffer, "\000");
$local_buffer = '\\textit{' . substr($local_buffer, 0, $pos) . '}' . substr($local_buffer, $pos);
}
if (in_array($field_name, $unique_keys)) {
$pos=strpos($local_buffer, "\000");
$local_buffer = '\\textbf{' . substr($local_buffer, 0, $pos) . '}' . substr($local_buffer, $pos);
}
$buffer = str_replace("\000", ' & ', $local_buffer);
$buffer .= ' \\\\ \\hline ' . $crlf;
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
} // end while
$buffer = ' \\end{longtable}' . $crlf;
return PMA_exportOutputHandler($buffer);
} // end of the 'PMA_exportStructure' function
} // end else
?>

View File

@ -0,0 +1,159 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build MediaWiki dumps of tables
*
* @package PhpMyAdmin-Export
* @subpackage MediaWiki
*/
if (! defined('PHPMYADMIN')) {
exit;
}
if (isset($plugin_list)) {
$plugin_list['mediawiki'] = array(
'text' => __('MediaWiki Table'),
'extension' => 'txt',
'mime_type' => 'text/plain',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'hidden', 'name' => 'structure_or_data'),
array('type' => 'end_group')
),
'options_text' => __('Options'),
);
} else {
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter() {
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader() {
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db) {
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db) {
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db) {
return true;
}
/**
* Outputs the content of a table in MediaWiki format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) {
$columns = PMA_DBI_get_columns($db, $table);
$columns = array_values($columns);
$row_cnt = count($columns);
$output = "{| cellpadding=\"10\" cellspacing=\"0\" border=\"1\" style=\"text-align:center;\"\n";
$output .= "|+'''" . $table . "'''\n";
$output .= "|- style=\"background:#ffdead;\"\n";
$output .= "! style=\"background:#ffffff\" | \n";
for ($i = 0; $i < $row_cnt; ++$i) {
$output .= " | " . $columns[$i]['Field'];
if (($i + 1) != $row_cnt) {
$output .= "\n";
}
}
$output .= "\n";
$output .= "|- style=\"background:#f9f9f9;\"\n";
$output .= "! style=\"background:#f2f2f2\" | Type\n";
for ($i = 0; $i < $row_cnt; ++$i) {
$output .= " | " . $columns[$i]['Type'];
if (($i + 1) != $row_cnt) {
$output .= "\n";
}
}
$output .= "\n";
$output .= "|- style=\"background:#f9f9f9;\"\n";
$output .= "! style=\"background:#f2f2f2\" | Null\n";
for ($i = 0; $i < $row_cnt; ++$i) {
$output .= " | " . $columns[$i]['Null'];
if (($i + 1) != $row_cnt) {
$output .= "\n";
}
}
$output .= "\n";
$output .= "|- style=\"background:#f9f9f9;\"\n";
$output .= "! style=\"background:#f2f2f2\" | Default\n";
for ($i = 0; $i < $row_cnt; ++$i) {
$output .= " | " . $columns[$i]['Default'];
if (($i + 1) != $row_cnt) {
$output .= "\n";
}
}
$output .= "\n";
$output .= "|- style=\"background:#f9f9f9;\"\n";
$output .= "! style=\"background:#f2f2f2\" | Extra\n";
for ($i = 0; $i < $row_cnt; ++$i) {
$output .= " | " . $columns[$i]['Extra'];
if (($i + 1) != $row_cnt) {
$output .= "\n";
}
}
$output .= "\n";
$output .= "|}\n\n\n\n";
return PMA_exportOutputHandler($output);
}
}
?>

View File

@ -0,0 +1,221 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build OpenDocument Spreadsheet dumps of tables
*
* @package PhpMyAdmin-Export
* @subpackage ODS
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['ods'] = array(
'text' => __('Open Document Spreadsheet'),
'extension' => 'ods',
'mime_type' => 'application/vnd.oasis.opendocument.spreadsheet',
'force_file' => true,
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL with:')),
array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row')),
array('type' => 'hidden', 'name' => 'structure_or_data'),
array('type' => 'end_group'),
),
'options_text' => __('Options'),
);
} else {
$GLOBALS['ods_buffer'] = '';
include_once './libraries/opendocument.lib.php';
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter() {
$GLOBALS['ods_buffer'] .= '</office:spreadsheet>'
. '</office:body>'
. '</office:document-content>';
if (!PMA_exportOutputHandler(PMA_createOpenDocument('application/vnd.oasis.opendocument.spreadsheet', $GLOBALS['ods_buffer']))) {
return false;
}
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader() {
$GLOBALS['ods_buffer'] .= '<?xml version="1.0" encoding="utf-8"?' . '>'
. '<office:document-content '. $GLOBALS['OpenDocumentNS'] . 'office:version="1.0">'
. '<office:automatic-styles>'
. '<number:date-style style:name="N37" number:automatic-order="true">'
. '<number:month number:style="long"/>'
. '<number:text>/</number:text>'
. '<number:day number:style="long"/>'
. '<number:text>/</number:text>'
. '<number:year/>'
. '</number:date-style>'
. '<number:time-style style:name="N43">'
. '<number:hours number:style="long"/>'
. '<number:text>:</number:text>'
. '<number:minutes number:style="long"/>'
. '<number:text>:</number:text>'
. '<number:seconds number:style="long"/>'
. '<number:text> </number:text>'
. '<number:am-pm/>'
. '</number:time-style>'
. '<number:date-style style:name="N50" number:automatic-order="true" number:format-source="language">'
. '<number:month/>'
. '<number:text>/</number:text>'
. '<number:day/>'
. '<number:text>/</number:text>'
. '<number:year/>'
. '<number:text> </number:text>'
. '<number:hours number:style="long"/>'
. '<number:text>:</number:text>'
. '<number:minutes number:style="long"/>'
. '<number:text> </number:text>'
. '<number:am-pm/>'
. '</number:date-style>'
. '<style:style style:name="DateCell" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N37"/>'
. '<style:style style:name="TimeCell" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N43"/>'
. '<style:style style:name="DateTimeCell" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N50"/>'
. '</office:automatic-styles>'
. '<office:body>'
. '<office:spreadsheet>';
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db) {
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db) {
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db) {
return true;
}
/**
* Outputs the content of a table in ODS format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) {
global $what;
// Gets the data from the database
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$fields_cnt = PMA_DBI_num_fields($result);
$fields_meta = PMA_DBI_get_fields_meta($result);
$field_flags = array();
for ($j = 0; $j < $fields_cnt; $j++) {
$field_flags[$j] = PMA_DBI_field_flags($result, $j);
}
$GLOBALS['ods_buffer'] .= '<table:table table:name="' . htmlspecialchars($table) . '">';
// If required, get fields name at the first line
if (isset($GLOBALS[$what . '_columns'])) {
$GLOBALS['ods_buffer'] .= '<table:table-row>';
for ($i = 0; $i < $fields_cnt; $i++) {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i))) . '</text:p>'
. '</table:table-cell>';
} // end for
$GLOBALS['ods_buffer'] .= '</table:table-row>';
} // end if
// Format the data
while ($row = PMA_DBI_fetch_row($result)) {
$GLOBALS['ods_buffer'] .= '<table:table-row>';
for ($j = 0; $j < $fields_cnt; $j++) {
if (!isset($row[$j]) || is_null($row[$j])) {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($GLOBALS[$what . '_null']) . '</text:p>'
. '</table:table-cell>';
// ignore BLOB
} elseif (stristr($field_flags[$j], 'BINARY')
&& $fields_meta[$j]->blob) {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p></text:p>'
. '</table:table-cell>';
} elseif ($fields_meta[$j]->type == "date") {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="date" office:date-value="' . date("Y-m-d", strtotime($row[$j])) . '" table:style-name="DateCell">'
. '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>'
. '</table:table-cell>';
} elseif ($fields_meta[$j]->type == "time") {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="time" office:time-value="' . date("\P\TH\Hi\Ms\S", strtotime($row[$j])) . '" table:style-name="TimeCell">'
. '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>'
. '</table:table-cell>';
} elseif ($fields_meta[$j]->type == "datetime") {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="date" office:date-value="' . date("Y-m-d\TH:i:s", strtotime($row[$j])) . '" table:style-name="DateTimeCell">'
. '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>'
. '</table:table-cell>';
} elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && ! $fields_meta[$j]->blob) {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="float" office:value="' . $row[$j] . '" >'
. '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>'
. '</table:table-cell>';
} else {
$GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>'
. '</table:table-cell>';
}
} // end for
$GLOBALS['ods_buffer'] .= '</table:table-row>';
} // end while
PMA_DBI_free_result($result);
$GLOBALS['ods_buffer'] .= '</table:table>';
return true;
}
}
?>

View File

@ -0,0 +1,400 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build OpenDocument Text dumps of tables
*
* @package PhpMyAdmin-Export
* @subpackage ODT
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$hide_structure = false;
if ($plugin_param['export_type'] == 'table' && !$plugin_param['single_table']) {
$hide_structure = true;
}
$plugin_list['odt'] = array(
'text' => __('Open Document Text'),
'extension' => 'odt',
'mime_type' => 'application/vnd.oasis.opendocument.text',
'force_file' => true,
'options' => array(), /* Filled later */
'options_text' => __('Options'),
);
/* what to dump (structure/data/both) */
$plugin_list['odt']['options'][]
= array('type' => 'begin_group', 'text' => __('Dump table') , 'name' => 'general_opts');
$plugin_list['odt']['options'][]
= array('type' => 'radio', 'name' => 'structure_or_data', 'values' => array('structure' => __('structure'), 'data' => __('data'), 'structure_and_data' => __('structure and data')));
$plugin_list['odt']['options'][] = array('type' => 'end_group');
/* Structure options */
if (!$hide_structure) {
$plugin_list['odt']['options'][]
= array('type' => 'begin_group', 'name' => 'structure', 'text' => __('Object creation options'), 'force' => 'data');
if (!empty($GLOBALS['cfgRelation']['relation'])) {
$plugin_list['odt']['options'][]
= array('type' => 'bool', 'name' => 'relation', 'text' => __('Display foreign key relationships'));
}
$plugin_list['odt']['options'][]
= array('type' => 'bool', 'name' => 'comments', 'text' => __('Display comments'));
if (!empty($GLOBALS['cfgRelation']['mimework'])) {
$plugin_list['odt']['options'][]
= array('type' => 'bool', 'name' => 'mime', 'text' => __('Display MIME types'));
}
$plugin_list['odt']['options'][]
= array('type' => 'end_group');
}
/* Data */
$plugin_list['odt']['options'][]
= array('type' => 'begin_group', 'name' => 'data', 'text' => __('Data dump options'), 'force' => 'structure');
$plugin_list['odt']['options'][]
= array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row'));
$plugin_list['odt']['options'][]
= array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL with:'));
$plugin_list['odt']['options'][]
= array('type' => 'end_group');
} else {
$GLOBALS['odt_buffer'] = '';
include_once './libraries/opendocument.lib.php';
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
$GLOBALS['odt_buffer'] .= '</office:text>'
. '</office:body>'
. '</office:document-content>';
if (! PMA_exportOutputHandler(PMA_createOpenDocument('application/vnd.oasis.opendocument.text', $GLOBALS['odt_buffer']))) {
return false;
}
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
$GLOBALS['odt_buffer'] .= '<?xml version="1.0" encoding="utf-8"?' . '>'
. '<office:document-content '. $GLOBALS['OpenDocumentNS'] . 'office:version="1.0">'
. '<office:body>'
. '<office:text>';
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
$GLOBALS['odt_buffer'] .= '<text:h text:outline-level="1" text:style-name="Heading_1" text:is-list-header="true">'
. __('Database') . ' ' . htmlspecialchars($db) . '</text:h>';
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table in ODT format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
global $what;
// Gets the data from the database
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$fields_cnt = PMA_DBI_num_fields($result);
$fields_meta = PMA_DBI_get_fields_meta($result);
$field_flags = array();
for ($j = 0; $j < $fields_cnt; $j++) {
$field_flags[$j] = PMA_DBI_field_flags($result, $j);
}
$GLOBALS['odt_buffer'] .= '<text:h text:outline-level="2" text:style-name="Heading_2" text:is-list-header="true">'
. __('Dumping data for table') . ' ' . htmlspecialchars($table) . '</text:h>';
$GLOBALS['odt_buffer'] .= '<table:table table:name="' . htmlspecialchars($table) . '_structure">';
$GLOBALS['odt_buffer'] .= '<table:table-column table:number-columns-repeated="' . $fields_cnt . '"/>';
// If required, get fields name at the first line
if (isset($GLOBALS[$what . '_columns'])) {
$GLOBALS['odt_buffer'] .= '<table:table-row>';
for ($i = 0; $i < $fields_cnt; $i++) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i))) . '</text:p>'
. '</table:table-cell>';
} // end for
$GLOBALS['odt_buffer'] .= '</table:table-row>';
} // end if
// Format the data
while ($row = PMA_DBI_fetch_row($result)) {
$GLOBALS['odt_buffer'] .= '<table:table-row>';
for ($j = 0; $j < $fields_cnt; $j++) {
if (!isset($row[$j]) || is_null($row[$j])) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($GLOBALS[$what . '_null']) . '</text:p>'
. '</table:table-cell>';
// ignore BLOB
} elseif (stristr($field_flags[$j], 'BINARY')
&& $fields_meta[$j]->blob) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p></text:p>'
. '</table:table-cell>';
} elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && ! $fields_meta[$j]->blob) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="float" office:value="' . $row[$j] . '" >'
. '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>'
. '</table:table-cell>';
} else {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>'
. '</table:table-cell>';
}
} // end for
$GLOBALS['odt_buffer'] .= '</table:table-row>';
} // end while
PMA_DBI_free_result($result);
$GLOBALS['odt_buffer'] .= '</table:table>';
return true;
}
/**
* Outputs table's structure
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param bool $do_relation whether to include relation comments
* @param bool $do_comments whether to include the pmadb-style column comments
* as comments in the structure; this is deprecated
* but the parameter is left here because export.php
* calls PMA_exportStructure() also for other export
* types which use this parameter
* @param bool $do_mime whether to include mime comments
* @param bool $dates whether to include creation/update/check dates
* @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in'
* @param string $export_type 'server', 'database', 'table'
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type)
{
global $cfgRelation;
/* Heading */
$GLOBALS['odt_buffer'] .= '<text:h text:outline-level="2" text:style-name="Heading_2" text:is-list-header="true">'
. __('Table structure for table') . ' ' . htmlspecialchars($table) . '</text:h>';
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = PMA_DBI_get_table_indexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
/**
* Gets fields properties
*/
PMA_DBI_select_db($db);
// Check if we can use Relations
if ($do_relation && !empty($cfgRelation['relation'])) {
// Find which tables are related with the current one and write it in
// an array
$res_rel = PMA_getForeigners($db, $table);
if ($res_rel && count($res_rel) > 0) {
$have_rel = true;
} else {
$have_rel = false;
}
} else {
$have_rel = false;
} // end if
/**
* Displays the table structure
*/
$GLOBALS['odt_buffer'] .= '<table:table table:name="' . htmlspecialchars($table) . '_data">';
$columns_cnt = 4;
if ($do_relation && $have_rel) {
$columns_cnt++;
}
if ($do_comments) {
$columns_cnt++;
}
if ($do_mime && $cfgRelation['mimework']) {
$columns_cnt++;
}
$GLOBALS['odt_buffer'] .= '<table:table-column table:number-columns-repeated="' . $columns_cnt . '"/>';
/* Header */
$GLOBALS['odt_buffer'] .= '<table:table-row>';
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . __('Column') . '</text:p>'
. '</table:table-cell>';
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . __('Type') . '</text:p>'
. '</table:table-cell>';
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . __('Null') . '</text:p>'
. '</table:table-cell>';
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . __('Default') . '</text:p>'
. '</table:table-cell>';
if ($do_relation && $have_rel) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . __('Links to') . '</text:p>'
. '</table:table-cell>';
}
if ($do_comments) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . __('Comments') . '</text:p>'
. '</table:table-cell>';
$comments = PMA_getComments($db, $table);
}
if ($do_mime && $cfgRelation['mimework']) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . __('MIME type') . '</text:p>'
. '</table:table-cell>';
$mime_map = PMA_getMIME($db, $table, true);
}
$GLOBALS['odt_buffer'] .= '</table:table-row>';
$columns = PMA_DBI_get_columns($db, $table);
foreach ($columns as $column) {
$field_name = $column['Field'];
$GLOBALS['odt_buffer'] .= '<table:table-row>';
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($field_name) . '</text:p>'
. '</table:table-cell>';
$extracted_fieldspec = PMA_extractFieldSpec($column['Type']);
$type = htmlspecialchars($extracted_fieldspec['print_type']);
if (empty($type)) {
$type = '&nbsp;';
}
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($type) . '</text:p>'
. '</table:table-cell>';
if (!isset($column['Default'])) {
if ($column['Null'] != 'NO') {
$column['Default'] = 'NULL';
} else {
$column['Default'] = '';
}
} else {
$column['Default'] = $column['Default'];
}
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . (($column['Null'] == '' || $column['Null'] == 'NO') ? __('No') : __('Yes')) . '</text:p>'
. '</table:table-cell>';
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($column['Default']) . '</text:p>'
. '</table:table-cell>';
if ($do_relation && $have_rel) {
if (isset($res_rel[$field_name])) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($res_rel[$field_name]['foreign_table'] . ' (' . $res_rel[$field_name]['foreign_field'] . ')') . '</text:p>'
. '</table:table-cell>';
}
}
if ($do_comments) {
if (isset($comments[$field_name])) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($comments[$field_name]) . '</text:p>'
. '</table:table-cell>';
} else {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p></text:p>'
. '</table:table-cell>';
}
}
if ($do_mime && $cfgRelation['mimework']) {
if (isset($mime_map[$field_name])) {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype'])) . '</text:p>'
. '</table:table-cell>';
} else {
$GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
. '<text:p></text:p>'
. '</table:table-cell>';
}
}
$GLOBALS['odt_buffer'] .= '</table:table-row>';
} // end while
$GLOBALS['odt_buffer'] .= '</table:table>';
return true;
} // end of the 'PMA_exportStructure' function
} // end else
?>

View File

@ -0,0 +1,454 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Produce a PDF report (export) from a query
*
* @package PhpMyAdmin-Export
* @subpackage PDF
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['pdf'] = array(
'text' => __('PDF'),
'extension' => 'pdf',
'mime_type' => 'application/pdf',
'force_file' => true,
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'message_only', 'name' => 'explanation', 'text' => __('(Generates a report containing the data of a single table)')),
array('type' => 'text', 'name' => 'report_title', 'text' => __('Report title:')),
array('type' => 'hidden', 'name' => 'structure_or_data'),
array('type' => 'end_group')
),
'options_text' => __('Options'),
);
} else {
include_once './libraries/PDF.class.php';
/**
* Adapted from a LGPL script by Philip Clarke
* @package PhpMyAdmin-Export
* @subpackage PDF
*/
class PMA_Export_PDF extends PMA_PDF
{
var $tablewidths;
var $headerset;
function checkPageBreak($h = 0, $y = '', $addpage = true)
{
if ($this->empty_string($y)) {
$y = $this->y;
}
$current_page = $this->page;
if ((($y + $h) > $this->PageBreakTrigger) AND (! $this->InFooter) AND ($this->AcceptPageBreak())) {
if ($addpage) {
//Automatic page break
$x = $this->x;
$this->AddPage($this->CurOrientation);
$this->y = $this->dataY;
$oldpage = $this->page - 1;
if ($this->rtl) {
if ($this->pagedim[$this->page]['orm'] != $this->pagedim[$oldpage]['orm']) {
$this->x = $x - ($this->pagedim[$this->page]['orm'] - $this->pagedim[$oldpage]['orm']);
} else {
$this->x = $x;
}
} else {
if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
$this->x = $x + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$oldpage]['olm']);
} else {
$this->x = $x;
}
}
}
return true;
}
if ($current_page != $this->page) {
// account for columns mode
return true;
}
return false;
}
function Header()
{
global $maxY;
// Check if header for this page already exists
if (! isset($this->headerset[$this->page])) {
$fullwidth = 0;
foreach ($this->tablewidths as $width) {
$fullwidth += $width;
}
$this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 5);
$this->cellFontSize = $this->FontSizePt ;
$this->SetFont(PMA_PDF_FONT, '', ($this->titleFontSize ? $this->titleFontSize : $this->FontSizePt));
$this->Cell(0, $this->FontSizePt, $this->titleText, 0, 1, 'C');
$this->SetFont(PMA_PDF_FONT, '', $this->cellFontSize);
$this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 2.5);
$this->Cell(
0, $this->FontSizePt,
__('Database') . ': ' . $this->currentDb . ', ' . __('Table') . ': ' . $this->currentTable,
0, 1, 'L'
);
$l = ($this->lMargin);
foreach ($this->colTitles as $col => $txt) {
$this->SetXY($l, ($this->tMargin));
$this->MultiCell($this->tablewidths[$col], $this->FontSizePt, $txt);
$l += $this->tablewidths[$col] ;
$maxY = ($maxY < $this->getY()) ? $this->getY() : $maxY ;
}
$this->SetXY($this->lMargin, $this->tMargin);
$this->setFillColor(200, 200, 200);
$l = ($this->lMargin);
foreach ($this->colTitles as $col => $txt) {
$this->SetXY($l, $this->tMargin);
$this->cell($this->tablewidths[$col], $maxY-($this->tMargin), '', 1, 0, 'L', 1);
$this->SetXY($l, $this->tMargin);
$this->MultiCell($this->tablewidths[$col], $this->FontSizePt, $txt, 0, 'C');
$l += $this->tablewidths[$col];
}
$this->setFillColor(255, 255, 255);
// set headerset
$this->headerset[$this->page] = 1;
}
$this->dataY = $maxY;
}
function morepagestable($lineheight=8)
{
// some things to set and 'remember'
$l = $this->lMargin;
$startheight = $h = $this->dataY;
$startpage = $currpage = $this->page;
// calculate the whole width
$fullwidth = 0;
foreach ($this->tablewidths as $width) {
$fullwidth += $width;
}
// Now let's start to write the table
$row = 0;
$tmpheight = array();
$maxpage = $this->page;
while ($data = PMA_DBI_fetch_row($this->results)) {
$this->page = $currpage;
// write the horizontal borders
$this->Line($l, $h, $fullwidth+$l, $h);
// write the content and remember the height of the highest col
foreach ($data as $col => $txt) {
$this->page = $currpage;
$this->SetXY($l, $h);
if ($this->tablewidths[$col] > 0) {
$this->MultiCell($this->tablewidths[$col], $lineheight, $txt, 0, $this->colAlign[$col]);
$l += $this->tablewidths[$col];
}
if (!isset($tmpheight[$row.'-'.$this->page])) {
$tmpheight[$row.'-'.$this->page] = 0;
}
if ($tmpheight[$row.'-'.$this->page] < $this->GetY()) {
$tmpheight[$row.'-'.$this->page] = $this->GetY();
}
if ($this->page > $maxpage) {
$maxpage = $this->page;
}
unset($data[$col]);
}
// get the height we were in the last used page
$h = $tmpheight[$row.'-'.$maxpage];
// set the "pointer" to the left margin
$l = $this->lMargin;
// set the $currpage to the last page
$currpage = $maxpage;
unset($data[$row]);
$row++;
}
// draw the borders
// we start adding a horizontal line on the last page
$this->page = $maxpage;
$this->Line($l, $h, $fullwidth+$l, $h);
// now we start at the top of the document and walk down
for ($i = $startpage; $i <= $maxpage; $i++) {
$this->page = $i;
$l = $this->lMargin;
$t = ($i == $startpage) ? $startheight : $this->tMargin;
$lh = ($i == $maxpage) ? $h : $this->h-$this->bMargin;
$this->Line($l, $t, $l, $lh);
foreach ($this->tablewidths as $width) {
$l += $width;
$this->Line($l, $t, $l, $lh);
}
}
// set it to the last page, if not it'll cause some problems
$this->page = $maxpage;
}
function setAttributes($attr = array())
{
foreach ($attr as $key => $val) {
$this->$key = $val ;
}
}
function setTopMargin($topMargin)
{
$this->tMargin = $topMargin;
}
function mysql_report($query)
{
unset($this->tablewidths);
unset($this->colTitles);
unset($this->titleWidth);
unset($this->colFits);
unset($this->display_column);
unset($this->colAlign);
/**
* Pass 1 for column widths
*/
$this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED);
$this->numFields = PMA_DBI_num_fields($this->results);
$this->fields = PMA_DBI_get_fields_meta($this->results);
// sColWidth = starting col width (an average size width)
$availableWidth = $this->w - $this->lMargin - $this->rMargin;
$this->sColWidth = $availableWidth / $this->numFields;
$totalTitleWidth = 0;
// loop through results header and set initial col widths/ titles/ alignment
// if a col title is less than the starting col width, reduce that column size
$colFits = array();
for ($i = 0; $i < $this->numFields; $i++) {
$stringWidth = $this->getstringwidth($this->fields[$i]->name) + 6 ;
// save the real title's width
$titleWidth[$i] = $stringWidth;
$totalTitleWidth += $stringWidth;
// set any column titles less than the start width to the column title width
if ($stringWidth < $this->sColWidth) {
$colFits[$i] = $stringWidth ;
}
$this->colTitles[$i] = $this->fields[$i]->name;
$this->display_column[$i] = true;
switch ($this->fields[$i]->type) {
case 'int':
$this->colAlign[$i] = 'R';
break;
case 'blob':
case 'tinyblob':
case 'mediumblob':
case 'longblob':
/**
* @todo do not deactivate completely the display
* but show the field's name and [BLOB]
*/
if (stristr($this->fields[$i]->flags, 'BINARY')) {
$this->display_column[$i] = false;
unset($this->colTitles[$i]);
}
$this->colAlign[$i] = 'L';
break;
default:
$this->colAlign[$i] = 'L';
}
}
// title width verification
if ($totalTitleWidth > $availableWidth) {
$adjustingMode = true;
} else {
$adjustingMode = false;
// we have enough space for all the titles at their
// original width so use the true title's width
foreach ($titleWidth as $key => $val) {
$colFits[$key] = $val;
}
}
// loop through the data; any column whose contents
// is greater than the column size is resized
/**
* @todo force here a LIMIT to avoid reading all rows
*/
while ($row = PMA_DBI_fetch_row($this->results)) {
foreach ($colFits as $key => $val) {
$stringWidth = $this->getstringwidth($row[$key]) + 6 ;
if ($adjustingMode && ($stringWidth > $this->sColWidth)) {
// any column whose data's width is bigger than
// the start width is now discarded
unset($colFits[$key]);
} else {
// if data's width is bigger than the current column width,
// enlarge the column (but avoid enlarging it if the
// data's width is very big)
if ($stringWidth > $val && $stringWidth < ($this->sColWidth * 3)) {
$colFits[$key] = $stringWidth ;
}
}
}
}
$totAlreadyFitted = 0;
foreach ($colFits as $key => $val) {
// set fitted columns to smallest size
$this->tablewidths[$key] = $val;
// to work out how much (if any) space has been freed up
$totAlreadyFitted += $val;
}
if ($adjustingMode) {
$surplus = (sizeof($colFits) * $this->sColWidth) - $totAlreadyFitted;
$surplusToAdd = $surplus / ($this->numFields - sizeof($colFits));
} else {
$surplusToAdd = 0;
}
for ($i=0; $i < $this->numFields; $i++) {
if (!in_array($i, array_keys($colFits))) {
$this->tablewidths[$i] = $this->sColWidth + $surplusToAdd;
}
if ($this->display_column[$i] == false) {
$this->tablewidths[$i] = 0;
}
}
ksort($this->tablewidths);
PMA_DBI_free_result($this->results);
// Pass 2
$this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED);
$this->setY($this->tMargin);
$this->AddPage();
$this->SetFont(PMA_PDF_FONT, '', 9);
$this->morepagestable($this->FontSizePt);
PMA_DBI_free_result($this->results);
} // end of mysql_report function
} // end of PMA_Export_PDF class
$pdf = new PMA_Export_PDF('L', 'pt', 'A3');
/**
* Finalize the pdf.
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
global $pdf;
// instead of $pdf->Output():
if (!PMA_exportOutputHandler($pdf->getPDFData())) {
return false;
}
return true;
}
/**
* Initialize the pdf to export data.
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
global $pdf_report_title;
global $pdf;
$pdf->Open();
$attr = array('titleFontSize' => 18, 'titleText' => $pdf_report_title);
$pdf->setAttributes($attr);
$pdf->setTopMargin(30);
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table in PDF format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
global $pdf;
$attr=array('currentDb' => $db, 'currentTable' => $table);
$pdf->setAttributes($attr);
$pdf->mysql_report($sql_query);
return true;
} // end of the 'PMA_exportData()' function
}
?>

View File

@ -0,0 +1,175 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build dumps of tables as PHP Arrays
*
* @package PhpMyAdmin-Export
* @subpackage PHP
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['php_array'] = array(
'text' => __('PHP array'),
'extension' => 'php',
'mime_type' => 'text/plain',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array(
'type' => 'hidden',
'name' => 'structure_or_data',
),
array('type' => 'end_group')
),
'options_text' => __('Options'),
);
} else {
/**
* Set of functions used to build exports of tables
*/
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
PMA_exportOutputHandler(
'<?php' . $GLOBALS['crlf']
. '/**' . $GLOBALS['crlf']
. ' * Export to PHP Array plugin for PHPMyAdmin' . $GLOBALS['crlf']
. ' * @version 0.2b' . $GLOBALS['crlf']
. ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf']
);
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
PMA_exportOutputHandler('//' . $GLOBALS['crlf'] . '// Database ' . PMA_backquote($db) . $GLOBALS['crlf'] . '//' . $GLOBALS['crlf']);
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table as a fragment of PHP code
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$columns_cnt = PMA_DBI_num_fields($result);
for ($i = 0; $i < $columns_cnt; $i++) {
$columns[$i] = stripslashes(PMA_DBI_field_name($result, $i));
}
unset($i);
// fix variable names (based on http://www.php.net/manual/language.variables.basics.php)
if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $table) == false) {
// fix invalid chars in variable names by replacing them with underscores
$tablefixed = preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '_', $table);
// variable name must not start with a number or dash...
if (preg_match('/^[a-zA-Z_\x7f-\xff]/', $tablefixed) == false) {
$tablefixed = '_' . $tablefixed;
}
} else {
$tablefixed = $table;
}
$buffer = '';
$record_cnt = 0;
while ($record = PMA_DBI_fetch_row($result)) {
$record_cnt++;
// Output table name as comment if this is the first record of the table
if ($record_cnt == 1) {
$buffer .= $crlf . '// ' . PMA_backquote($db) . '.' . PMA_backquote($table) . $crlf;
$buffer .= '$' . $tablefixed . ' = array(' . $crlf;
$buffer .= ' array(';
} else {
$buffer .= ',' . $crlf . ' array(';
}
for ($i = 0; $i < $columns_cnt; $i++) {
$buffer .= var_export($columns[$i], true) . " => " . var_export($record[$i], true) . (($i + 1 >= $columns_cnt) ? '' : ',');
}
$buffer .= ')';
}
$buffer .= $crlf . ');' . $crlf;
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
PMA_DBI_free_result($result);
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,304 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Export to Texy! text.
*
* @package PhpMyAdmin-Export
* @subpackage Texy
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['texytext'] = array(
'text' => __('Texy! text'),
'extension' => 'txt',
'mime_type' => 'text/plain',
'options' => array(
/* what to dump (structure/data/both) */
array('type' => 'begin_group', 'text' => __('Dump table'), 'name' => 'general_opts'),
array('type' => 'radio', 'name' => 'structure_or_data', 'values' => array('structure' => __('structure'), 'data' => __('data'), 'structure_and_data' => __('structure and data'))),
array('type' => 'end_group'),
array('type' => 'begin_group', 'name' => 'data', 'text' => __('Data dump options'), 'force' => 'structure'),
array('type' => 'text', 'name' => 'null', 'text' => __('Replace NULL by')),
array('type' => 'bool', 'name' => 'columns', 'text' => __('Put columns names in the first row')),
array('type' => 'end_group'),
),
'options_text' => __('Options'),
);
} else {
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter() {
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader() {
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db) {
return PMA_exportOutputHandler('===' . __('Database') . ' ' . $db . "\n\n");
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db) {
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db) {
return true;
}
/**
* Outputs the content of a table in Texy format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
global $what;
if (! PMA_exportOutputHandler('== ' . __('Dumping data for table') . ' ' . $table . "\n\n")) {
return false;
}
// Gets the data from the database
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$fields_cnt = PMA_DBI_num_fields($result);
// If required, get fields name at the first line
if (isset($GLOBALS[$what . '_columns'])) {
$text_output = "|------\n";
for ($i = 0; $i < $fields_cnt; $i++) {
$text_output .= '|' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i)));
} // end for
$text_output .= "\n|------\n";
if (! PMA_exportOutputHandler($text_output)) {
return false;
}
} // end if
// Format the data
while ($row = PMA_DBI_fetch_row($result)) {
$text_output = '';
for ($j = 0; $j < $fields_cnt; $j++) {
if (! isset($row[$j]) || is_null($row[$j])) {
$value = $GLOBALS[$what . '_null'];
} elseif ($row[$j] == '0' || $row[$j] != '') {
$value = $row[$j];
} else {
$value = ' ';
}
$text_output .= '|' . htmlspecialchars($value);
} // end for
$text_output .= "\n";
if (! PMA_exportOutputHandler($text_output)) {
return false;
}
} // end while
PMA_DBI_free_result($result);
return true;
}
/**
* Outputs table's structure
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param bool $do_relation whether to include relation comments
* @param bool $do_comments whether to include the pmadb-style column comments
* as comments in the structure; this is deprecated
* but the parameter is left here because export.php
* calls PMA_exportStructure() also for other export
* types which use this parameter
* @param bool $do_mime whether to include mime comments
* @param bool $dates whether to include creation/update/check dates
* @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in'
* @param string $export_type 'server', 'database', 'table'
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type)
{
global $cfgRelation;
if (! PMA_exportOutputHandler('== ' . __('Table structure for table') . ' ' .$table . "\n\n")) {
return false;
}
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = PMA_DBI_get_table_indexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
/**
* Gets fields properties
*/
PMA_DBI_select_db($db);
// Check if we can use Relations
if ($do_relation && ! empty($cfgRelation['relation'])) {
// Find which tables are related with the current one and write it in
// an array
$res_rel = PMA_getForeigners($db, $table);
if ($res_rel && count($res_rel) > 0) {
$have_rel = true;
} else {
$have_rel = false;
}
} else {
$have_rel = false;
} // end if
/**
* Displays the table structure
*/
$columns_cnt = 4;
if ($do_relation && $have_rel) {
$columns_cnt++;
}
if ($do_comments && $cfgRelation['commwork']) {
$columns_cnt++;
}
if ($do_mime && $cfgRelation['mimework']) {
$columns_cnt++;
}
$text_output = "|------\n";
$text_output .= '|' . __('Column');
$text_output .= '|' . __('Type');
$text_output .= '|' . __('Null');
$text_output .= '|' . __('Default');
if ($do_relation && $have_rel) {
$text_output .= '|' . __('Links to');
}
if ($do_comments) {
$text_output .= '|' . __('Comments');
$comments = PMA_getComments($db, $table);
}
if ($do_mime && $cfgRelation['mimework']) {
$text_output .= '|' . htmlspecialchars('MIME');
$mime_map = PMA_getMIME($db, $table, true);
}
$text_output .= "\n|------\n";
if (! PMA_exportOutputHandler($text_output)) {
return false;
}
$columns = PMA_DBI_get_columns($db, $table);
foreach ($columns as $column) {
$text_output = '';
$extracted_fieldspec = PMA_extractFieldSpec($column['Type']);
$type = $extracted_fieldspec['print_type'];
if (empty($type)) {
$type = '&nbsp;';
}
if (! isset($column['Default'])) {
if ($column['Null'] != 'NO') {
$column['Default'] = 'NULL';
}
}
$fmt_pre = '';
$fmt_post = '';
if (in_array($column['Field'], $unique_keys)) {
$fmt_pre = '**' . $fmt_pre;
$fmt_post = $fmt_post . '**';
}
if ($column['Key']=='PRI') {
$fmt_pre = '//' . $fmt_pre;
$fmt_post = $fmt_post . '//';
}
$text_output .= '|' . $fmt_pre . htmlspecialchars($column['Field']) . $fmt_post;
$text_output .= '|' . htmlspecialchars($type);
$text_output .= '|' . (($column['Null'] == '' || $column['Null'] == 'NO') ? __('No') : __('Yes'));
$text_output .= '|' . htmlspecialchars(isset($column['Default']) ? $column['Default'] : '');
$field_name = $column['Field'];
if ($do_relation && $have_rel) {
$text_output .= '|' . (isset($res_rel[$field_name]) ? htmlspecialchars($res_rel[$field_name]['foreign_table'] . ' (' . $res_rel[$field_name]['foreign_field'] . ')') : '');
}
if ($do_comments && $cfgRelation['commwork']) {
$text_output .= '|' . (isset($comments[$field_name]) ? htmlspecialchars($comments[$field_name]) : '');
}
if ($do_mime && $cfgRelation['mimework']) {
$text_output .= '|' . (isset($mime_map[$field_name]) ? htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype'])) : '');
}
$text_output .= "\n";
if (! PMA_exportOutputHandler($text_output)) {
return false;
}
} // end while
return true;
}
}
?>

View File

@ -0,0 +1,386 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build XML dumps of tables
*
* @package PhpMyAdmin-Export
* @subpackage XML
*/
if (! defined('PHPMYADMIN')) {
exit;
}
if (!strlen($GLOBALS['db'])) { /* Can't do server export */
return;
}
if (isset($plugin_list)) {
$plugin_list['xml'] = array(
'text' => __('XML'),
'extension' => 'xml',
'mime_type' => 'text/xml',
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array('type' => 'hidden', 'name' => 'structure_or_data'),
array('type' => 'end_group')
),
'options_text' => __('Options')
);
/* Export structure */
$plugin_list['xml']['options'][] = array(
'type' => 'begin_group',
'name' => 'structure',
'text' => __('Object creation options (all are recommended)')
);
if (!PMA_DRIZZLE) {
$plugin_list['xml']['options'][] = array(
'type' => 'bool',
'name' => 'export_functions',
'text' => __('Functions')
);
$plugin_list['xml']['options'][] = array(
'type' => 'bool',
'name' => 'export_procedures',
'text' => __('Procedures')
);
}
$plugin_list['xml']['options'][] = array(
'type' => 'bool',
'name' => 'export_tables',
'text' => __('Tables')
);
if (!PMA_DRIZZLE) {
$plugin_list['xml']['options'][] = array(
'type' => 'bool',
'name' => 'export_triggers',
'text' => __('Triggers')
);
$plugin_list['xml']['options'][] = array(
'type' => 'bool',
'name' => 'export_views',
'text' => __('Views')
);
}
$plugin_list['xml']['options'][] = array(
'type' => 'end_group'
);
/* Data */
$plugin_list['xml']['options'][] = array(
'type' => 'begin_group',
'name' => 'data',
'text' => __('Data dump options')
);
$plugin_list['xml']['options'][] = array(
'type' => 'bool',
'name' => 'export_contents',
'text' => __('Export contents')
);
$plugin_list['xml']['options'][] = array(
'type' => 'end_group'
);
} else {
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
$foot = '</pma_xml_export>';
return PMA_exportOutputHandler($foot);
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
global $crlf;
global $cfg;
global $db;
global $table;
global $tables;
$export_struct = isset($GLOBALS['xml_export_functions']) || isset($GLOBALS['xml_export_procedures'])
|| isset($GLOBALS['xml_export_tables']) || isset($GLOBALS['xml_export_triggers'])
|| isset($GLOBALS['xml_export_views']);
$export_data = isset($GLOBALS['xml_export_contents']) ? true : false;
if ($GLOBALS['output_charset_conversion']) {
$charset = $GLOBALS['charset_of_file'];
} else {
$charset = 'utf-8';
}
$head = '<?xml version="1.0" encoding="' . $charset . '"?>' . $crlf
. '<!--' . $crlf
. '- phpMyAdmin XML Dump' . $crlf
. '- version ' . PMA_VERSION . $crlf
. '- http://www.phpmyadmin.net' . $crlf
. '-' . $crlf
. '- ' . __('Host') . ': ' . $cfg['Server']['host'];
if (!empty($cfg['Server']['port'])) {
$head .= ':' . $cfg['Server']['port'];
}
$head .= $crlf
. '- ' . __('Generation Time') . ': ' . PMA_localisedDate() . $crlf
. '- ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf
. '- ' . __('PHP Version') . ': ' . phpversion() . $crlf
. '-->' . $crlf . $crlf;
$head .= '<pma_xml_export version="1.0"' . (($export_struct) ? ' xmlns:pma="http://www.phpmyadmin.net/some_doc_url/"' : '') . '>' . $crlf;
if ($export_struct) {
if (PMA_DRIZZLE) {
$result = PMA_DBI_fetch_result("
SELECT
'utf8' AS DEFAULT_CHARACTER_SET_NAME,
DEFAULT_COLLATION_NAME
FROM data_dictionary.SCHEMAS
WHERE SCHEMA_NAME = '" . PMA_sqlAddSlashes($db) . "'");
} else {
$result = PMA_DBI_fetch_result('SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME` FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME` = \''.PMA_sqlAddSlashes($db).'\' LIMIT 1');
}
$db_collation = $result[0]['DEFAULT_COLLATION_NAME'];
$db_charset = $result[0]['DEFAULT_CHARACTER_SET_NAME'];
$head .= ' <!--' . $crlf;
$head .= ' - Structure schemas' . $crlf;
$head .= ' -->' . $crlf;
$head .= ' <pma:structure_schemas>' . $crlf;
$head .= ' <pma:database name="' . htmlspecialchars($db) . '" collation="' . $db_collation . '" charset="' . $db_charset . '">' . $crlf;
if (count($tables) == 0) {
$tables[] = $table;
}
foreach ($tables as $table) {
// Export tables and views
$result = PMA_DBI_fetch_result('SHOW CREATE TABLE ' . PMA_backquote($db) . '.' . PMA_backquote($table), 0);
$tbl = $result[$table][1];
$is_view = PMA_Table::isView($db, $table);
if ($is_view) {
$type = 'view';
} else {
$type = 'table';
}
if ($is_view && ! isset($GLOBALS['xml_export_views'])) {
continue;
}
if (! $is_view && ! isset($GLOBALS['xml_export_tables'])) {
continue;
}
$head .= ' <pma:' . $type . ' name="' . $table . '">' . $crlf;
$tbl = " " . htmlspecialchars($tbl);
$tbl = str_replace("\n", "\n ", $tbl);
$head .= $tbl . ';' . $crlf;
$head .= ' </pma:' . $type . '>' . $crlf;
if (isset($GLOBALS['xml_export_triggers']) && $GLOBALS['xml_export_triggers']) {
// Export triggers
$triggers = PMA_DBI_get_triggers($db, $table);
if ($triggers) {
foreach ($triggers as $trigger) {
$code = $trigger['create'];
$head .= ' <pma:trigger name="' . $trigger['name'] . '">' . $crlf;
// Do some formatting
$code = substr(rtrim($code), 0, -3);
$code = " " . htmlspecialchars($code);
$code = str_replace("\n", "\n ", $code);
$head .= $code . $crlf;
$head .= ' </pma:trigger>' . $crlf;
}
unset($trigger);
unset($triggers);
}
}
}
if (isset($GLOBALS['xml_export_functions']) && $GLOBALS['xml_export_functions']) {
// Export functions
$functions = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION');
if ($functions) {
foreach ($functions as $function) {
$head .= ' <pma:function name="' . $function . '">' . $crlf;
// Do some formatting
$sql = PMA_DBI_get_definition($db, 'FUNCTION', $function);
$sql = rtrim($sql);
$sql = " " . htmlspecialchars($sql);
$sql = str_replace("\n", "\n ", $sql);
$head .= $sql . $crlf;
$head .= ' </pma:function>' . $crlf;
}
unset($create_func);
unset($function);
unset($functions);
}
}
if (isset($GLOBALS['xml_export_procedures']) && $GLOBALS['xml_export_procedures']) {
// Export procedures
$procedures = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE');
if ($procedures) {
foreach ($procedures as $procedure) {
$head .= ' <pma:procedure name="' . $procedure . '">' . $crlf;
// Do some formatting
$sql = PMA_DBI_get_definition($db, 'PROCEDURE', $procedure);
$sql = rtrim($sql);
$sql = " " . htmlspecialchars($sql);
$sql = str_replace("\n", "\n ", $sql);
$head .= $sql . $crlf;
$head .= ' </pma:procedure>' . $crlf;
}
unset($create_proc);
unset($procedure);
unset($procedures);
}
}
unset($result);
$head .= ' </pma:database>' . $crlf;
$head .= ' </pma:structure_schemas>' . $crlf;
if ($export_data) {
$head .= $crlf;
}
}
return PMA_exportOutputHandler($head);
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
global $crlf;
if (isset($GLOBALS['xml_export_contents']) && $GLOBALS['xml_export_contents']) {
$head = ' <!--' . $crlf
. ' - ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf
. ' -->' . $crlf
. ' <database name="' . htmlspecialchars($db) . '">' . $crlf;
return PMA_exportOutputHandler($head);
} else {
return true;
}
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
global $crlf;
if (isset($GLOBALS['xml_export_contents']) && $GLOBALS['xml_export_contents']) {
return PMA_exportOutputHandler(' </database>' . $crlf);
} else {
return true;
}
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table in XML format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
if (isset($GLOBALS['xml_export_contents']) && $GLOBALS['xml_export_contents']) {
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$columns_cnt = PMA_DBI_num_fields($result);
$columns = array();
for ($i = 0; $i < $columns_cnt; $i++) {
$columns[$i] = stripslashes(str_replace(' ', '_', PMA_DBI_field_name($result, $i)));
}
unset($i);
$buffer = ' <!-- ' . __('Table') . ' ' . $table . ' -->' . $crlf;
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
while ($record = PMA_DBI_fetch_row($result)) {
$buffer = ' <table name="' . htmlspecialchars($table) . '">' . $crlf;
for ($i = 0; $i < $columns_cnt; $i++) {
// If a cell is NULL, still export it to preserve the XML structure
if (!isset($record[$i]) || is_null($record[$i])) {
$record[$i] = 'NULL';
}
$buffer .= ' <column name="' . htmlspecialchars($columns[$i]) . '">' . htmlspecialchars((string)$record[$i])
. '</column>' . $crlf;
}
$buffer .= ' </table>' . $crlf;
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
}
PMA_DBI_free_result($result);
}
return true;
} // end of the 'PMA_getTableXML()' function
}
?>

View File

@ -0,0 +1,169 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Set of functions used to build YAML dumps of tables
*
* @package PhpMyAdmin-Export
* @subpackage YAML
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
*
*/
if (isset($plugin_list)) {
$plugin_list['yaml'] = array(
'text' => 'YAML',
'extension' => 'yml',
'mime_type' => 'text/yaml',
'force_file' => true,
'options' => array(
array('type' => 'begin_group', 'name' => 'general_opts'),
array(
'type' => 'hidden',
'name' => 'structure_or_data',
),
array('type' => 'end_group')
),
'options_text' => __('Options'),
);
} else {
/**
* Set of functions used to build exports of tables
*/
/**
* Outputs export footer
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportFooter()
{
PMA_exportOutputHandler('...' . $GLOBALS['crlf']);
return true;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportHeader()
{
PMA_exportOutputHandler('%YAML 1.1' . $GLOBALS['crlf'] . '---' . $GLOBALS['crlf']);
return true;
}
/**
* Outputs database header
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBHeader($db)
{
return true;
}
/**
* Outputs database footer
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBFooter($db)
{
return true;
}
/**
* Outputs CREATE DATABASE statement
*
* @param string $db Database name
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportDBCreate($db)
{
return true;
}
/**
* Outputs the content of a table in YAML format
*
* @param string $db database name
* @param string $table table name
* @param string $crlf the end of line sequence
* @param string $error_url the url to go back in case of error
* @param string $sql_query SQL query for obtaining data
* @return bool Whether it succeeded
*
* @access public
*/
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query)
{
$result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$columns_cnt = PMA_DBI_num_fields($result);
for ($i = 0; $i < $columns_cnt; $i++) {
$columns[$i] = stripslashes(PMA_DBI_field_name($result, $i));
}
unset($i);
$buffer = '';
$record_cnt = 0;
while ($record = PMA_DBI_fetch_row($result)) {
$record_cnt++;
// Output table name as comment if this is the first record of the table
if ($record_cnt == 1) {
$buffer = '# ' . $db . '.' . $table . $crlf;
$buffer .= '-' . $crlf;
} else {
$buffer = '-' . $crlf;
}
for ($i = 0; $i < $columns_cnt; $i++) {
if (! isset($record[$i])) {
continue;
}
$column = $columns[$i];
if (is_null($record[$i])) {
$buffer .= ' ' . $column . ': null' . $crlf;
continue;
}
if (is_numeric($record[$i])) {
$buffer .= ' ' . $column . ': ' . $record[$i] . $crlf;
continue;
}
$record[$i] = str_replace(array('\\', '"', "\n", "\r"), array('\\\\', '\"', '\n', '\r'), $record[$i]);
$buffer .= ' ' . $column . ': "' . $record[$i] . '"' . $crlf;
}
if (! PMA_exportOutputHandler($buffer)) {
return false;
}
}
PMA_DBI_free_result($result);
return true;
}
}
?>

View File

@ -0,0 +1,95 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions for listing directories
*
* @todo rename to file_listing.lib.php
* @package PhpMyAdmin
*/
/**
* Returns array of filtered file names
*
* @param string $dir directory to list
* @param string $expression regular expression to match files
* @return array sorted file list on success, false on failure
*/
function PMA_getDirContent($dir, $expression = '')
{
if (file_exists($dir) && $handle = @opendir($dir)) {
$result = array();
if (substr($dir, -1) != '/') {
$dir .= '/';
}
while ($file = @readdir($handle)) {
// for PHP < 5.2.4, is_file() gives a warning when using open_basedir
// and verifying '..' or '.'
if ('.' != $file && '..' != $file && is_file($dir . $file) && ($expression == '' || preg_match($expression, $file))) {
$result[] = $file;
}
}
@closedir($handle);
asort($result);
return $result;
} else {
return false;
}
}
/**
* Returns options of filtered file names
*
* @param string $dir directory to list
* @param string $extensions regullar expression to match files
* @param string $active currently active choice
* @return array sorted file list on success, false on failure
*/
function PMA_getFileSelectOptions($dir, $extensions = '', $active = '')
{
$list = PMA_getDirContent($dir, $extensions);
if ($list === false) {
return false;
}
$result = '';
foreach ($list as $key => $val) {
$result .= '<option value="'. htmlspecialchars($val) . '"';
if ($val == $active) {
$result .= ' selected="selected"';
}
$result .= '>' . htmlspecialchars($val) . '</option>' . "\n";
}
return $result;
}
/**
* Get currently supported decompressions.
*
* @return string | separated list of extensions usable in PMA_getDirContent
*/
function PMA_supportedDecompressions()
{
global $cfg;
$compressions = '';
if ($cfg['GZipDump'] && @function_exists('gzopen')) {
if (!empty($compressions)) {
$compressions .= '|';
}
$compressions .= 'gz';
}
if ($cfg['BZipDump'] && @function_exists('bzopen')) {
if (!empty($compressions)) {
$compressions .= '|';
}
$compressions .= 'bz2';
}
if ($cfg['ZipDump'] && @function_exists('gzinflate')) {
if (!empty($compressions)) {
$compressions .= '|';
}
$compressions .= 'zip';
}
return $compressions;
}

Some files were not shown because too many files have changed in this diff Show More