diff --git a/ChangeLog b/ChangeLog index 6db2ee0550..326eb74a4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,7 +17,7 @@ phpMyAdmin - ChangeLog - issue #13269 Small refactoring in preparation to CSP - issue #13384 Database link broken in Databases Page - issue #13391 Configurable authentication logging using $cfg['AuthLog'] -- issue #13086 Add support for Goole Invisible Captcha +- issue #13086 Add support for Google Invisible Captcha - issue #13058 Improved error reporting for reCAPTCHA - issue #12899 Improved rendering of server variables table - issue #12948 Fixed javascript editor for TIME values @@ -34,6 +34,7 @@ phpMyAdmin - ChangeLog - issue #5827 Allow Designer to show tables from other databases - issue #13268 Replace Query-By-Example with multi-table query generator interface - issue #13576 Add privileges export to per database listing +- issue Consolidate functions into class files 4.7.5 (not yet released) - issue #13615 Avoid problems with browsing unknown query types diff --git a/js/config.js b/js/config.js index ea50f7a90c..f35f34c774 100644 --- a/js/config.js +++ b/js/config.js @@ -379,7 +379,7 @@ function getFieldValidators(field_id, onKeyUpOnly) * Displays errors for given form fields * * WARNING: created DOM elements must be identical with the ones made by - * display_input() in FormDisplay.tpl.php! + * PhpMyAdmin\Config\FormDisplayTemplate::displayInput()! * * @param {Object} error_list list of errors in the form {field id: error array} */ diff --git a/libraries/classes/Advisor.php b/libraries/classes/Advisor.php index 4c9ba78533..73e0070c86 100644 --- a/libraries/classes/Advisor.php +++ b/libraries/classes/Advisor.php @@ -10,6 +10,7 @@ namespace PhpMyAdmin; use Exception; use PhpMyAdmin\Core; +use PhpMyAdmin\SysInfo; use PhpMyAdmin\Url; use PhpMyAdmin\Util; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; @@ -209,8 +210,7 @@ class Advisor ); // Add total memory to variables as well - include_once 'libraries/sysinfo.lib.php'; - $sysinfo = PMA_getSysInfo(); + $sysinfo = SysInfo::get(); $memory = $sysinfo->memory(); $this->variables['system_memory'] = isset($memory['MemTotal']) ? $memory['MemTotal'] : 0; diff --git a/libraries/classes/Config/FormDisplay.php b/libraries/classes/Config/FormDisplay.php index fcc17b24d5..78b0bf92d5 100644 --- a/libraries/classes/Config/FormDisplay.php +++ b/libraries/classes/Config/FormDisplay.php @@ -17,13 +17,12 @@ namespace PhpMyAdmin\Config; use PhpMyAdmin\Config\ConfigFile; use PhpMyAdmin\Config\Descriptions; use PhpMyAdmin\Config\Form; +use PhpMyAdmin\Config\FormDisplayTemplate; use PhpMyAdmin\Config\Forms\User\UserFormList; use PhpMyAdmin\Config\Validator; use PhpMyAdmin\Sanitize; use PhpMyAdmin\Util; -require_once './libraries/config/FormDisplay.tpl.php'; - /** * Form management class, displays and processes forms * @@ -230,7 +229,7 @@ class FormDisplay /* @var $form Form */ $form_errors = isset($this->_errors[$form->name]) ? $this->_errors[$form->name] : null; - $htmlOutput .= PMA_displayFieldsetTop( + $htmlOutput .= FormDisplayTemplate::displayFieldsetTop( Descriptions::get("Form_{$form->name}"), Descriptions::get("Form_{$form->name}", 'desc'), $form_errors, @@ -258,10 +257,10 @@ class FormDisplay ); // register JS validators for this field if (isset($validators[$path])) { - PMA_addJsValidate($translated_path, $validators[$path], $js); + FormDisplayTemplate::addJsValidate($translated_path, $validators[$path], $js); } } - $htmlOutput .= PMA_displayFieldsetBottom($show_buttons); + $htmlOutput .= FormDisplayTemplate::displayFieldsetBottom($show_buttons); } return $htmlOutput; } @@ -293,14 +292,14 @@ class FormDisplay $js = array(); $js_default = array(); - $htmlOutput .= PMA_displayFormTop($form_action, 'post', $hidden_fields); + $htmlOutput .= FormDisplayTemplate::displayFormTop($form_action, 'post', $hidden_fields); if ($tabbed_form) { $tabs = array(); foreach ($this->_forms as $form) { $tabs[$form->name] = Descriptions::get("Form_$form->name"); } - $htmlOutput .= PMA_displayTabsTop($tabs); + $htmlOutput .= FormDisplayTemplate::displayTabsTop($tabs); } // validate only when we aren't displaying a "new server" form @@ -325,9 +324,9 @@ class FormDisplay ); if ($tabbed_form) { - $htmlOutput .= PMA_displayTabsBottom(); + $htmlOutput .= FormDisplayTemplate::displayTabsBottom(); } - $htmlOutput .= PMA_displayFormBottom(); + $htmlOutput .= FormDisplayTemplate::displayFormBottom(); // if not already done, send strings used for validation to JavaScript if (! $js_lang_sent) { @@ -342,7 +341,7 @@ class FormDisplay $js[] = "$.extend(defaultValues, {\n\t" . implode(",\n\t", $js_default) . '})'; - $htmlOutput .= PMA_displayJavascript($js); + $htmlOutput .= FormDisplayTemplate::displayJavascript($js); return $htmlOutput; } @@ -423,11 +422,11 @@ class FormDisplay // :group:end is changed to :group:end:{unique id} in Form class $htmlOutput = ''; if (mb_substr($field, 7, 4) != 'end:') { - $htmlOutput .= PMA_displayGroupHeader( + $htmlOutput .= FormDisplayTemplate::displayGroupHeader( mb_substr($field, 7) ); } else { - PMA_displayGroupFooter(); + FormDisplayTemplate::displayGroupFooter(); } return $htmlOutput; case 'NULL': @@ -479,7 +478,7 @@ class FormDisplay } $js_default[] = $js_line; - return PMA_displayInput( + return FormDisplayTemplate::displayInput( $translated_path, $name, $type, $value, $description, $value_is_default, $opts ); @@ -505,7 +504,7 @@ class FormDisplay } else { $name = Descriptions::get('Form_' . $system_path); } - $htmlOutput .= PMA_displayErrors($name, $error_list); + $htmlOutput .= FormDisplayTemplate::displayErrors($name, $error_list); } return $htmlOutput; diff --git a/libraries/classes/Config/FormDisplayTemplate.php b/libraries/classes/Config/FormDisplayTemplate.php new file mode 100644 index 0000000000..b1cc22710d --- /dev/null +++ b/libraries/classes/Config/FormDisplayTemplate.php @@ -0,0 +1,536 @@ +'; + $htmlOutput .= ''; + // 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; + $htmlOutput .= '' . "\n"; + } + $htmlOutput .= Url::getHiddenInputs('', '', 0, 'server') . "\n"; + $htmlOutput .= Url::getHiddenFields((array)$hidden_fields); + return $htmlOutput; + } + + /** + * Displays form tabs which are given by an array indexed by fieldset id + * ({@link self::displayFieldsetTop}), with values being tab titles. + * + * @param array $tabs tab names + * + * @return string + */ + public static function displayTabsTop($tabs) + { + $items = array(); + foreach ($tabs as $tab_id => $tab_name) { + $items[] = array( + 'content' => htmlspecialchars($tab_name), + 'url' => array( + 'href' => '#' . $tab_id, + ), + ); + } + + $htmlOutput = Template::get('list/unordered')->render( + array( + 'class' => 'tabs responsivetable', + 'items' => $items, + ) + ); + $htmlOutput .= '
'; + $htmlOutput .= '
'; + return $htmlOutput; + } + + /** + * Displays top part of a fieldset + * + * @param string $title title of fieldset + * @param string $description description shown on top of fieldset + * @param array $errors error messages to display + * @param array $attributes optional extra attributes of fieldset + * + * @return string + */ + public static function displayFieldsetTop($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) . '"'; + } + + $htmlOutput = '
'; + $htmlOutput .= '' . $title . ''; + if (!empty($description)) { + $htmlOutput .= '

' . $description . '

'; + } + // this must match with displayErrors() in scripts.js + if (is_array($errors) && count($errors) > 0) { + $htmlOutput .= '
'; + foreach ($errors as $error) { + $htmlOutput .= '
' . $error . '
'; + } + $htmlOutput .= '
'; + } + $htmlOutput .= ''; + return $htmlOutput; + } + + /** + * Displays input field + * + * $opts keys: + * o doc - (string) documentation link + * o errors - error array + * o setvalue - (string) shows button allowing to set predefined 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 pairs for '; + $htmlOutput .= ''; + if ($is_setup_script && isset($opts['userprefs_allow'])) { + $htmlOutput .= ''; + $htmlOutput .= ''; + $htmlOutput .= ''; + return $htmlOutput; + } + + /** + * Display group footer + * + * @return void + */ + public static function displayGroupFooter() + { + global $_FormDisplayGroup; + + $_FormDisplayGroup--; + } + + /** + * Displays bottom part of a fieldset + * + * @param bool $show_buttons whether show submit and reset button + * + * @return string + */ + public static function displayFieldsetBottom($show_buttons = true) + { + $colspan = 2; + if ($GLOBALS['PMA_Config']->get('is_setup')) { + $colspan++; + } + $htmlOutput = ''; + if ($show_buttons) { + $htmlOutput .= ''; + $htmlOutput .= ''; + $htmlOutput .= ''; + } + $htmlOutput .= '
'; + $htmlOutput .= ''; + + if (! empty($opts['doc'])) { + $htmlOutput .= ''; + $htmlOutput .= '' . $icons['help'] . ''; + $htmlOutput .= "\n"; + $htmlOutput .= ''; + } + + if ($option_is_disabled) { + $htmlOutput .= '' . __('Disabled') . ""; + } + + if (!empty($description)) { + $htmlOutput .= '' . $description . ''; + } + + $htmlOutput .= ''; + + switch ($type) { + case 'text': + $htmlOutput .= ''; + break; + case 'password': + $htmlOutput .= ''; + break; + case 'short_text': + // As seen in the reporting server (#15042) we sometimes receive + // an array here. No clue about its origin nor content, so let's avoid + // a notice on htmlspecialchars(). + if (! is_array($value)) { + $htmlOutput .= ''; + } + break; + case 'number_text': + $htmlOutput .= ''; + break; + case 'checkbox': + $htmlOutput .= ''; + break; + case 'select': + $htmlOutput .= ''; + break; + case 'list': + $htmlOutput .= ''; + break; + } + if (isset($opts['comment']) && $opts['comment']) { + $class = 'field-comment-mark'; + if (isset($opts['comment_warning']) && $opts['comment_warning']) { + $class .= ' field-comment-warning'; + } + $htmlOutput .= 'i'; + } + if ($is_setup_script + && isset($opts['userprefs_comment']) + && $opts['userprefs_comment'] + ) { + $htmlOutput .= '' + . $icons['tblops'] . ''; + } + if (isset($opts['setvalue']) && $opts['setvalue']) { + $htmlOutput .= '' . $icons['edit'] . ''; + } + if (isset($opts['show_restore_default']) && $opts['show_restore_default']) { + $htmlOutput .= '' . $icons['reload'] . ''; + } + // this must match with displayErrors() in scripts/config.js + if ($has_errors) { + $htmlOutput .= "\n
"; + foreach ($opts['errors'] as $error) { + $htmlOutput .= '
' . htmlspecialchars($error) . '
'; + } + $htmlOutput .= '
'; + } + $htmlOutput .= '
'; + $htmlOutput .= 'get('is_setup') + ? 3 + : 2; + $htmlOutput = '
'; + $htmlOutput .= $header_text; + $htmlOutput .= '
'; + $htmlOutput .= ''; + $htmlOutput .= ''; + $htmlOutput .= '
'; + $htmlOutput .= '
'; + return $htmlOutput; + } + + /** + * Displays simple bottom part of a fieldset (without submit buttons) + * + * @return string + */ + public static function displayFieldsetBottomSimple() + { + $htmlOutput = ''; + $htmlOutput .= ''; + return $htmlOutput; + } + + /** + * Closes form tabs + * + * @return string + */ + public static function displayTabsBottom() + { + $htmlOutput = "
\n"; + return $htmlOutput; + } + + /** + * Displays bottom part of the form + * + * @return string + */ + public static function displayFormBottom() + { + $htmlOutput = "\n"; + return $htmlOutput; + } + + /** + * Appends JS validation code to $js_array + * + * @param string $field_id ID of field to validate + * @param string|array $validators validators callback + * @param array &$js_array will be updated with javascript code + * + * @return void + */ + public static function addJsValidate($field_id, $validators, &$js_array) + { + foreach ((array)$validators as $validator) { + $validator = (array)$validator; + $v_name = array_shift($validator); + $v_name = "PMA_" . $v_name; + $v_args = array(); + foreach ($validator as $arg) { + $v_args[] = Sanitize::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 lines of javascript code + * + * @return string + */ + public static function displayJavascript($js_array) + { + if (empty($js_array)) { + return null; + } + + return Template::get('javascript/display')->render( + array('js_array' => $js_array,) + ); + } + + /** + * Displays error list + * + * @param string $name name of item with errors + * @param array $error_list list of errors to show + * + * @return string HTML for errors + */ + public static function displayErrors($name, $error_list) + { + $htmlOutput = '
'; + $htmlOutput .= '
' . htmlspecialchars($name) . '
'; + foreach ($error_list as $error) { + $htmlOutput .= '
' . htmlspecialchars($error) . '
'; + } + $htmlOutput .= '
'; + return $htmlOutput; + } +} diff --git a/libraries/classes/Config/ServerConfigChecks.php b/libraries/classes/Config/ServerConfigChecks.php index 77b6409e91..dbf4e2332b 100644 --- a/libraries/classes/Config/ServerConfigChecks.php +++ b/libraries/classes/Config/ServerConfigChecks.php @@ -11,14 +11,15 @@ use PhpMyAdmin\Config\ConfigFile; use PhpMyAdmin\Config\Descriptions; use PhpMyAdmin\Core; use PhpMyAdmin\Sanitize; +use PhpMyAdmin\Setup\Index as SetupIndex; use PhpMyAdmin\Url; use PhpMyAdmin\Util; /** * Performs various compatibility, security and consistency checks on current config * - * Outputs results to message list, must be called between PMA_messagesBegin() - * and PMA_messagesEnd() + * Outputs results to message list, must be called between SetupIndex::messagesBegin() + * and SetupIndex::messagesEnd() * * @package PhpMyAdmin */ @@ -81,7 +82,7 @@ class ServerConfigChecks '[a@' . Url::getCommon(array('page' => 'form', 'formset' => 'Features')) . '#tab_Security]', '[/a]' ); - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', 'AllowArbitraryServer', Descriptions::get('AllowArbitraryServer'), @@ -102,7 +103,7 @@ class ServerConfigChecks // should not be world-accessible // if ($this->cfg->getValue('SaveDir') != '') { - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', 'SaveDir', Descriptions::get('SaveDir'), @@ -115,7 +116,7 @@ class ServerConfigChecks // should not be world-accessible // if ($this->cfg->getValue('TempDir') != '') { - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', 'TempDir', Descriptions::get('TempDir'), @@ -160,7 +161,7 @@ class ServerConfigChecks // if (!$this->cfg->getValue("Servers/$i/ssl")) { $title = Descriptions::get('Servers/1/ssl') . " ($serverName)"; - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', "Servers/$i/ssl", $title, @@ -193,7 +194,7 @@ class ServerConfigChecks ) { $title = Descriptions::get('Servers/1/auth_type') . " ($serverName)"; - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', "Servers/$i/auth_type", $title, @@ -222,7 +223,7 @@ class ServerConfigChecks ) { $title = Descriptions::get('Servers/1/AllowNoPassword') . " ($serverName)"; - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', "Servers/$i/AllowNoPassword", $title, @@ -293,7 +294,7 @@ class ServerConfigChecks // requires zip_open in import // if ($this->cfg->getValue('ZipDump') && !$this->functionExists('zip_open')) { - PMA_messagesSet( + SetupIndex::messagesSet( 'error', 'ZipDump_import', Descriptions::get('ZipDump'), @@ -314,7 +315,7 @@ class ServerConfigChecks // requires gzcompress in export // if ($this->cfg->getValue('ZipDump') && !$this->functionExists('gzcompress')) { - PMA_messagesSet( + SetupIndex::messagesSet( 'error', 'ZipDump_export', Descriptions::get('ZipDump'), @@ -351,7 +352,7 @@ class ServerConfigChecks if ($cookieAuthUsed) { if ($blowfishSecretSet) { // 'cookie' auth used, blowfish_secret was generated - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', 'blowfish_secret_created', Descriptions::get('blowfish_secret'), @@ -384,7 +385,7 @@ class ServerConfigChecks ); } if (!empty($blowfishWarnings)) { - PMA_messagesSet( + SetupIndex::messagesSet( 'error', 'blowfish_warnings' . count($blowfishWarnings), Descriptions::get('blowfish_secret'), @@ -408,7 +409,7 @@ class ServerConfigChecks $loginCookieValidity = $this->cfg->getValue('LoginCookieValidity'); if ($loginCookieValidity > ini_get('session.gc_maxlifetime') ) { - PMA_messagesSet( + SetupIndex::messagesSet( 'error', 'LoginCookieValidity', Descriptions::get('LoginCookieValidity'), @@ -432,7 +433,7 @@ class ServerConfigChecks // should be at most 1800 (30 min) // if ($loginCookieValidity > 1800) { - PMA_messagesSet( + SetupIndex::messagesSet( 'notice', 'LoginCookieValidity', Descriptions::get('LoginCookieValidity'), @@ -456,7 +457,7 @@ class ServerConfigChecks if (($this->cfg->getValue('LoginCookieStore') != 0) && ($loginCookieValidity > $this->cfg->getValue('LoginCookieStore')) ) { - PMA_messagesSet( + SetupIndex::messagesSet( 'error', 'LoginCookieValidity', Descriptions::get('LoginCookieValidity'), @@ -495,7 +496,7 @@ class ServerConfigChecks $functions .= $this->functionExists('bzcompress') ? '' : ($functions ? ', ' : '') . 'bzcompress'; - PMA_messagesSet( + SetupIndex::messagesSet( 'error', 'BZipDump', Descriptions::get('BZipDump'), @@ -528,7 +529,7 @@ class ServerConfigChecks if ($this->cfg->getValue('GZipDump') && (!$this->functionExists('gzopen') || !$this->functionExists('gzencode')) ) { - PMA_messagesSet( + SetupIndex::messagesSet( 'error', 'GZipDump', Descriptions::get('GZipDump'), diff --git a/libraries/classes/Display/Results.php b/libraries/classes/Display/Results.php index 7102046506..b7c4d49da3 100644 --- a/libraries/classes/Display/Results.php +++ b/libraries/classes/Display/Results.php @@ -3113,7 +3113,7 @@ class Results } // Check for the predefined fields need to show as link in schemas - include_once 'libraries/special_schema_links.lib.php'; + include_once 'libraries/special_schema_links.inc.php'; if (isset($GLOBALS['special_schema_links']) && (! empty($GLOBALS['special_schema_links'][$dbLower][$tblLower][$nameLower])) diff --git a/libraries/classes/Export.php b/libraries/classes/Export.php index 98102076e1..c8c0466d9e 100644 --- a/libraries/classes/Export.php +++ b/libraries/classes/Export.php @@ -7,8 +7,10 @@ */ namespace PhpMyAdmin; +use PhpMyAdmin\Core; use PhpMyAdmin\Encoding; use PhpMyAdmin\Message; +use PhpMyAdmin\Plugins; use PhpMyAdmin\Plugins\ExportPlugin; use PhpMyAdmin\Sanitize; use PhpMyAdmin\Table; @@ -1046,4 +1048,41 @@ class Export return ''; } } + + /** + * get all the export options and verify + * call and include the appropriate Schema Class depending on $export_type + * + * @param string $export_type format of the export + * + * @return void + */ + public static function processExportSchema($export_type) + { + /** + * default is PDF, otherwise validate it's only letters a-z + */ + if (! isset($export_type) || ! preg_match('/^[a-zA-Z]+$/', $export_type)) { + $export_type = 'pdf'; + } + + // sanitize this parameter which will be used below in a file inclusion + $export_type = Core::securePath($export_type); + + // get the specific plugin + /* @var $export_plugin SchemaPlugin */ + $export_plugin = Plugins::getPlugin( + "schema", + $export_type, + 'libraries/classes/Plugins/Schema/' + ); + + // Check schema export type + if (! isset($export_plugin)) { + Core::fatalError(__('Bad type!')); + } + + $GLOBALS['dbi']->selectDb($GLOBALS['db']); + $export_plugin->exportSchema($GLOBALS['db']); + } } diff --git a/libraries/classes/Sanitize.php b/libraries/classes/Sanitize.php index 6457d4fbd6..7dd3d7a69c 100644 --- a/libraries/classes/Sanitize.php +++ b/libraries/classes/Sanitize.php @@ -48,7 +48,7 @@ class Sanitize './tbl_select.php?', './tbl_change.php?', './sql.php?', - # Hardcoded options in libraries/special_schema_links.lib.php + # Hardcoded options in libraries/special_schema_links.inc.php './db_events.php?', './db_routines.php?', './server_privileges.php?', diff --git a/libraries/classes/Server/Status/Monitor.php b/libraries/classes/Server/Status/Monitor.php index 07dbdf6f27..5e5232d90d 100644 --- a/libraries/classes/Server/Status/Monitor.php +++ b/libraries/classes/Server/Status/Monitor.php @@ -11,10 +11,9 @@ namespace PhpMyAdmin\Server\Status; use PhpMyAdmin\Sanitize; use PhpMyAdmin\Server\Status\Data; +use PhpMyAdmin\SysInfo; use PhpMyAdmin\Util; -require_once 'libraries/sysinfo.lib.php'; - class Monitor { /** @@ -349,7 +348,7 @@ class Monitor $input = ''; $form = '
'; $form .= sprintf($input, 'server_time', microtime(true) * 1000); - $form .= sprintf($input, 'server_os', PMA_getSysInfoOs()); + $form .= sprintf($input, 'server_os', SysInfo::getOs()); $form .= sprintf($input, 'is_superuser', $GLOBALS['dbi']->isSuperuser()); $form .= sprintf($input, 'server_db_isLocal', $serverStatusData->db_isLocal); $form .= '
'; @@ -522,14 +521,13 @@ class Monitor case 'cpu': if (!$sysinfo) { - include_once 'libraries/sysinfo.lib.php'; - $sysinfo = PMA_getSysInfo(); + $sysinfo = SysInfo::get(); } if (!$cpuload) { $cpuload = $sysinfo->loadavg(); } - if (PMA_getSysInfoOs() == 'Linux') { + if (SysInfo::getOs() == 'Linux') { $ret['idle'] = $cpuload['idle']; $ret['busy'] = $cpuload['busy']; } else { @@ -540,8 +538,7 @@ class Monitor case 'memory': if (!$sysinfo) { - include_once 'libraries/sysinfo.lib.php'; - $sysinfo = PMA_getSysInfo(); + $sysinfo = SysInfo::get(); } if (!$memory) { $memory = $sysinfo->memory(); diff --git a/libraries/classes/SysInfo.php b/libraries/classes/SysInfo.php index 70bb0582a0..f33d9e128b 100644 --- a/libraries/classes/SysInfo.php +++ b/libraries/classes/SysInfo.php @@ -1,48 +1,64 @@ 0); + // look for common UNIX-like systems + $unix_like = array('FreeBSD', 'DragonFly'); + if (in_array($php_os, $unix_like)) { + $php_os = 'Linux'; + } + + return ucfirst($php_os); } /** - * Gets information about memory usage + * Gets sysinfo class mathing current OS * - * @return array with memory usage data + * @return PhpMyAdmin\SysInfoBase|mixed sysinfo class */ - public function memory() + public static function get() { - return array(); - } + $php_os = self::getOs(); + $supported = array('Linux', 'WINNT', 'SunOS'); - /** - * Checks whether class is supported in this environment - * - * @return true on success - */ - public function supported() - { - return true; + if (in_array($php_os, $supported)) { + $class_name = 'PhpMyAdmin\SysInfo' . $php_os; + /** @var PhpMyAdmin\SysInfoBase $ret */ + $ret = new $class_name(); + if ($ret->supported()) { + return $ret; + } + } + + return new SysInfoBase(); } } diff --git a/libraries/classes/SysInfoBase.php b/libraries/classes/SysInfoBase.php new file mode 100644 index 0000000000..3052b1e40d --- /dev/null +++ b/libraries/classes/SysInfoBase.php @@ -0,0 +1,48 @@ + 0); + } + + /** + * Gets information about memory usage + * + * @return array with memory usage data + */ + public function memory() + { + return array(); + } + + /** + * Checks whether class is supported in this environment + * + * @return true on success + */ + public function supported() + { + return true; + } +} diff --git a/libraries/classes/SysInfoLinux.php b/libraries/classes/SysInfoLinux.php index c29c2bfd20..3fc4f61274 100644 --- a/libraries/classes/SysInfoLinux.php +++ b/libraries/classes/SysInfoLinux.php @@ -8,13 +8,14 @@ namespace PhpMyAdmin; use PhpMyAdmin\SysInfo; +use PhpMyAdmin\SysInfoBase; /** * Linux based SysInfo class * * @package PhpMyAdmin */ -class SysInfoLinux extends SysInfo +class SysInfoLinux extends SysInfoBase { public $os = 'Linux'; @@ -59,7 +60,7 @@ class SysInfoLinux extends SysInfo function memory() { preg_match_all( - MEMORY_REGEXP, + SysInfo::MEMORY_REGEXP, file_get_contents('/proc/meminfo'), $matches ); diff --git a/libraries/classes/SysInfoSunOS.php b/libraries/classes/SysInfoSunOS.php index f24cd71307..99390e8510 100644 --- a/libraries/classes/SysInfoSunOS.php +++ b/libraries/classes/SysInfoSunOS.php @@ -7,14 +7,14 @@ */ namespace PhpMyAdmin; -use PhpMyAdmin\SysInfo; +use PhpMyAdmin\SysInfoBase; /** * SunOS based SysInfo class * * @package PhpMyAdmin */ -class SysInfoSunOS extends SysInfo +class SysInfoSunOS extends SysInfoBase { public $os = 'SunOS'; diff --git a/libraries/classes/SysInfoWINNT.php b/libraries/classes/SysInfoWINNT.php index ae23d41ace..7dfa2aa44c 100644 --- a/libraries/classes/SysInfoWINNT.php +++ b/libraries/classes/SysInfoWINNT.php @@ -8,14 +8,14 @@ namespace PhpMyAdmin; use COM; -use PhpMyAdmin\SysInfo; +use PhpMyAdmin\SysInfoBase; /** * Windows NT based SysInfo class * * @package PhpMyAdmin */ -class SysInfoWINNT extends SysInfo +class SysInfoWINNT extends SysInfoBase { private $_wmi; public $os = 'WINNT'; diff --git a/libraries/classes/UserPassword.php b/libraries/classes/UserPassword.php new file mode 100644 index 0000000000..3ae5161562 --- /dev/null +++ b/libraries/classes/UserPassword.php @@ -0,0 +1,251 @@ +isAjax()) { + /** + * If in an Ajax request, we don't need to show the rest of the page + */ + if ($change_password_message['error']) { + $response->addJSON('message', $change_password_message['msg']); + $response->setRequestStatus(false); + } else { + $sql_query = Util::getMessage( + $change_password_message['msg'], + $sql_query, + 'success' + ); + $response->addJSON('message', $sql_query); + } + exit; + } + } + + /** + * Generate the message + * + * @return array error value and message + */ + public static function setChangePasswordMsg() + { + $error = false; + $message = Message::success(__('The profile has been updated.')); + + if (($_REQUEST['nopass'] != '1')) { + if (strlen($_REQUEST['pma_pw']) === 0 || strlen($_REQUEST['pma_pw2']) === 0) { + $message = Message::error(__('The password is empty!')); + $error = true; + } elseif ($_REQUEST['pma_pw'] !== $_REQUEST['pma_pw2']) { + $message = Message::error( + __('The passwords aren\'t the same!') + ); + $error = true; + } elseif (strlen($_REQUEST['pma_pw']) > 256) { + $message = Message::error(__('Password is too long!')); + $error = true; + } + } + return array('error' => $error, 'msg' => $message); + } + + /** + * Change the password + * + * @param string $password New password + * @param string $message Message + * @param array $change_password_message Message to show + * + * @return void + */ + public static function changePassword($password, $message, $change_password_message) + { + global $auth_plugin; + + $hashing_function = self::changePassHashingFunction(); + + list($username, $hostname) = $GLOBALS['dbi']->getCurrentUserAndHost(); + + $serverType = Util::getServerType(); + $serverVersion = $GLOBALS['dbi']->getVersion(); + + if (isset($_REQUEST['authentication_plugin']) + && ! empty($_REQUEST['authentication_plugin']) + ) { + $orig_auth_plugin = $_REQUEST['authentication_plugin']; + } else { + $orig_auth_plugin = Privileges::getCurrentAuthenticationPlugin( + 'change', $username, $hostname + ); + } + + $sql_query = 'SET password = ' + . (($password == '') ? '\'\'' : $hashing_function . '(\'***\')'); + + if ($serverType == 'MySQL' + && $serverVersion >= 50706 + ) { + $sql_query = 'ALTER USER \'' . $username . '\'@\'' . $hostname + . '\' IDENTIFIED WITH ' . $orig_auth_plugin . ' BY ' + . (($password == '') ? '\'\'' : '\'***\''); + } else if (($serverType == 'MySQL' + && $serverVersion >= 50507) + || ($serverType == 'MariaDB' + && $serverVersion >= 50200) + ) { + // For MySQL versions 5.5.7+ and MariaDB versions 5.2+, + // explicitly set value of `old_passwords` so that + // it does not give an error while using + // the PASSWORD() function + if ($orig_auth_plugin == 'sha256_password') { + $value = 2; + } else { + $value = 0; + } + $GLOBALS['dbi']->tryQuery('SET `old_passwords` = ' . $value . ';'); + } + + self::changePassUrlParamsAndSubmitQuery( + $username, $hostname, $password, + $sql_query, $hashing_function, $orig_auth_plugin + ); + + $auth_plugin->handlePasswordChange($password); + self::getChangePassMessage($change_password_message, $sql_query); + self::changePassDisplayPage($message, $sql_query); + } + + /** + * Generate the hashing function + * + * @return string $hashing_function + */ + public static function changePassHashingFunction() + { + if (Core::isValid( + $_REQUEST['authentication_plugin'], 'identical', 'mysql_old_password' + )) { + $hashing_function = 'OLD_PASSWORD'; + } else { + $hashing_function = 'PASSWORD'; + } + return $hashing_function; + } + + /** + * Changes password for a user + * + * @param string $username Username + * @param string $hostname Hostname + * @param string $password Password + * @param string $sql_query SQL query + * @param string $hashing_function Hashing function + * @param string $orig_auth_plugin Original Authentication Plugin + * + * @return void + */ + public static function changePassUrlParamsAndSubmitQuery( + $username, $hostname, $password, $sql_query, $hashing_function, $orig_auth_plugin + ) { + $err_url = 'user_password.php' . Url::getCommon(); + + $serverType = Util::getServerType(); + $serverVersion = $GLOBALS['dbi']->getVersion(); + + if ($serverType == 'MySQL' && $serverVersion >= 50706) { + $local_query = 'ALTER USER \'' . $username . '\'@\'' . $hostname . '\'' + . ' IDENTIFIED with ' . $orig_auth_plugin . ' BY ' + . (($password == '') + ? '\'\'' + : '\'' . $GLOBALS['dbi']->escapeString($password) . '\''); + } else if ($serverType == 'MariaDB' + && $serverVersion >= 50200 + && $serverVersion < 100100 + && $orig_auth_plugin !== '' + ) { + if ($orig_auth_plugin == 'mysql_native_password') { + // Set the hashing method used by PASSWORD() + // to be 'mysql_native_password' type + $GLOBALS['dbi']->tryQuery('SET old_passwords = 0;'); + } else if ($orig_auth_plugin == 'sha256_password') { + // Set the hashing method used by PASSWORD() + // to be 'sha256_password' type + $GLOBALS['dbi']->tryQuery('SET `old_passwords` = 2;'); + } + + $hashedPassword = Privileges::getHashedPassword($_POST['pma_pw']); + + $local_query = "UPDATE `mysql`.`user` SET" + . " `authentication_string` = '" . $hashedPassword + . "', `Password` = '', " + . " `plugin` = '" . $orig_auth_plugin . "'" + . " WHERE `User` = '" . $username . "' AND Host = '" + . $hostname . "';"; + } else { + $local_query = 'SET password = ' . (($password == '') + ? '\'\'' + : $hashing_function . '(\'' + . $GLOBALS['dbi']->escapeString($password) . '\')'); + } + if (! @$GLOBALS['dbi']->tryQuery($local_query)) { + Util::mysqlDie( + $GLOBALS['dbi']->getError(), + $sql_query, + false, + $err_url + ); + } + + // Flush privileges after successful password change + $GLOBALS['dbi']->tryQuery("FLUSH PRIVILEGES;"); + } + + /** + * Display the page + * + * @param string $message Message + * @param string $sql_query SQL query + * + * @return void + */ + public static function changePassDisplayPage($message, $sql_query) + { + echo '

' , __('Change password') , '

' , "\n\n"; + echo Util::getMessage( + $message, $sql_query, 'success' + ); + echo '' , "\n" + , '' , __('Back') , ''; + exit; + } +} diff --git a/libraries/config/FormDisplay.tpl.php b/libraries/config/FormDisplay.tpl.php deleted file mode 100644 index cb03f27d29..0000000000 --- a/libraries/config/FormDisplay.tpl.php +++ /dev/null @@ -1,527 +0,0 @@ -'; - $htmlOutput .= ''; - // 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; - $htmlOutput .= '' . "\n"; - } - $htmlOutput .= Url::getHiddenInputs('', '', 0, 'server') . "\n"; - $htmlOutput .= Url::getHiddenFields((array)$hidden_fields); - return $htmlOutput; -} - -/** - * Displays form tabs which are given by an array indexed by fieldset id - * ({@link PMA_displayFieldsetTop}), with values being tab titles. - * - * @param array $tabs tab names - * - * @return string - */ -function PMA_displayTabsTop($tabs) -{ - $items = array(); - foreach ($tabs as $tab_id => $tab_name) { - $items[] = array( - 'content' => htmlspecialchars($tab_name), - 'url' => array( - 'href' => '#' . $tab_id, - ), - ); - } - - $htmlOutput = Template::get('list/unordered')->render( - array( - 'class' => 'tabs responsivetable', - 'items' => $items, - ) - ); - $htmlOutput .= '
'; - $htmlOutput .= '
'; - return $htmlOutput; -} - - -/** - * Displays top part of a fieldset - * - * @param string $title title of fieldset - * @param string $description description shown on top of fieldset - * @param array $errors error messages to display - * @param array $attributes optional extra attributes of fieldset - * - * @return string - */ -function PMA_displayFieldsetTop($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) . '"'; - } - - $htmlOutput = '
'; - $htmlOutput .= '' . $title . ''; - if (!empty($description)) { - $htmlOutput .= '

' . $description . '

'; - } - // this must match with displayErrors() in scripts.js - if (is_array($errors) && count($errors) > 0) { - $htmlOutput .= '
'; - foreach ($errors as $error) { - $htmlOutput .= '
' . $error . '
'; - } - $htmlOutput .= '
'; - } - $htmlOutput .= ''; - return $htmlOutput; -} - -/** - * Displays input field - * - * $opts keys: - * o doc - (string) documentation link - * o errors - error array - * o setvalue - (string) shows button allowing to set predefined 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 pairs for '; - $htmlOutput .= ''; - if ($is_setup_script && isset($opts['userprefs_allow'])) { - $htmlOutput .= ''; - $htmlOutput .= ''; - $htmlOutput .= ''; - return $htmlOutput; -} - -/** - * Display group footer - * - * @return void - */ -function PMA_displayGroupFooter() -{ - global $_FormDisplayGroup; - - $_FormDisplayGroup--; -} - -/** - * Displays bottom part of a fieldset - * - * @param bool $show_buttons whether show submit and reset button - * - * @return string - */ -function PMA_displayFieldsetBottom($show_buttons = true) -{ - $colspan = 2; - if ($GLOBALS['PMA_Config']->get('is_setup')) { - $colspan++; - } - $htmlOutput = ''; - if ($show_buttons) { - $htmlOutput .= ''; - $htmlOutput .= ''; - $htmlOutput .= ''; - } - $htmlOutput .= '
'; - $htmlOutput .= ''; - - if (! empty($opts['doc'])) { - $htmlOutput .= ''; - $htmlOutput .= '' . $icons['help'] . ''; - $htmlOutput .= "\n"; - $htmlOutput .= ''; - } - - if ($option_is_disabled) { - $htmlOutput .= '' . __('Disabled') . ""; - } - - if (!empty($description)) { - $htmlOutput .= '' . $description . ''; - } - - $htmlOutput .= ''; - - switch ($type) { - case 'text': - $htmlOutput .= ''; - break; - case 'password': - $htmlOutput .= ''; - break; - case 'short_text': - // As seen in the reporting server (#15042) we sometimes receive - // an array here. No clue about its origin nor content, so let's avoid - // a notice on htmlspecialchars(). - if (! is_array($value)) { - $htmlOutput .= ''; - } - break; - case 'number_text': - $htmlOutput .= ''; - break; - case 'checkbox': - $htmlOutput .= ''; - break; - case 'select': - $htmlOutput .= ''; - break; - case 'list': - $htmlOutput .= ''; - break; - } - if (isset($opts['comment']) && $opts['comment']) { - $class = 'field-comment-mark'; - if (isset($opts['comment_warning']) && $opts['comment_warning']) { - $class .= ' field-comment-warning'; - } - $htmlOutput .= 'i'; - } - if ($is_setup_script - && isset($opts['userprefs_comment']) - && $opts['userprefs_comment'] - ) { - $htmlOutput .= '' - . $icons['tblops'] . ''; - } - if (isset($opts['setvalue']) && $opts['setvalue']) { - $htmlOutput .= '' . $icons['edit'] . ''; - } - if (isset($opts['show_restore_default']) && $opts['show_restore_default']) { - $htmlOutput .= '' . $icons['reload'] . ''; - } - // this must match with displayErrors() in scripts/config.js - if ($has_errors) { - $htmlOutput .= "\n
"; - foreach ($opts['errors'] as $error) { - $htmlOutput .= '
' . htmlspecialchars($error) . '
'; - } - $htmlOutput .= '
'; - } - $htmlOutput .= '
'; - $htmlOutput .= 'get('is_setup') - ? 3 - : 2; - $htmlOutput = '
'; - $htmlOutput .= $header_text; - $htmlOutput .= '
'; - $htmlOutput .= ''; - $htmlOutput .= ''; - $htmlOutput .= '
'; - $htmlOutput .= '
'; - return $htmlOutput; -} - -/** - * Displays simple bottom part of a fieldset (without submit buttons) - * - * @return string - */ -function PMA_displayFieldsetBottomSimple() -{ - $htmlOutput = ''; - $htmlOutput .= ''; - return $htmlOutput; -} - -/** - * Closes form tabs - * - * @return string - */ -function PMA_displayTabsBottom() -{ - $htmlOutput = "
\n"; - return $htmlOutput; -} - -/** - * Displays bottom part of the form - * - * @return string - */ -function PMA_displayFormBottom() -{ - $htmlOutput = "\n"; - return $htmlOutput; -} - -/** - * Appends JS validation code to $js_array - * - * @param string $field_id ID of field to validate - * @param string|array $validators validators callback - * @param array &$js_array will be updated with javascript code - * - * @return void - */ -function PMA_addJsValidate($field_id, $validators, &$js_array) -{ - foreach ((array)$validators as $validator) { - $validator = (array)$validator; - $v_name = array_shift($validator); - $v_name = "PMA_" . $v_name; - $v_args = array(); - foreach ($validator as $arg) { - $v_args[] = Sanitize::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 lines of javascript code - * - * @return string - */ -function PMA_displayJavascript($js_array) -{ - if (empty($js_array)) { - return null; - } - - return Template::get('javascript/display')->render( - array('js_array' => $js_array,) - ); -} - -/** - * Displays error list - * - * @param string $name name of item with errors - * @param array $error_list list of errors to show - * - * @return string HTML for errors - */ -function PMA_displayErrors($name, $error_list) -{ - $htmlOutput = '
'; - $htmlOutput .= '
' . htmlspecialchars($name) . '
'; - foreach ($error_list as $error) { - $htmlOutput .= '
' . htmlspecialchars($error) . '
'; - } - $htmlOutput .= '
'; - return $htmlOutput; -} diff --git a/libraries/special_schema_links.lib.php b/libraries/special_schema_links.inc.php similarity index 100% rename from libraries/special_schema_links.lib.php rename to libraries/special_schema_links.inc.php diff --git a/libraries/sysinfo.lib.php b/libraries/sysinfo.lib.php deleted file mode 100644 index d53edc1868..0000000000 --- a/libraries/sysinfo.lib.php +++ /dev/null @@ -1,63 +0,0 @@ -supported()) { - return $ret; - } - } - - return new SysInfo(); -} diff --git a/schema_export.php b/schema_export.php index fd5d2d13ce..6a007512e6 100644 --- a/schema_export.php +++ b/schema_export.php @@ -6,10 +6,9 @@ * @package PhpMyAdmin */ -use PhpMyAdmin\Core; -use PhpMyAdmin\Plugins; -use PhpMyAdmin\Plugins\SchemaPlugin; +use PhpMyAdmin\Export; use PhpMyAdmin\Relation; +use PhpMyAdmin\Util; /** * Gets some core libraries @@ -23,48 +22,11 @@ require_once 'libraries/common.inc.php'; $cfgRelation = Relation::getRelationsParam(); if (! isset($_REQUEST['export_type'])) { - PhpMyAdmin\Util::checkParameters(array('export_type')); + Util::checkParameters(array('export_type')); } /** * Include the appropriate Schema Class depending on $export_type * default is PDF */ -PMA_processExportSchema($_REQUEST['export_type']); - -/** - * get all the export options and verify - * call and include the appropriate Schema Class depending on $export_type - * - * @param string $export_type format of the export - * - * @return void - */ -function PMA_processExportSchema($export_type) -{ - /** - * default is PDF, otherwise validate it's only letters a-z - */ - if (! isset($export_type) || ! preg_match('/^[a-zA-Z]+$/', $export_type)) { - $export_type = 'pdf'; - } - - // sanitize this parameter which will be used below in a file inclusion - $export_type = Core::securePath($export_type); - - // get the specific plugin - /* @var $export_plugin SchemaPlugin */ - $export_plugin = Plugins::getPlugin( - "schema", - $export_type, - 'libraries/classes/Plugins/Schema/' - ); - - // Check schema export type - if (! isset($export_plugin)) { - Core::fatalError(__('Bad type!')); - } - - $GLOBALS['dbi']->selectDb($GLOBALS['db']); - $export_plugin->exportSchema($GLOBALS['db']); -} +Export::processExportSchema($_REQUEST['export_type']); diff --git a/setup/frames/config.inc.php b/setup/frames/config.inc.php index ba24104750..a543bc3124 100644 --- a/setup/frames/config.inc.php +++ b/setup/frames/config.inc.php @@ -6,25 +6,20 @@ * @package PhpMyAdmin-Setup */ -use PhpMyAdmin\Setup\ConfigGenerator; +use PhpMyAdmin\Config\FormDisplayTemplate; use PhpMyAdmin\Core; +use PhpMyAdmin\Setup\ConfigGenerator; if (!defined('PHPMYADMIN')) { exit; } -/** - * Core libraries. - */ -require_once './libraries/config/FormDisplay.tpl.php'; -require_once './setup/lib/index.lib.php'; - echo '

' , __('Configuration file') , '

'; -echo PMA_displayFormTop('config.php'); +echo FormDisplayTemplate::displayFormTop('config.php'); echo ''; -echo PMA_displayFieldsetTop('config.inc.php', '', null, array('class' => 'simple')); +echo FormDisplayTemplate::displayFieldsetTop('config.inc.php', '', null, array('class' => 'simple')); echo ''; echo ''; echo '