/
var
/
www
/
html
/
restaurants
/
var
/
phpmyadmin
/
src
/
Query
/
Upload File
HOME
<?php declare(strict_types=1); namespace PhpMyAdmin\Query; use PhpMyAdmin\Config; use PhpMyAdmin\Dbal\ResultInterface; use PhpMyAdmin\Error\Error; use PhpMyAdmin\Url; use function __; use function array_slice; use function debug_backtrace; use function explode; use function htmlspecialchars; use function htmlspecialchars_decode; use function md5; use function sprintf; use function str_contains; use function strcasecmp; use function strnatcasecmp; use function strtolower; /** * Some helfull functions for common tasks related to SQL results */ class Utilities { /** * Get the list of system schemas * * @return string[] list of system schemas */ public static function getSystemSchemas(): array { $schemas = ['information_schema', 'performance_schema', 'mysql', 'sys']; $systemSchemas = []; foreach ($schemas as $schema) { if (! self::isSystemSchema($schema, true)) { continue; } $systemSchemas[] = $schema; } return $systemSchemas; } /** * Checks whether given schema is a system schema * * @param string $schemaName Name of schema (database) to test * @param bool $testForMysqlSchema Whether 'mysql' schema should be treated the same as IS and DD * * @psalm-pure */ public static function isSystemSchema( string $schemaName, bool $testForMysqlSchema = false, ): bool { $schemaName = strtolower($schemaName); $isMySqlSystemSchema = $schemaName === 'mysql' && $testForMysqlSchema; return $schemaName === 'information_schema' || $schemaName === 'performance_schema' || $isMySqlSystemSchema || $schemaName === 'sys'; } /** * Formats database error message in a friendly way. * This is needed because some errors messages cannot * be obtained by mysql_error(). * * @param int $errorNumber Error code * @param string $errorMessage Error message as returned by server * * @return string HML text with error details * @psalm-return non-empty-string */ public static function formatError(int $errorNumber, string $errorMessage): string { $errorMessage = htmlspecialchars($errorMessage); $error = '#' . $errorNumber; $separator = ' — '; if ($errorNumber === 2002) { $error .= ' - ' . $errorMessage; $error .= $separator; $error .= __('The server is not responding (or the local server\'s socket is not correctly configured).'); } elseif ($errorNumber === 2003) { $error .= ' - ' . $errorMessage; $error .= $separator . __('The server is not responding.'); } elseif ($errorNumber === 1698) { $error .= ' - ' . $errorMessage; $error .= $separator . '<a href="' . Url::getFromRoute('/logout') . '" class="disableAjax">'; $error .= __('Logout and try as another user.') . '</a>'; } elseif ($errorNumber === 1005) { if (str_contains($errorMessage, 'errno: 13')) { $error .= ' - ' . $errorMessage; $error .= $separator . __('Please check privileges of directory containing database.'); } else { /** * InnoDB constraints, see * https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html */ $error .= ' - ' . $errorMessage . ' (<a href="' . Url::getFromRoute('/server/engines/InnoDB/Status') . '">' . __('Details…') . '</a>)'; } } else { $error .= ' - ' . $errorMessage; } return $error; } /** * usort comparison callback * * @param mixed[] $a first argument to sort * @param mixed[] $b second argument to sort * @param string $sortBy Key to sort by * @param string $sortOrder The order (ASC/DESC) * * @return int a value representing whether $a should be before $b in the * sorted array or not */ public static function usortComparisonCallback(array $a, array $b, string $sortBy, string $sortOrder): int { /* No sorting when key is not present */ if (! isset($a[$sortBy], $b[$sortBy])) { return 0; } // produces f.e.: // return -1 * strnatcasecmp($a['SCHEMA_TABLES'], $b['SCHEMA_TABLES']) $compare = Config::getInstance()->settings['NaturalOrder'] ? strnatcasecmp( (string) $a[$sortBy], (string) $b[$sortBy], ) : strcasecmp((string) $a[$sortBy], (string) $b[$sortBy]); return ($sortOrder === 'ASC' ? 1 : -1) * $compare; } /** * Convert version string to integer. * * @param string $version MySQL server version */ public static function versionToInt(string $version): int { $match = explode('.', $version); return (int) sprintf('%d%02d%02d', $match[0], $match[1], (int) $match[2]); } /** * Stores query data into session data for debugging purposes * * @param string $query Query text * @param string|null $errorMessage Error message from getError() * @param ResultInterface|false $result Query result * @param int|float $time Time to execute query */ public static function debugLogQueryIntoSession( string $query, string|null $errorMessage, ResultInterface|false $result, int|float $time, ): void { $dbgInfo = []; if ($result === false && $errorMessage !== null) { // because Utilities::formatError is applied in DbiMysqli $dbgInfo['error'] = htmlspecialchars_decode($errorMessage); } $dbgInfo['query'] = $query; $dbgInfo['time'] = $time; // Get and slightly format backtrace, this is used // in the javascript console. // Strip call to debugLogQueryIntoSession $dbgInfo['trace'] = Error::processBacktrace( array_slice(debug_backtrace(), 1), ); $dbgInfo['hash'] = md5($query); $_SESSION['debug']['queries'][] = $dbgInfo; } }