").append(form_data.message);
$("#fieldsForm").replaceWith($temp_div.find("#fieldsForm"));
$("#addColumns").replaceWith($temp_div.find("#addColumns"));
$('#move_columns_dialog ul').replaceWith($temp_div.find("#move_columns_dialog ul"));
diff --git a/js/tbl_zoom_plot_jqplot.js b/js/tbl_zoom_plot_jqplot.js
index 006e6cd15e..4c3b0706fa 100644
--- a/js/tbl_zoom_plot_jqplot.js
+++ b/js/tbl_zoom_plot_jqplot.js
@@ -12,10 +12,7 @@
** Display Help/Info
**/
function displayHelp() {
- var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'], 10000);
- msgbox.click(function() {
- PMA_ajaxRemoveMessage(msgbox);
- });
+ PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'], 10000);
}
/**
@@ -139,7 +136,7 @@ $(document).ready(function() {
'table' : window.parent.table,
'field' : $('#tableid_0').val(),
'it' : 0,
- 'token' : window.parent.token,
+ 'token' : window.parent.token
},function(data) {
$('#tableFieldsId tr:eq(1) td:eq(0)').html(data.field_type);
$('#tableFieldsId tr:eq(1) td:eq(1)').html(data.field_collation);
@@ -163,7 +160,7 @@ $(document).ready(function() {
'table' : window.parent.table,
'field' : $('#tableid_1').val(),
'it' : 1,
- 'token' : window.parent.token,
+ 'token' : window.parent.token
},function(data) {
$('#tableFieldsId tr:eq(3) td:eq(0)').html(data.field_type);
$('#tableFieldsId tr:eq(3) td:eq(1)').html(data.field_collation);
@@ -186,7 +183,7 @@ $(document).ready(function() {
'table' : window.parent.table,
'field' : $('#tableid_2').val(),
'it' : 2,
- 'token' : window.parent.token,
+ 'token' : window.parent.token
},function(data) {
$('#tableFieldsId tr:eq(6) td:eq(0)').html(data.field_type);
$('#tableFieldsId tr:eq(6) td:eq(1)').html(data.field_collation);
@@ -207,7 +204,7 @@ $(document).ready(function() {
'table' : window.parent.table,
'field' : $('#tableid_3').val(),
'it' : 3,
- 'token' : window.parent.token,
+ 'token' : window.parent.token
},function(data) {
$('#tableFieldsId tr:eq(8) td:eq(0)').html(data.field_type);
$('#tableFieldsId tr:eq(8) td:eq(1)').html(data.field_collation);
@@ -264,14 +261,14 @@ $(document).ready(function() {
//Find changed values by comparing form values with selectedRow Object
var newValues = new Object();//Stores the values changed from original
var sqlTypes = new Object();
- var it = 4;
+ var it = 0;
var xChange = false;
var yChange = false;
for (key in selectedRow) {
var oldVal = selectedRow[key];
- var newVal = ($('#fields_null_id_' + it).attr('checked')) ? null : $('#fieldID_' + it).val();
+ var newVal = ($('#edit_fields_null_id_' + it).attr('checked')) ? null : $('#edit_fieldID_' + it).val();
if (newVal instanceof Array) { // when the column is of type SET
- newVal = $('#fieldID_' + it).map(function(){
+ newVal = $('#edit_fieldID_' + it).map(function(){
return $(this).val();
}).get().join(",");
}
@@ -286,7 +283,7 @@ $(document).ready(function() {
searchedData[searchedDataKey][yLabel] = newVal;
}
}
- var $input = $('#fieldID_' + it);
+ var $input = $('#edit_fieldID_' + it);
if ($input.hasClass('bit')) {
sqlTypes[key] = 'bit';
}
@@ -534,6 +531,7 @@ $(document).ready(function() {
// resizing, it's ok
// under IE 9, everything is fine
currentChart = $.jqplot('querychart', series, options);
+ currentChart.resetZoom();
$('button.button-reset').click(function(event) {
event.preventDefault();
@@ -551,7 +549,7 @@ $(document).ready(function() {
$('div#querychart').bind('jqplotDataClick',
function(event, seriesIndex, pointIndex, data) {
searchedDataKey = data[4]; // key from searchedData (global)
- var field_id = 4;
+ var field_id = 0;
var post_params = {
'ajax_request' : true,
'get_data_row' : true,
@@ -565,8 +563,8 @@ $(document).ready(function() {
// Row is contained in data.row_info,
// now fill the displayResultForm with row values
for (key in data.row_info) {
- $field = $('#fieldID_' + field_id);
- $field_null = $('#fields_null_id_' + field_id);
+ $field = $('#edit_fieldID_' + field_id);
+ $field_null = $('#edit_fields_null_id_' + field_id);
if (data.row_info[key] == null) {
$field_null.attr('checked', true);
$field.val('');
diff --git a/libraries/Error.class.php b/libraries/Error.class.php
index 06498917a3..306d2c19b5 100644
--- a/libraries/Error.class.php
+++ b/libraries/Error.class.php
@@ -255,7 +255,9 @@ class PMA_Error extends PMA_Message
$retval = '';
foreach ($this->getBacktrace() as $step) {
- $retval .= PMA_Error::relPath($step['file']) . '#' . $step['line'] . ': ';
+ if (isset($step['file']) && isset($step['line'])) {
+ $retval .= PMA_Error::relPath($step['file']) . '#' . $step['line'] . ': ';
+ }
if (isset($step['class'])) {
$retval .= $step['class'] . $step['type'];
}
@@ -317,6 +319,7 @@ class PMA_Error extends PMA_Message
*/
public function getDisplay()
{
+ $this->isDisplayed(true);
$retval = '
';
if (! $this->isUserError()) {
$retval .= '
' . $this->getType() . ' ';
diff --git a/libraries/Error_Handler.class.php b/libraries/Error_Handler.class.php
index ef3ed50fba..d623c321ca 100644
--- a/libraries/Error_Handler.class.php
+++ b/libraries/Error_Handler.class.php
@@ -64,8 +64,8 @@ class PMA_Error_Handler
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()) {
+ break;
+ } else if (($error instanceof PMA_Error) && ! $error->isDisplayed()) {
$_SESSION['errors'][$key] = $error;
}
}
@@ -205,17 +205,29 @@ class PMA_Error_Handler
}
/**
- * display user errors not displayed
+ * Displays user errors not displayed
*
* @return void
*/
public function dispUserErrors()
{
+ echo $this->getDispUserErrors();
+ }
+
+ /**
+ * Renders user errors not displayed
+ *
+ * @return string
+ */
+ public function getDispUserErrors()
+ {
+ $retval = '';
foreach ($this->getErrors() as $error) {
if ($error->isUserError() && ! $error->isDisplayed()) {
- $error->display();
+ $retval .= $error->getDisplay();
}
}
+ return $retval;
}
/**
@@ -227,6 +239,7 @@ class PMA_Error_Handler
*/
protected function dispPageStart($error = null)
{
+ PMA_Response::getInstance()->disable();
echo '
';
if ($error) {
echo $error->getTitle();
@@ -259,25 +272,39 @@ class PMA_Error_Handler
}
/**
- * display errors not displayed
+ * renders errors not displayed
+ *
+ * @return void
+ */
+ public function getDispErrors()
+ {
+ $retval = '';
+ if ($GLOBALS['cfg']['Error_Handler']['display']) {
+ foreach ($this->getErrors() as $error) {
+ if ($error instanceof PMA_Error) {
+ if (! $error->isDisplayed()) {
+ $retval .= $error->getDisplay();
+ }
+ } else {
+ ob_start();
+ var_dump($error);
+ $retval .= ob_end_clean();
+ }
+ }
+ } else {
+ $retval .= $this->getDispUserErrors();
+ }
+ return $retval;
+ }
+
+ /**
+ * displays errors not displayed
*
* @return void
*/
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();
- }
+ echo $this->getDispErrors();
}
/**
@@ -297,7 +324,7 @@ class PMA_Error_Handler
}
//$this->errors = array_merge($_SESSION['errors'], $this->errors);
- // delet stored errors
+ // delete stored errors
$_SESSION['errors'] = array();
unset($_SESSION['errors']);
}
diff --git a/libraries/Footer.class.php b/libraries/Footer.class.php
new file mode 100644
index 0000000000..d231e134cc
--- /dev/null
+++ b/libraries/Footer.class.php
@@ -0,0 +1,334 @@
+_isEnabled = true;
+ $this->_scripts = new PMA_Scripts();
+ $this->_isMinimal = false;
+ $this->_addDefaultScripts();
+ }
+
+ /**
+ * Loads common scripts
+ *
+ * @return void
+ */
+ private function _addDefaultScripts()
+ {
+ if (empty($GLOBALS['error_message'])) {
+ $this->_scripts->addCode("
+ $(function() {
+ // updates current settings
+ if (window.parent.setAll) {
+ window.parent.setAll(
+ '" . PMA_escapeJsString($GLOBALS['lang']) . "',
+ '" . PMA_escapeJsString($GLOBALS['collation_connection']) . "',
+ '" . PMA_escapeJsString($GLOBALS['server']) . "',
+ '" . PMA_escapeJsString(PMA_ifSetOr($GLOBALS['db'], '')) . "',
+ '" . PMA_escapeJsString(PMA_ifSetOr($GLOBALS['table'], '')) . "',
+ '" . PMA_escapeJsString($_SESSION[' PMA_token ']) . "'
+ );
+ }
+ });
+ ");
+ if (! empty($GLOBALS['reload'])) {
+ $this->_scripts->addCode("
+ // refresh navigation frame content
+ if (window.parent.refreshNavigation) {
+ window.parent.refreshNavigation();
+ }
+ ");
+ } else if (isset($_GET['reload_left_frame'])
+ && $_GET['reload_left_frame'] == '1'
+ ) {
+ // reload left frame (used by user preferences)
+ $this->_scripts->addCode("
+ if (window.parent && window.parent.frame_navigation) {
+ window.parent.frame_navigation.location.reload();
+ }
+ ");
+ }
+
+ // set current db, table and sql query in the querywindow
+ $query = '';
+ if (strlen($GLOBALS['sql_query']) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
+ $query = PMA_escapeJsString($GLOBALS['sql_query']);
+ }
+ $this->_scripts->addCode("
+ if (window.parent.reload_querywindow) {
+ window.parent.reload_querywindow(
+ '" . PMA_escapeJsString(PMA_ifSetOr($GLOBALS['db'], '')) . "',
+ '" . PMA_escapeJsString(PMA_ifSetOr($GLOBALS['table'], '')) . "',
+ '" . $query . "'
+ );
+ }
+ ");
+
+ if (! empty($GLOBALS['focus_querywindow'])) {
+ // set focus to the querywindow
+ $this->_scripts->addCode("
+ if (parent.querywindow && !parent.querywindow.closed
+ && parent.querywindow.location
+ ) {
+ self.focus();
+ }
+ ");
+ }
+ $this->_scripts->addCode("
+ if (window.parent.frame_content) {
+ // reset content frame name, as querywindow needs
+ // to set a unique name before submitting form data,
+ // and navigation frame needs the original name
+ if (typeof(window.parent.frame_content.name) != 'undefined'
+ && window.parent.frame_content.name != 'frame_content') {
+ window.parent.frame_content.name = 'frame_content';
+ }
+ if (typeof(window.parent.frame_content.id) != 'undefined'
+ && window.parent.frame_content.id != 'frame_content') {
+ window.parent.frame_content.id = 'frame_content';
+ }
+ //window.parent.frame_content.setAttribute('name', 'frame_content');
+ //window.parent.frame_content.setAttribute('id', 'frame_content');
+ }
+ ");
+ }
+ }
+
+ /**
+ * Renders the debug messages
+ *
+ * @return string
+ */
+ private function _getDebugMessage()
+ {
+ $retval = '';
+ if (! empty($_SESSION['debug'])) {
+ $sum_time = 0;
+ $sum_exec = 0;
+ foreach ($_SESSION['debug']['queries'] as $query) {
+ $sum_time += $query['count'] * $query['time'];
+ $sum_exec += $query['count'];
+ }
+
+ $retval .= '';
+ $retval .= count($_SESSION['debug']['queries']) . ' queries executed ';
+ $retval .= $sum_exec . ' times in ' . $sum_time . ' seconds';
+ $retval .= '
';
+
+ ob_start();
+ print_r($_SESSION['debug']);
+ $retval .= ob_end_clean();
+
+ $retval .= ' ';
+ $retval .= '
';
+ $_SESSION['debug'] = array();
+ }
+ return $retval;
+ }
+
+ /**
+ * Renders the link to open a new page
+ *
+ * @param string $url_params URL paramater string
+ *
+ * @return string
+ */
+ private function _getSelfLink($url_params)
+ {
+ $retval = '';
+ $retval .= '';
+ return $retval;
+ }
+
+ /**
+ * Renders the link to open a new page
+ *
+ * @return string
+ */
+ private function _getErrorMessages()
+ {
+ $retval = '';
+ if ($GLOBALS['error_handler']->hasDisplayErrors()) {
+ $retval .= '';
+ $retval .= $GLOBALS['error_handler']->getDispErrors();
+ $retval .= '
';
+ }
+ return $retval;
+ }
+
+ /**
+ * Saves query in history
+ *
+ * @return void
+ */
+ private function _setHistory()
+ {
+ if (! PMA_isValid($_REQUEST['no_history'])
+ && empty($GLOBALS['error_message'])
+ && ! empty($GLOBALS['sql_query'])
+ ) {
+ PMA_setHistory(
+ PMA_ifSetOr($GLOBALS['db'], ''),
+ PMA_ifSetOr($GLOBALS['table'], ''),
+ $GLOBALS['cfg']['Server']['user'],
+ $GLOBALS['sql_query']
+ );
+ }
+ }
+
+ /**
+ * Disables the rendering of the footer
+ *
+ * @return void
+ */
+ public function disable()
+ {
+ $this->_isEnabled = false;
+ }
+
+ /**
+ * Set the ajax flag to indicate whether
+ * we are sevicing an ajax request
+ *
+ * @param bool $isAjax Whether we are sevicing an ajax request
+ *
+ * @return void
+ */
+ public function setAjax($isAjax)
+ {
+ $this->_isAjax = ($isAjax == true);
+ }
+
+ /**
+ * Turn on minimal display mode
+ *
+ * @return void
+ */
+ public function setMinimal()
+ {
+ $this->_isMinimal = true;
+ }
+
+ /**
+ * Returns the PMA_Scripts object
+ *
+ * @return PMA_Scripts object
+ */
+ public function getScripts()
+ {
+ return $this->_scripts;
+ }
+
+ /**
+ * Renders the footer
+ *
+ * @return string
+ */
+ public function getDisplay()
+ {
+ $retval = '';
+ $this->_setHistory();
+ if ($this->_isEnabled) {
+ if (! $this->_isAjax && ! $this->_isMinimal) {
+ // Link to itself to replicate windows including frameset
+ if (! isset($GLOBALS['checked_special'])) {
+ $GLOBALS['checked_special'] = false;
+ }
+ if (PMA_getenv('SCRIPT_NAME')
+ && empty($_POST)
+ && ! $GLOBALS['checked_special']
+ && ! $this->_isAjax
+ ) {
+ $url_params['target'] = basename(PMA_getenv('SCRIPT_NAME'));
+ $url = PMA_generate_common_url($url_params, 'text', '');
+ $this->_scripts->addCode("
+ // Store current location in hash part
+ // of URL to allow direct bookmarking
+ setURLHash('$url');
+ ");
+ $retval .= $this->_getSelfLink($url_params);
+ }
+ $retval .= $this->_getDebugMessage();
+ $retval .= $this->_getErrorMessages();
+ $retval .= $this->_scripts->getDisplay();
+ // Include possible custom footers
+ if (file_exists(CUSTOM_FOOTER_FILE)) {
+ ob_start();
+ include CUSTOM_FOOTER_FILE;
+ $retval .= ob_end_clean();
+ }
+ } else if (! $this->_isAjax) {
+ $retval .= "";
+ }
+ }
+
+ return $retval;
+ }
+}
diff --git a/libraries/Header.class.php b/libraries/Header.class.php
new file mode 100644
index 0000000000..eaabde56c8
--- /dev/null
+++ b/libraries/Header.class.php
@@ -0,0 +1,528 @@
+_isEnabled = true;
+ $this->_isAjax = false;
+ $this->_bodyId = '';
+ $this->_title = '';
+ $this->_menu = new PMA_Menu(
+ $GLOBALS['server'],
+ $GLOBALS['db'],
+ $GLOBALS['table']
+ );
+ $this->_menuEnabled = true;
+ $this->_warningsEnabled = true;
+ $this->_isPrintView = false;
+ $this->_scripts = new PMA_Scripts();
+ $this->_addDefaultScripts();
+ $this->_headerIsSent = false;
+ // if database storage for user preferences is transient,
+ // offer to load exported settings from localStorage
+ // (detection will be done in JavaScript)
+ $this->_userprefsOfferImport = false;
+ if ($GLOBALS['PMA_Config']->get('user_preferences') == 'session'
+ && ! isset($_SESSION['userprefs_autoload'])
+ ) {
+ $this->_userprefsOfferImport = true;
+ }
+ }
+
+ /**
+ * Loads common scripts
+ *
+ * @return void
+ */
+ private function _addDefaultScripts()
+ {
+ $this->_scripts->addFile('jquery/jquery-1.6.2.js');
+ $this->_scripts->addFile('jquery/jquery-ui-1.8.16.custom.js');
+ $this->_scripts->addFile('jquery/jquery.sprintf.js');
+ $this->_scripts->addFile('update-location.js');
+
+ $this->_scripts->addFile('jquery/jquery.qtip-1.0.0-rc3.js');
+ if ($GLOBALS['cfg']['CodemirrorEnable']) {
+ $this->_scripts->addFile('codemirror/lib/codemirror.js');
+ $this->_scripts->addFile('codemirror/mode/mysql/mysql.js');
+ }
+ // Cross-framing protection
+ if ($GLOBALS['cfg']['AllowThirdPartyFraming'] === false) {
+ $this->_scripts->addFile('cross_framing_protection.js');
+ }
+ // Localised strings
+ $params = array('lang' => $GLOBALS['lang']);
+ if (isset($GLOBALS['db'])) {
+ $params['db'] = $GLOBALS['db'];
+ }
+ $this->_scripts->addFile('messages.php' . PMA_generate_common_url($params));
+ // Append the theme id to this url to invalidate
+ // the cache on a theme change
+ $this->_scripts->addFile(
+ 'get_image.js.php?theme='
+ . urlencode($_SESSION['PMA_Theme']->getId())
+ );
+ $this->_scripts->addFile('functions.js');
+ $this->_scripts->addCode(PMA_getReloadNavigationScript(true));
+ }
+
+ /**
+ * Disables the rendering of the header
+ *
+ * @return void
+ */
+ public function disable()
+ {
+ $this->_isEnabled = false;
+ }
+
+ /**
+ * Set the ajax flag to indicate whether
+ * we are sevicing an ajax request
+ *
+ * @param bool $isAjax Whether we are sevicing an ajax request
+ *
+ * @return void
+ */
+ public function setAjax($isAjax)
+ {
+ $this->_isAjax = ($isAjax == true);
+ }
+
+ /**
+ * Returns the PMA_Scripts object
+ *
+ * @return PMA_Scripts object
+ */
+ public function getScripts()
+ {
+ return $this->_scripts;
+ }
+
+ /**
+ * Setter for the ID attribute in the BODY tag
+ *
+ * @param string $id Value for the ID attribute
+ *
+ * @return void
+ */
+ public function setBodyId($id)
+ {
+ $this->_bodyId = htmlspecialchars($id);
+ }
+
+ /**
+ * Setter for the title of the page
+ *
+ * @param string $title New title
+ *
+ * @return void
+ */
+ public function setTitle($title)
+ {
+ $this->_title = htmlspecialchars($title);
+ }
+
+ /**
+ * Disables the display of the top menu
+ *
+ * @return void
+ */
+ public function disableMenu()
+ {
+ $this->_menuEnabled = false;
+ }
+
+ /**
+ * Disables the display of the top menu
+ *
+ * @return void
+ */
+ public function disableWarnings()
+ {
+ $this->_warningsEnabled = false;
+ }
+
+ /**
+ * Turns on 'print view' mode
+ *
+ * @return void
+ */
+ public function enablePrintView()
+ {
+ $this->disableMenu();
+ $this->setTitle(__('Print view') . ' - phpMyAdmin ' . PMA_VERSION);
+ $this->_isPrintView = true;
+ }
+
+ /**
+ * Generates the header
+ *
+ * @return string The header
+ */
+ public function getDisplay()
+ {
+ $retval = '';
+ if (! $this->_headerIsSent) {
+ if (! $this->_isAjax && $this->_isEnabled) {
+ $this->sendHttpHeaders();
+ $retval .= $this->_getHtmlStart();
+ $retval .= $this->_getMetaTags();
+ $retval .= $this->_getLinkTags();
+ $retval .= $this->_getTitleTag();
+ $title = PMA_sanitize(
+ PMA_escapeJsString($this->_getPageTitle()),
+ false,
+ true
+ );
+ $this->_scripts->addCode(
+ "if (typeof(parent.document) != 'undefined'"
+ . " && typeof(parent.document) != 'unknown'"
+ . " && typeof(parent.document.title) == 'string')"
+ . "{"
+ . "parent.document.title = '$title'"
+ . "}"
+ );
+ if ($this->_userprefsOfferImport) {
+ $this->_scripts->addFile('config.js');
+ }
+ $retval .= $this->_scripts->getDisplay();
+ $retval .= $this->_getBodyStart();
+ // Include possible custom headers
+ if (file_exists(CUSTOM_HEADER_FILE)) {
+ ob_start();
+ include CUSTOM_HEADER_FILE;
+ $retval .= ob_end_clean();
+ }
+ // offer to load user preferences from localStorage
+ if ($this->_userprefsOfferImport) {
+ include_once './libraries/user_preferences.lib.php';
+ $retval .= PMA_userprefsAutoloadGetHeader();
+ }
+ // pass configuration for hint tooltip display
+ // (to be used by PMA_createqTip in js/functions.js)
+ if (! $GLOBALS['cfg']['ShowHint']) {
+ $retval .= ' ';
+ }
+ $retval .= $this->_getWarnings();
+ if ($this->_menuEnabled && $GLOBALS['server'] > 0) {
+ $retval .= $this->_menu->getDisplay();
+ }
+ $retval .= $this->_addRecentTable(
+ $GLOBALS['db'],
+ $GLOBALS['table']
+ );
+ }
+ }
+ return $retval;
+ }
+
+ /**
+ * Sends out the HTTP headers
+ *
+ * @return void
+ */
+ public function sendHttpHeaders()
+ {
+ /**
+ * Sends http headers
+ */
+ $GLOBALS['now'] = gmdate('D, d M Y H:i:s') . ' GMT';
+ /* Prevent against ClickJacking by allowing frames only from same origin */
+ if (! $GLOBALS['cfg']['AllowThirdPartyFraming']) {
+ header(
+ 'X-Frame-Options: SAMEORIGIN'
+ );
+ header(
+ "X-Content-Security-Policy: allow 'self'; "
+ . "options inline-script eval-script; "
+ . "frame-ancestors 'self'; img-src 'self' data:; "
+ . "script-src 'self' http://www.phpmyadmin.net"
+ );
+ header(
+ "X-WebKit-CSP: allow 'self' http://www.phpmyadmin.net; "
+ . "options inline-script eval-script"
+ );
+ }
+ PMA_noCacheHeader();
+ if (! defined('IS_TRANSFORMATION_WRAPPER')) {
+ // Define the charset to be used
+ header('Content-Type: text/html; charset=utf-8');
+ }
+ $this->_headerIsSent = true;
+ }
+
+ /**
+ * Returns the DOCTYPE and the start HTML tag
+ *
+ * @return string DOCTYPE and HTML tags
+ */
+ private function _getHtmlStart()
+ {
+ $lang = $GLOBALS['available_languages'][$GLOBALS['lang']][1];
+ $dir = $GLOBALS['text_dir'];
+
+ $retval = "";
+ $retval .= "";
+
+ return $retval;
+ }
+
+ /**
+ * Returns the META tags
+ *
+ * @return string the META tags
+ */
+ private function _getMetaTags()
+ {
+ $retval = ' ';
+ $retval .= ' ';
+ return $retval;
+ }
+
+ /**
+ * Returns the LINK tags for the favicon and the stylesheets
+ *
+ * @return string the LINK tags
+ */
+ private function _getLinkTags()
+ {
+ $retval = ' '
+ . ' ';
+ // stylesheets
+ $basedir = defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : '';
+ $common_url = PMA_generate_common_url(array('server' => $GLOBALS['server']));
+ $theme_id = $GLOBALS['PMA_Config']->getThemeUniqueValue();
+ $theme_path = $GLOBALS['pmaThemePath'];
+
+ if ($this->_isPrintView) {
+ $retval .= ' ';
+ } else {
+ $retval .= ' ';
+ $retval .= ' ';
+ }
+
+ return $retval;
+ }
+
+ /**
+ * Returns the TITLE tag
+ *
+ * @return string the TITLE tag
+ */
+ private function _getTitleTag()
+ {
+ $retval = "";
+ $retval .= $this->_getPageTitle();
+ $retval .= " ";
+ return $retval;
+ }
+
+ /**
+ * If the page is missing the title, this function
+ * will set it to something reasonable
+ *
+ * @return string
+ */
+ private function _getPageTitle()
+ {
+ if (empty($this->_title)) {
+ if ($GLOBALS['server'] > 0) {
+ if (! empty($GLOBALS['table'])) {
+ $temp_title = $GLOBALS['cfg']['TitleTable'];
+ } else if (! empty($GLOBALS['db'])) {
+ $temp_title = $GLOBALS['cfg']['TitleDatabase'];
+ } elseif (! empty($GLOBALS['cfg']['Server']['host'])) {
+ $temp_title = $GLOBALS['cfg']['TitleServer'];
+ } else {
+ $temp_title = $GLOBALS['cfg']['TitleDefault'];
+ }
+ $this->_title = htmlspecialchars(
+ PMA_expandUserString($temp_title)
+ );
+ } else {
+ $this->_title = 'phpMyAdmin';
+ }
+ }
+ return $this->_title;
+ }
+
+ /**
+ * Returns the close tag to the HEAD
+ * and the start tag for the BODY
+ *
+ * @return string HEAD and BODY tags
+ */
+ private function _getBodyStart()
+ {
+ $retval = " _bodyId)) {
+ $retval .= " id='" . $this->_bodyId . "'";
+ }
+ $retval .= ">";
+ return $retval;
+ }
+
+ /**
+ * Returns some warnings to be displayed at the top of the page
+ *
+ * @return string The warnings
+ */
+ private function _getWarnings()
+ {
+ $retval = '';
+ if ($this->_warningsEnabled) {
+ // message of "Cookies required" displayed for auth_type http or config
+ // note: here, the decoration won't work because without cookies,
+ // our standard CSS is not operational
+ if (empty($_COOKIE)) {
+ $retval .= PMA_Message::notice(
+ __('Cookies must be enabled past this point.')
+ )->getDisplay();
+ }
+ $retval .= "
";
+ $retval .= PMA_message::error(
+ __("Javascript must be enabled past this point")
+ )->getDisplay();
+ $retval .= " ";
+ }
+ return $retval;
+ }
+
+ /**
+ * Add recently used table and reload the navigation.
+ *
+ * @param string $db Database name where the table is located.
+ * @param string $table The table name
+ *
+ * @return string
+ */
+ private function _addRecentTable($db, $table)
+ {
+ $retval = '';
+ if (strlen($table) && $GLOBALS['cfg']['LeftRecentTable'] > 0) {
+ $tmp_result = PMA_RecentTable::getInstance()->add($db, $table);
+ if ($tmp_result === true) {
+ $retval = '
';
+ } else {
+ $error = $tmp_result;
+ $retval = $error->getDisplay();
+ }
+ }
+ return $retval;
+ }
+}
+
+?>
diff --git a/libraries/Menu.class.php b/libraries/Menu.class.php
index 4d4f5d668f..f1b192929e 100644
--- a/libraries/Menu.class.php
+++ b/libraries/Menu.class.php
@@ -10,7 +10,7 @@ if (! defined('PHPMYADMIN')) {
}
/**
- * Singleton class for generating the top menu
+ * Class for generating the top menu
*
* @package PhpMyAdmin
*/
@@ -37,17 +37,9 @@ class PMA_Menu
* @var string
*/
private $_table;
- /**
- * PMA_Menu instance
- *
- * @access private
- * @static
- * @var object
- */
- private static $_instance;
/**
- * Private constructor disables direct object creation
+ * Creates a new instance of PMA_Menu
*
* @param int $server Server id
* @param string $db Database name
@@ -55,28 +47,11 @@ class PMA_Menu
*
* @return New PMA_Table
*/
- private function __construct($server, $db, $table)
+ public function __construct($server, $db, $table)
{
$this->_server = $server;
- $this->_db = $db;
- $this->_table = $table;
- }
-
- /**
- * Prints the menu and the breadcrumbs
- *
- * @return void
- */
- public static function getInstance()
- {
- if (empty(self::$_instance)) {
- self::$_instance = new PMA_Menu(
- $GLOBALS['server'],
- $GLOBALS['db'],
- $GLOBALS['table']
- );
- }
- return self::$_instance;
+ $this->_db = $db;
+ $this->_table = $table;
}
/**
@@ -86,12 +61,29 @@ class PMA_Menu
*/
public function display()
{
- echo $this->_getBreadcrumbs();
- echo $this->_getMenu();
+ echo $this->getDisplay();
+ }
+
+ /**
+ * Returns the menu and the breadcrumbs as a string
+ *
+ * @return string
+ */
+ public function getDisplay()
+ {
+ $retval = $this->_getBreadcrumbs();
+ $retval .= $this->_getMenu();
if (! empty($GLOBALS['message'])) {
- echo PMA_getMessage($GLOBALS['message']);
+ if (isset($GLOBALS['buffer_message'])) {
+ $buffer_message = $GLOBALS['buffer_message'];
+ }
+ $retval .= PMA_getMessage($GLOBALS['message']);
unset($GLOBALS['message']);
+ if (isset($buffer_message)) {
+ $GLOBALS['buffer_message'] = $buffer_message;
+ }
}
+ return $retval;
}
/**
@@ -214,10 +206,6 @@ class PMA_Menu
} // end if
} else {
// no table selected, display database comment if present
- /**
- * Settings for relations stuff
- */
- include_once './libraries/relation.lib.php';
$cfgRelation = PMA_getRelationsParam();
// Get additional information about tables for tooltip is done
@@ -353,7 +341,7 @@ class PMA_Menu
* export, search and qbe links if there is at least one table
*/
if ($num_tables == 0) {
- $tabs['qbe']['warning'] = __('Database seems to be empty!');
+ $tabs['qbe']['warning'] = __('Database seems to be empty!');
$tabs['search']['warning'] = __('Database seems to be empty!');
$tabs['export']['warning'] = __('Database seems to be empty!');
}
@@ -480,9 +468,9 @@ class PMA_Menu
$tabs['import']['link'] = 'server_import.php';
$tabs['import']['text'] = __('Import');
- $tabs['settings']['icon'] = 'b_tblops.png';
- $tabs['settings']['link'] = 'prefs_manage.php';
- $tabs['settings']['text'] = __('Settings');
+ $tabs['settings']['icon'] = 'b_tblops.png';
+ $tabs['settings']['link'] = 'prefs_manage.php';
+ $tabs['settings']['text'] = __('Settings');
$tabs['settings']['active'] = in_array(
basename($GLOBALS['PMA_PHP_SELF']),
array('prefs_forms.php', 'prefs_manage.php')
diff --git a/libraries/Message.class.php b/libraries/Message.class.php
index b17ec31b95..de7cfe9fba 100644
--- a/libraries/Message.class.php
+++ b/libraries/Message.class.php
@@ -27,15 +27,15 @@
* $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');
+ * // two parameters: $strSomeTooltip = 'Read the %smanual%s'
+ * $hint = PMA_Message::notice('strSomeTooltip');
* // replace %d with the following params
* $hint->addParam('[a@./Documentation.html#cfg_Example@_blank]');
* $hint->addParam('[/a]');
- * // add this hint as a footnote
+ * // add this hint as a tooltip
* $hint = PMA_showHint($hint);
*
- * // add the retrieved footnote reference to the original message
+ * // add the retrieved tooltip reference to the original message
* $message->addMessage($hint);
*
* // create another message ...
@@ -700,6 +700,7 @@ class PMA_Message
*/
public function getDisplay()
{
+ $this->isDisplayed(true);
return '
'
. $this->getMessage() . '
';
}
diff --git a/libraries/OutputBuffering.class.php b/libraries/OutputBuffering.class.php
new file mode 100644
index 0000000000..782e7d0686
--- /dev/null
+++ b/libraries/OutputBuffering.class.php
@@ -0,0 +1,129 @@
+_mode = $this->_getMode();
+ $this->_on = false;
+ }
+
+ /**
+ * This function could be used eventually to support more modes.
+ *
+ * @return integer the output buffer mode
+ */
+ private function _getMode()
+ {
+ $mode = 0;
+ if ($GLOBALS['cfg']['OBGzip'] && function_exists('ob_start')) {
+ if (ini_get('output_handler') == 'ob_gzhandler') {
+ // If a user sets the output_handler in php.ini to ob_gzhandler, then
+ // any right frame file in phpMyAdmin will not be handled properly by
+ // the browser. My fix was to check the ini file within the
+ // PMA_outBufferModeGet() function.
+ $mode = 0;
+ } elseif (function_exists('ob_get_level') && ob_get_level() > 0) {
+ // If output buffering is enabled in php.ini it's not possible to
+ // add the ob_gzhandler without a warning message from php 4.3.0.
+ // Being better safe than sorry, check for any existing output handler
+ // instead of just checking the 'output_buffering' setting.
+ $mode = 0;
+ } else {
+ $mode = 1;
+ }
+ }
+ // Zero (0) is no mode or in other words output buffering is OFF.
+ // Follow 2^0, 2^1, 2^2, 2^3 type values for the modes.
+ // Usefull if we ever decide to combine modes. Then a bitmask field of
+ // the sum of all modes will be the natural choice.
+ return $mode;
+ }
+
+ /**
+ * Returns the singleton PMA_OutputBuffering object
+ *
+ * @return PMA_OutputBuffering object
+ */
+ public static function getInstance()
+ {
+ if (empty(self::$_instance)) {
+ self::$_instance = new PMA_OutputBuffering();
+ }
+ return self::$_instance;
+ }
+
+ /**
+ * This function will need to run at the top of all pages if output
+ * output buffering is turned on. It also needs to be passed $mode from
+ * the PMA_outBufferModeGet() function or it will be useless.
+ *
+ */
+ public function start()
+ {
+ if (! $this->_on) {
+ if ($this->_mode) {
+ ob_start('ob_gzhandler');
+ }
+ ob_start();
+ header('X-ob_mode: ' . $this->_mode);
+ register_shutdown_function('PMA_OutputBuffering::stop');
+ $this->_on = true;
+ }
+ }
+
+ /**
+ * This function will need to run at the bottom of all pages if output
+ * buffering is turned on. It also needs to be passed $mode from the
+ * PMA_outBufferModeGet() function or it will be useless.
+ *
+ */
+ public static function stop()
+ {
+ $buffer = PMA_OutputBuffering::getInstance();
+ if ($buffer->_on) {
+ $buffer->_on = false;
+ $buffer->_content = ob_get_contents();
+ ob_end_clean();
+ }
+ PMA_Response::response();
+ }
+
+ public function getContents()
+ {
+ return $this->_content;
+ }
+
+ public function flush()
+ {
+ if (ob_get_status() && $this->_mode) {
+ ob_flush();
+ }
+ /**
+ * previously we had here an "else flush()" but some PHP versions
+ * (at least PHP 5.2.11) have a bug (49816) that produces garbled
+ * data
+ */
+ }
+}
+
+?>
diff --git a/libraries/PDF.class.php b/libraries/PDF.class.php
index 99ea2035a9..54b83e1203 100644
--- a/libraries/PDF.class.php
+++ b/libraries/PDF.class.php
@@ -85,9 +85,8 @@ class PMA_PDF extends TCPDF
*/
function Error($error_message = '')
{
- include './libraries/header.inc.php';
PMA_Message::error(__('Error while creating PDF:') . ' ' . $error_message)->display();
- include './libraries/footer.inc.php';
+ exit;
}
/**
diff --git a/libraries/Response.class.php b/libraries/Response.class.php
new file mode 100644
index 0000000000..c341acc614
--- /dev/null
+++ b/libraries/Response.class.php
@@ -0,0 +1,315 @@
+start();
+ $this->_header = new PMA_Header();
+ $this->_HTML = '';
+ $this->_JSON = array();
+ $this->_footer = new PMA_Footer();
+
+ $this->_isSuccess = true;
+ $this->_isAjax = false;
+ if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
+ $this->_isAjax = true;
+ }
+ $this->_header->setAjax($this->_isAjax);
+ $this->_footer->setAjax($this->_isAjax);
+ $this->_CWD = getcwd();
+ }
+
+ /**
+ * Returns the singleton PMA_Response object
+ *
+ * @return PMA_Response object
+ */
+ public static function getInstance()
+ {
+ if (empty(self::$_instance)) {
+ self::$_instance = new PMA_Response();
+ }
+ return self::$_instance;
+ }
+
+ /**
+ * Set the status of an ajax response,
+ * whether it is a success or an error
+ *
+ * @param bool $state Whether the request was successfully processed
+ *
+ * @return void
+ */
+ public function isSuccess($state)
+ {
+ $this->_isSuccess = ($state == true);
+ }
+
+ /**
+ * Returns true or false depending on whether
+ * we are servicing an ajax request
+ *
+ * @return void
+ */
+ public function isAjax()
+ {
+ return $this->_isAjax;
+ }
+
+ /**
+ * Returns the path to the current working directory
+ * Necessary to work around a PHP bug where the CWD is
+ * reset after the initial script exits
+ *
+ * @return string
+ */
+ public function getCWD()
+ {
+ return $this->_CWD;
+ }
+
+ /**
+ * Disables the rendering of the header
+ * and the footer in responses
+ *
+ * @return void
+ */
+ public function disable()
+ {
+ $this->_header->disable();
+ $this->_footer->disable();
+ }
+
+ /**
+ * Returns a PMA_Header object
+ *
+ * @return object
+ */
+ public function getHeader()
+ {
+ return $this->_header;
+ }
+
+ /**
+ * Returns a PMA_Footer object
+ *
+ * @return object
+ */
+ public function getFooter()
+ {
+ return $this->_footer;
+ }
+
+ /**
+ * Add HTML code to the response
+ *
+ * @param string $content A string to be appended to
+ * the current output buffer
+ *
+ * @return void
+ */
+ public function addHTML($content)
+ {
+ if ($content instanceof PMA_Message) {
+ $this->_HTML .= $content->getDisplay();
+ } else {
+ $this->_HTML .= $content;
+ }
+ }
+
+ /**
+ * Add JSON code to the response
+ *
+ * @param mixed $json Either a key (string) or an
+ * array or key-value pairs
+ * @param mixed $value Null, if passing an array in $json otherwise
+ * it's a string value to the key
+ *
+ * @return void
+ */
+ public function addJSON($json, $value = null)
+ {
+ if (is_array($json)) {
+ foreach ($json as $key => $value) {
+ $this->addJSON($key, $value);
+ }
+ } else {
+ if ($value instanceof PMA_Message) {
+ $this->_JSON[$json] = $value->getDisplay();
+ } else {
+ $this->_JSON[$json] = $value;
+ }
+ }
+
+ }
+
+ /**
+ * Renders the HTML response text
+ *
+ * @return string
+ */
+ private function _getDisplay()
+ {
+ // The header may contain nothing at all,
+ // if it's content was already rendered
+ // and, in this case, the header will be
+ // in the content part of the request
+ $retval = $this->_header->getDisplay();
+ $retval .= $this->_HTML;
+ $retval .= $this->_footer->getDisplay();
+ return $retval;
+ }
+
+ /**
+ * Sends an HTML response to the browser
+ *
+ * @return void
+ */
+ private function _htmlResponse()
+ {
+ echo $this->_getDisplay();
+ }
+
+ /**
+ * Sends a JSON response to the browser
+ *
+ * @return void
+ */
+ private function _ajaxResponse()
+ {
+ if (! isset($this->_JSON['message'])) {
+ $this->_JSON['message'] = $this->_getDisplay();
+ } else if ($this->_JSON['message'] instanceof PMA_Message) {
+ $this->_JSON['message'] = $this->_JSON['message']->getDisplay();
+ }
+
+ if ($this->_isSuccess) {
+ $this->_JSON['success'] = true;
+ } else {
+ $this->_JSON['success'] = false;
+ $this->_JSON['error'] = $this->_JSON['message'];
+ unset($this->_JSON['message']);
+ }
+
+ // Set the Content-Type header to JSON so that jQuery parses the
+ // response correctly.
+ if (! defined('TESTSUITE')) {
+ header('Cache-Control: no-cache');
+ header('Content-Type: application/json');
+ }
+
+ echo json_encode($this->_JSON);
+ }
+
+ /**
+ * Sends an HTML response to the browser
+ *
+ * @static
+ * @return void
+ */
+ public static function response()
+ {
+ $response = PMA_Response::getInstance();
+ chdir($response->getCWD());
+ $buffer = PMA_OutputBuffering::getInstance();
+ if (empty($response->_HTML)) {
+ $response->_HTML = $buffer->getContents();
+ }
+ if ($response->isAjax()) {
+ $response->_ajaxResponse();
+ } else {
+ $response->_htmlResponse();
+ }
+ $buffer->flush();
+ exit;
+ }
+}
+
+?>
diff --git a/libraries/Scripts.class.php b/libraries/Scripts.class.php
new file mode 100644
index 0000000000..604f310ede
--- /dev/null
+++ b/libraries/Scripts.class.php
@@ -0,0 +1,174 @@
+' . "\n ";
+ } else {
+ $include .= '' . "\n";
+ }
+ return $include;
+ }
+
+ /**
+ * Generates new PMA_Scripts objects
+ *
+ * @return PMA_Scripts object
+ */
+ public function __construct()
+ {
+ $this->_files = array();
+ $this->_code = '';
+ $this->_events = array();
+
+ }
+
+ /**
+ * Adds a new file to the list of scripts
+ *
+ * @param string $filename The name of the file to include
+ * @param bool $conditional_ie Whether to wrap the script tag in
+ * conditional comments for IE
+ *
+ * @return void
+ */
+ public function addFile($filename, $conditional_ie = false)
+ {
+ $filename = 'js/' . $filename;
+ $hash = md5($filename);
+ if (empty($this->_files[$hash])) {
+ $timestamp = null;
+ if (strpos($filename, '?') === false) {
+ $timestamp = filemtime($filename);
+ }
+ $this->_files[$hash] = array(
+ 'filename' => $filename,
+ 'timestamp' => $timestamp,
+ 'conditional_ie' => $conditional_ie
+ );
+ }
+ }
+
+ /**
+ * Adds a new code snippet to the code to be executed
+ *
+ * @param string $code The JS code to be added
+ *
+ * @return void
+ */
+ public function addCode($code)
+ {
+ $this->_code .= "$code\n";
+ }
+
+ /**
+ * Adds a new event to the list of events
+ *
+ * @param string $event The name of the event to register
+ * @param string $function The code to execute when the event fires
+ * E.g: 'function () { doSomething(); }'
+ * or 'doSomething'
+ *
+ * @return void
+ */
+ public function addEvent($event, $function)
+ {
+ $this->_events[] = array(
+ 'event' => $event,
+ 'function' => $function
+ );
+ }
+
+ /**
+ * Renders all the JavaScript file inclusions, code and events
+ *
+ * @return string
+ */
+ public function getDisplay()
+ {
+ $retval = '';
+
+ foreach ($this->_files as $file) {
+ $retval .= $this->_includeFile(
+ $file['filename'],
+ $file['conditional_ie']
+ );
+ }
+ $retval .= '';
+
+ return $retval;
+ }
+}
diff --git a/libraries/TableSearch.class.php b/libraries/TableSearch.class.php
new file mode 100644
index 0000000000..14624009aa
--- /dev/null
+++ b/libraries/TableSearch.class.php
@@ -0,0 +1,1207 @@
+_db = $db;
+ $this->_table = $table;
+ $this->_searchType = $searchType;
+ $this->_columnNames = array();
+ $this->_columnNullFlags = array();
+ $this->_columnTypes = array();
+ $this->_columnCollations = array();
+ $this->_geomColumnFlag = false;
+ $this->_foreigners = array();
+ // Loads table's information
+ $this->_loadTableInfo($this->_db, $this->_table);
+ }
+
+ /**
+ * Returns Column names array
+ *
+ * @return array column names
+ */
+ public function getColumnNames()
+ {
+ return $this->_columnNames;
+ }
+
+ /**
+ * Gets all the columns of a table along with their types, collations
+ * and whether null or not.
+ *
+ * @return array Array containing the column list, column types, collations
+ * and null constraint
+ */
+ private function _loadTableInfo()
+ {
+ // Gets the list and number of columns
+ $columns = PMA_DBI_get_columns($this->_db, $this->_table, null, true);
+ // Get details about the geometry fucntions
+ $geom_types = PMA_getGISDatatypes();
+
+ foreach ($columns as $key => $row) {
+ // set column name
+ $this->_columnNames[] = $row['Field'];
+
+ $type = $row['Type'];
+ // check whether table contains geometric columns
+ if (in_array($type, $geom_types)) {
+ $this->_geomColumnFlag = true;
+ }
+ // reformat mysql query output
+ if (strncasecmp($type, 'set', 3) == 0
+ || strncasecmp($type, 'enum', 4) == 0
+ ) {
+ $type = str_replace(',', ', ', $type);
+ } else {
+ // strip the "BINARY" attribute, except if we find "BINARY(" because
+ // this would be a BINARY or VARBINARY column type
+ if (! preg_match('@BINARY[\(]@i', $type)) {
+ $type = preg_replace('@BINARY@i', '', $type);
+ }
+ $type = preg_replace('@ZEROFILL@i', '', $type);
+ $type = preg_replace('@UNSIGNED@i', '', $type);
+ $type = strtolower($type);
+ }
+ if (empty($type)) {
+ $type = ' ';
+ }
+ $this->_columnTypes[] = $type;
+ $this->_columnNullFlags[] = $row['Null'];
+ $this->_columnCollations[]
+ = ! empty($row['Collation']) && $row['Collation'] != 'NULL'
+ ? $row['Collation']
+ : '';
+ } // end for
+
+ // Retrieve foreign keys
+ $this->_foreigners = PMA_getForeigners($this->_db, $this->_table);
+ }
+
+ /**
+ * Sets the table header for displaying a table in query-by-example format.
+ *
+ * @return HTML content, the tags and content for table header
+ */
+ private function _getTableHeader()
+ {
+ // Display the Function column only if there is at least one geometry column
+ $func = '';
+ if ($this->_geomColumnFlag) {
+ $func = '
' . __('Function') . ' ';
+ }
+
+ return '
+ ' . $func . '' . __('Column') . '
+ ' . __('Type') . '
+ ' . __('Collation') . '
+ ' . __('Operator') . '
+ ' . __('Value') . '
+
+ ';
+ }
+
+ /**
+ * Returns an array with necessary configrations to create
+ * sub-tabs(Table Search and Zoom Search) in the table_select page.
+ *
+ * @return array Array containing configuration (icon, text, link, id, args)
+ * of sub-tabs for Table Search and Zoom search
+ */
+ private function _getSubTabs()
+ {
+ $subtabs = array();
+ $subtabs['search']['icon'] = 'b_search.png';
+ $subtabs['search']['text'] = __('Table Search');
+ $subtabs['search']['link'] = 'tbl_select.php';
+ $subtabs['search']['id'] = 'tbl_search_id';
+ $subtabs['search']['args']['pos'] = 0;
+
+ $subtabs['zoom']['icon'] = 'b_props.png';
+ $subtabs['zoom']['link'] = 'tbl_zoom_select.php';
+ $subtabs['zoom']['text'] = __('Zoom Search');
+ $subtabs['zoom']['id'] = 'zoom_search_id';
+
+ return $subtabs;
+ }
+
+ /**
+ * Provides html elements for search criteria inputbox
+ * in case the column's type is geometrical
+ *
+ * @param int $column_index Column's index
+ * @param bool $in_fbs Whether we are in 'function based search'
+ *
+ * @return HTML elements.
+ */
+ private function _getGeometricalInputBox($column_index, $in_fbs)
+ {
+ $html_output = '
';
+
+ if ($in_fbs) {
+ $edit_url = 'gis_data_editor.php?' . PMA_generate_common_url();
+ $edit_str = PMA_getIcon('b_edit.png', __('Edit/Insert'));
+ $html_output .= '
';
+ $html_output .= PMA_linkOrButton(
+ $edit_url, $edit_str, array(), false, false, '_blank'
+ );
+ $html_output .= ' ';
+ }
+ return $html_output;
+ }
+
+ /**
+ * Provides html elements for search criteria inputbox
+ * in case the column is a Foreign Key
+ *
+ * @param array $foreignData Foreign keys data
+ * @param string $column_name Column name
+ * @param int $column_index Column index
+ * @param array $titles Selected title
+ * @param int $foreignMaxLimit Max limit of displaying foreign elements
+ * @param array $criteriaValues Array of search criteria inputs
+ * @param string $column_id Column's inputbox's id
+ * @param bool $in_zoom_search_edit Whether we are in zoom search edit
+ *
+ * @return HTML elements.
+ */
+ private function _getForeignKeyInputBox($foreignData, $column_name,
+ $column_index, $titles, $foreignMaxLimit, $criteriaValues, $column_id,
+ $in_zoom_search_edit = false
+ ) {
+ $html_output = '';
+ if (is_array($foreignData['disp_row'])) {
+ $html_output .= '
';
+ $html_output .= PMA_foreignDropdown(
+ $foreignData['disp_row'], $foreignData['foreign_field'],
+ $foreignData['foreign_display'], '', $foreignMaxLimit
+ );
+ $html_output .= ' ';
+
+ } elseif ($foreignData['foreign_link'] == true) {
+ $html_output .= '
';
+
+ $html_output .= <<
';
+ }
+ return $html_output;
+ }
+
+ /**
+ * Provides html elements for search criteria inputbox
+ * in case the column is of ENUM or SET type
+ *
+ * @param int $column_index Column index
+ * @param array $criteriaValues Array of search criteria inputs
+ * @param string $column_type Column type
+ * @param string $column_id Column's inputbox's id
+ * @param bool $in_zoom_search_edit Whether we are in zoom search edit
+ *
+ * @return HTML elements.
+ */
+ private function _getEnumSetInputBox($column_index, $criteriaValues,
+ $column_type, $column_id, $in_zoom_search_edit = false
+ ) {
+ $html_output = '';
+ $value = explode(
+ ', ',
+ str_replace("'", '', substr($column_type, 5, -1))
+ );
+ $cnt_value = count($value);
+
+ /*
+ * Enum in edit mode --> dropdown
+ * Enum in search mode --> multiselect
+ * Set in edit mode --> multiselect
+ * Set in search mode --> input (skipped here, so the 'else'
+ * section would handle it)
+ */
+ if ((strncasecmp($column_type, 'enum', 4) && ! $in_zoom_search_edit)
+ || (strncasecmp($column_type, 'set', 3) && $in_zoom_search_edit)
+ ) {
+ $html_output .= '';
+ } else {
+ $html_output .= '';
+ }
+
+ //Add select options
+ for ($j = 0; $j < $cnt_value; $j++) {
+ if (isset($criteriaValues[$column_index])
+ && is_array($criteriaValues[$column_index])
+ && in_array($value[$j], $criteriaValues[$column_index])
+ ) {
+ $html_output .= ''
+ . $value[$j] . ' ';
+ } else {
+ $html_output .= ''
+ . $value[$j] . ' ';
+ }
+ } // end for
+ $html_output .= ' ';
+ return $html_output;
+ }
+
+ /**
+ * Creates the HTML content for:
+ * 1) Browsing foreign data for a column.
+ * 2) Creating elements for search criteria input on columns.
+ *
+ * @param array $foreignData Foreign keys data
+ * @param string $column_name Column name
+ * @param string $column_type Column type
+ * @param int $column_index Column index
+ * @param array $titles Selected title
+ * @param int $foreignMaxLimit Max limit of displaying foreign elements
+ * @param array $criteriaValues Array of search criteria inputs
+ * @param bool $in_fbs Whether we are in 'function based search'
+ * @param bool $in_zoom_search_edit Whether we are in zoom search edit
+ *
+ * @return string HTML content for viewing foreing data and elements
+ * for search criteria input.
+ */
+ private function _getInputbox($foreignData, $column_name, $column_type,
+ $column_index, $titles, $foreignMaxLimit, $criteriaValues, $in_fbs = false,
+ $in_zoom_search_edit = false
+ ) {
+ $str = '';
+ $column_type = (string)$column_type;
+ $column_id = ($in_zoom_search_edit) ? 'edit_fieldID_' : 'fieldID_';
+
+ //Get inputbox based on different column types (Foreign key, geometrical, enum)
+ if ($this->_foreigners && isset($this->_foreigners[$column_name])) {
+ $str .= $this->_getForeignKeyInputBox(
+ $foreignData, $column_name, $column_index, $titles,
+ $foreignMaxLimit, $criteriaValues, $column_id
+ );
+
+ } elseif (in_array($column_type, PMA_getGISDatatypes())) {
+ $str .= $this->_getGeometricalInputBox($column_index, $in_fbs);
+
+ } elseif (strncasecmp($column_type, 'enum', 4) == 0
+ || (strncasecmp($column_type, 'set', 3) == 0 && $in_zoom_search_edit)
+ ) {
+ $str .= $this->_getEnumSetInputBox(
+ $column_index, $criteriaValues, $column_type, $column_id,
+ $in_zoom_search_edit = false
+ );
+
+ } else {
+ // other cases
+ $the_class = 'textfield';
+
+ if ($column_type == 'date') {
+ $the_class .= ' datefield';
+ } elseif ($column_type == 'datetime' || substr($column_type, 0, 9) == 'timestamp') {
+ $the_class .= ' datetimefield';
+ } elseif (substr($column_type, 0, 3) == 'bit') {
+ $the_class .= ' bit';
+ }
+
+ $str .= ' ';
+ }
+ return $str;
+ }
+
+ /**
+ * Return the where clause in case column's type is ENUM.
+ *
+ * @param mixed $criteriaValues Search criteria input
+ * @param string $func_type Search fucntion/operator
+ *
+ * @return string part of where clause.
+ */
+ private function _getEnumWhereClause($criteriaValues, $func_type)
+ {
+ $where = '';
+ if (! empty($criteriaValues)) {
+ if (! is_array($criteriaValues)) {
+ $criteriaValues = explode(',', $criteriaValues);
+ }
+ $enum_selected_count = count($criteriaValues);
+ if ($func_type == '=' && $enum_selected_count > 1) {
+ $func_type = 'IN';
+ $parens_open = '(';
+ $parens_close = ')';
+
+ } elseif ($func_type == '!=' && $enum_selected_count > 1) {
+ $func_type = 'NOT IN';
+ $parens_open = '(';
+ $parens_close = ')';
+
+ } else {
+ $parens_open = '';
+ $parens_close = '';
+ }
+ $enum_where = '\'' . PMA_sqlAddslashes($criteriaValues[0]) . '\'';
+ for ($e = 1; $e < $enum_selected_count; $e++) {
+ $enum_where .= ', \'' . PMA_sqlAddslashes($criteriaValues[$e])
+ . '\'';
+ }
+
+ $where = ' ' . $func_type . ' ' . $parens_open
+ . $enum_where . $parens_close;
+ }
+ return $where;
+ }
+
+ /**
+ * Return the where clause for a geometrical column.
+ *
+ * @param mixed $criteriaValues Search criteria input
+ * @param string $names Name of the column on which search is submitted
+ * @param string $func_type Search fucntion/operator
+ * @param bool $geom_func Whether geometry functions should be applied
+ *
+ * @return string part of where clause.
+ */
+ private function _getGeomWhereClause($criteriaValues, $names, $func_type, $geom_func = null)
+ {
+ $geom_unary_functions = array(
+ 'IsEmpty' => 1,
+ 'IsSimple' => 1,
+ 'IsRing' => 1,
+ 'IsClosed' => 1,
+ );
+ $where = '';
+
+ // Get details about the geometry fucntions
+ $geom_funcs = PMA_getGISFunctions($types, true, false);
+ // New output type is the output type of the function being applied
+ $types = $geom_funcs[$geom_func]['type'];
+
+ // If the function takes a single parameter
+ if ($geom_funcs[$geom_func]['params'] == 1) {
+ $backquoted_name = $geom_func . '(' . PMA_backquote($names) . ')';
+ } else {
+ // If the function takes two parameters
+ // create gis data from the criteria input
+ $gis_data = PMA_createGISData($criteriaValues);
+ $where = $geom_func . '(' . PMA_backquote($names) . ',' . $gis_data . ')';
+ return $where;
+ }
+
+ // If the where clause is something like 'IsEmpty(`spatial_col_name`)'
+ if (isset($geom_unary_functions[$geom_func]) && trim($criteriaValues) == '') {
+ $where = $backquoted_name;
+
+ } elseif (in_array($types, PMA_getGISDatatypes()) && ! empty($criteriaValues)) {
+ // create gis data from the criteria input
+ $gis_data = PMA_createGISData($criteriaValues);
+ $where = $backquoted_name . ' ' . $func_type . ' ' . $gis_data;
+ }
+ return $where;
+ }
+
+ /**
+ * Return the where clause for query generation based on the inputs provided.
+ *
+ * @param mixed $criteriaValues Search criteria input
+ * @param string $names Name of the column on which search is submitted
+ * @param string $types Type of the field
+ * @param string $collations Field collation
+ * @param string $func_type Search fucntion/operator
+ * @param bool $unaryFlag Whether operator unary or not
+ * @param bool $geom_func Whether geometry functions should be applied
+ *
+ * @return string generated where clause.
+ */
+ private function _getWhereClause($criteriaValues, $names, $types, $collations,
+ $func_type, $unaryFlag, $geom_func = null
+ ) {
+ // If geometry function is set
+ if ($geom_func != null && trim($geom_func) != '') {
+ return $this->_getGeomWhereClause($criteriaValues, $names, $func_type, $geom_func);
+ }
+
+ $backquoted_name = PMA_backquote($names);
+ $where = '';
+ if ($unaryFlag) {
+ $criteriaValues = '';
+ $where = $backquoted_name . ' ' . $func_type;
+
+ } elseif (strncasecmp($types, 'enum', 4) == 0) {
+ $where = $backquoted_name;
+ $where .= $this->_getEnumWhereClause($criteriaValues, $func_type);
+
+ } elseif ($criteriaValues != '') {
+ // For these types we quote the value. Even if it's another type (like INT),
+ // for a LIKE we always quote the value. MySQL converts strings to numbers
+ // and numbers to strings as necessary during the comparison
+ if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types)
+ || strpos(' ' . $func_type, 'LIKE')
+ ) {
+ $quot = '\'';
+ } else {
+ $quot = '';
+ }
+
+ // LIKE %...%
+ if ($func_type == 'LIKE %...%') {
+ $func_type = 'LIKE';
+ $criteriaValues = '%' . $criteriaValues . '%';
+ }
+ if ($func_type == 'REGEXP ^...$') {
+ $func_type = 'REGEXP';
+ $criteriaValues = '^' . $criteriaValues . '$';
+ }
+
+ if ($func_type == 'IN (...)'
+ || $func_type == 'NOT IN (...)'
+ || $func_type == 'BETWEEN'
+ || $func_type == 'NOT BETWEEN'
+ ) {
+ $func_type = str_replace(' (...)', '', $func_type);
+
+ // quote values one by one
+ $values = explode(',', $criteriaValues);
+ foreach ($values as &$value) {
+ $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot;
+ }
+
+ if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') {
+ $where = $backquoted_name . ' ' . $func_type . ' '
+ . (isset($values[0]) ? $values[0] : '')
+ . ' AND ' . (isset($values[1]) ? $values[1] : '');
+ } else {
+ $where = $backquoted_name . ' ' . $func_type
+ . ' (' . implode(',', $values) . ')';
+ }
+ } else {
+ $where = $backquoted_name . ' ' . $func_type . ' '
+ . $quot . PMA_sqlAddslashes($criteriaValues) . $quot;
+ }
+ } // end if
+
+ return $where;
+ }
+
+ /**
+ * Builds the sql search query from the post parameters
+ *
+ * @return string the generated SQL query
+ */
+ public function buildSqlQuery()
+ {
+ $sql_query = 'SELECT ';
+
+ // If only distinct values are needed
+ $is_distinct = (isset($_POST['distinct'])) ? 'true' : 'false';
+ if ($is_distinct == 'true') {
+ $sql_query .= 'DISTINCT ';
+ }
+
+ // if all column names were selected to display, we do a 'SELECT *'
+ // (more efficient and this helps prevent a problem in IE
+ // if one of the rows is edited and we come back to the Select results)
+ if (isset($_POST['zoom_submit'])) {
+ $sql_query .= '* ';
+ } else {
+ $sql_query .= (count($_POST['columnsToDisplay'])
+ == count($_POST['criteriaColumnNames'])
+ ? '* '
+ : implode(', ', PMA_backquote($_POST['columnsToDisplay'])));
+ } // end if
+
+ $sql_query .= ' FROM ' . PMA_backquote($_POST['table']);
+ $whereClause = $this->_generateWhereClause();
+ $sql_query .= $whereClause;
+
+ // if the search results are to be ordered
+ if (isset($_POST['orderByColumn']) && $_POST['orderByColumn'] != '--nil--') {
+ $sql_query .= ' ORDER BY ' . PMA_backquote($_POST['orderByColumn'])
+ . ' ' . $_POST['order'];
+ } // end if
+ return $sql_query;
+ }
+
+ /**
+ * Generates the where clause for the SQL search query to be executed
+ *
+ * @return string the generated where clause
+ */
+ private function _generateWhereClause()
+ {
+ $fullWhereClause = '';
+
+ if (isset($_POST['customWhereClause']) && trim($_POST['customWhereClause']) != '') {
+ $fullWhereClause .= ' WHERE ' . $_POST['customWhereClause'];
+ return $fullWhereClause;
+ }
+
+ // If there are no search criteria set, return
+ if (! array_filter($_POST['criteriaValues'])) {
+ return $fullWhereClause;
+ }
+
+ // else continue to form the where clause from column criteria values
+ $fullWhereClause = $charsets = array();
+ reset($_POST['criteriaColumnOperators']);
+ while (list($column_index, $operator) = each($_POST['criteriaColumnOperators'])) {
+ list($charsets[$column_index]) = explode(
+ '_', $_POST['criteriaColumnCollations'][$column_index]
+ );
+ $unaryFlag = $GLOBALS['PMA_Types']->isUnaryOperator($operator);
+ $tmp_geom_func = isset($geom_func[$column_index])
+ ? $geom_func[$column_index] : null;
+
+ $whereClause = $this->_getWhereClause(
+ $_POST['criteriaValues'][$column_index],
+ $_POST['criteriaColumnNames'][$column_index],
+ $_POST['criteriaColumnTypes'][$column_index],
+ $_POST['criteriaColumnCollations'][$column_index], $operator, $unaryFlag,
+ $tmp_geom_func
+ );
+
+ if ($whereClause) {
+ $fullWhereClause[] = $whereClause;
+ }
+ } // end while
+
+ if ($fullWhereClause) {
+ $fullWhereClause = ' WHERE ' . implode(' AND ', $fullWhereClause);
+ }
+ return $fullWhereClause;
+ }
+
+ /**
+ * Generates HTML for a geometrical function column to be displayed in table
+ * search selection form
+ *
+ * @param integer $column_index index of current column in $columnTypes array
+ *
+ * @return string the generated HTML
+ */
+ private function _getGeomFuncHtml($column_index)
+ {
+ $html_output = '';
+ // return if geometrical column is not present
+ if (! $this->_geomColumnFlag) {
+ return $html_output;
+ }
+
+ /**
+ * Displays 'Function' column if it is present
+ */
+ $html_output .= '';
+ $geom_types = PMA_getGISDatatypes();
+ // if a geometry column is present
+ if (in_array($this->_columnTypes[$column_index], $geom_types)) {
+ $html_output .= '';
+ // get the relevant list of GIS functions
+ $funcs = PMA_getGISFunctions($this->_columnTypes[$column_index], true, true);
+ /**
+ * For each function in the list of functions, add an option to select list
+ */
+ foreach ($funcs as $func_name => $func) {
+ $name = isset($func['display']) ? $func['display'] : $func_name;
+ $html_output .= ''
+ . htmlspecialchars($name) . ' ';
+ }
+ $html_output .= ' ';
+ } else {
+ $html_output .= ' ';
+ }
+ $html_output .= ' ';
+ return $html_output;
+ }
+
+ /**
+ * Generates formatted HTML for extra search options in table search form
+ *
+ * @return string the generated HTML
+ */
+ private function _getOptions()
+ {
+ $html_output = '';
+ $html_output .= PMA_getDivForSliderEffect('searchoptions', __('Options'));
+ /**
+ * Displays columns select list for selecting distinct columns in the search
+ */
+ $html_output .= ''
+ . '' . __('Select columns (at least one):') . ' '
+ . '';
+ // Displays the list of the fields
+ foreach ($this->_columnNames as $each_field) {
+ $html_output .= ' '
+ . '' . htmlspecialchars($each_field)
+ . ' ' . "\n";
+ } // end for
+ $html_output .= ' '
+ . ' '
+ . 'DISTINCT ';
+
+ /**
+ * Displays input box for custom 'Where' clause to be used in the search
+ */
+ $html_output .= ''
+ . '' . '' . __('Or') . ' '
+ . __('Add search conditions (body of the "where" clause):') . ' ';
+ $html_output .= PMA_showMySQLDocu('SQL-Syntax', 'Functions');
+ $html_output .= ' ';
+ $html_output .= ' ';
+
+ /**
+ * Displays option of changing default number of rows displayed per page
+ */
+ $html_output .= ''
+ . '' . __('Number of rows per page') . ' '
+ . ' '
+ . ' ';
+
+ /**
+ * Displays option for ordering search results by a column value (Asc or Desc)
+ */
+ $html_output .= ''
+ . '' . __('Display order:') . ' '
+ . ' ';
+ foreach ($this->_columnNames as $each_field) {
+ $html_output .= ' '
+ . ''
+ . htmlspecialchars($each_field) . ' ' . "\n";
+ } // end for
+ $html_output .= ' ';
+ $choices = array(
+ 'ASC' => __('Ascending'),
+ 'DESC' => __('Descending')
+ );
+ $html_output .= PMA_getRadioFields(
+ 'order', $choices, 'ASC', false, true, "formelement"
+ );
+ unset($choices);
+
+ $html_output .= ' ';
+ return $html_output;
+ }
+
+ /**
+ * Other search criteria like data label
+ * (for tbl_zoom_select.php)
+ *
+ * @param array $dataLabel Label for points in zoom plot
+ *
+ * @return string the generated html
+ */
+ private function _getOptionsZoom($dataLabel)
+ {
+ $html_output = '';
+ $html_output .= '
';
+ return $html_output;
+ }
+
+ /**
+ * Provides a column's type, collation, operators list, and crietria value
+ * to display in table search form
+ *
+ * @param integer $search_index Row number in table search form
+ * @param integer $column_index Column index in ColumnNames array
+ *
+ * @return array Array contaning column's properties
+ */
+ public function getColumnProperties($search_index, $column_index)
+ {
+ $selected_operator = (isset($_POST['criteriaColumnOperators'])
+ ? $_POST['criteriaColumnOperators'][$search_index] : '');
+ $entered_value = (isset($_POST['criteriaValues'])
+ ? $_POST['criteriaValues'] : '');
+ $titles['Browse'] = PMA_getIcon('b_browse.png', __('Browse foreign values'));
+ //Gets column's type and collation
+ $type = $this->_columnTypes[$column_index];
+ $collation = $this->_columnCollations[$column_index];
+ //Gets column's comparison operators depending on column type
+ $func = '
';
+ $func .= $GLOBALS['PMA_Types']->getTypeOperatorsHtml(
+ preg_replace('@\(.*@s', '', $this->_columnTypes[$column_index]),
+ $this->_columnNullFlags[$column_index], $selected_operator
+ );
+ $func .= ' ';
+ //Gets link to browse foreign data(if any) and criteria inputbox
+ $foreignData = PMA_getForeignData(
+ $this->_foreigners, $this->_columnNames[$column_index], false, '', ''
+ );
+ $value = $this->_getInputbox(
+ $foreignData, $this->_columnNames[$column_index], $type, $search_index,
+ $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], $entered_value
+ );
+ return array(
+ 'type' => $type,
+ 'collation' => $collation,
+ 'func' => $func,
+ 'value' => $value
+ );
+ }
+
+ /**
+ * Provides the search form's table row in case of Normal Search
+ * (for tbl_select.php)
+ *
+ * @return string the generated table row
+ */
+ private function _getRowsNormal()
+ {
+ $odd_row = true;
+ $html_output = '';
+ // for every column present in table
+ for ($column_index = 0; $column_index < count($this->_columnNames); $column_index++) {
+ $html_output .= '
';
+ $odd_row = !$odd_row;
+ //If 'Function' column is present
+ $html_output .= $this->_getGeomFuncHtml($column_index);
+ //Displays column's name, type, collation and value
+ $html_output .= '' . htmlspecialchars($this->_columnNames[$column_index])
+ . ' ';
+ $properties = $this->getColumnProperties($column_index, $column_index);
+ $html_output .= '' . $properties['type'] . ' ';
+ $html_output .= '' . $properties['collation'] . ' ';
+ $html_output .= '' . $properties['func'] . ' ';
+ $html_output .= '' . $properties['value'] . ' ';
+ $html_output .= ' ';
+ //Displays hidden fields
+ $html_output .= '
';
+ $html_output .= ' ';
+ $html_output .= ' ';
+ $html_output .= ' ';
+ } // end for
+
+ return $html_output;
+ }
+
+ /**
+ * Provides the search form's table row in case of Zoom Search
+ * (for tbl_zoom_select.php)
+ *
+ * @return string the generated table row
+ */
+ private function _getRowsZoom()
+ {
+ $odd_row = true;
+ $html_output = '';
+ /**
+ * Get already set search criteria (if any)
+ */
+
+ //Displays column rows for search criteria input
+ for ($i = 0; $i < 4; $i++) {
+ //After X-Axis and Y-Axis column rows, display additional criteria option
+ if ($i == 2) {
+ $html_output .= '
';
+ $html_output .= __("Additional search criteria");
+ $html_output .= ' ';
+ }
+ $html_output .= '
';
+ $odd_row = ! $odd_row;
+ //Select options for column names
+ $html_output .= '';
+ $html_output .= '' . __('None')
+ . ' ';
+ for ($j = 0 ; $j < count($this->_columnNames); $j++) {
+ if (isset($_POST['criteriaColumnNames'][$i])
+ && $_POST['criteriaColumnNames'][$i] == htmlspecialchars($this->_columnNames[$j])
+ ) {
+ $html_output .= ''
+ . htmlspecialchars($this->_columnNames[$j]) . ' ';
+ } else {
+ $html_output .= ''
+ . htmlspecialchars($this->_columnNames[$j]) . ' ';
+ }
+ }
+ $html_output .= ' ';
+ if (isset($_POST['criteriaColumnNames'])
+ && $_POST['criteriaColumnNames'][$i] != 'pma_null'
+ ) {
+ $key = array_search($_POST['criteriaColumnNames'][$i], $this->_columnNames);
+ $properties = $this->getColumnProperties($i, $key);
+ $type[$i] = $properties['type'];
+ $collation[$i] = $properties['collation'];
+ $func[$i] = $properties['func'];
+ $value[$i] = $properties['value'];
+ }
+ //Column type
+ $html_output .= '' . (isset($type[$i]) ? $type[$i] : '') . ' ';
+ //Column Collation
+ $html_output .= '' . (isset($collation[$i]) ? $collation[$i] : '')
+ . ' ';
+ //Select options for column operators
+ $html_output .= '' . (isset($func[$i]) ? $func[$i] : '') . ' ';
+ //Inputbox for search criteria value
+ $html_output .= '' . (isset($value[$i]) ? $value[$i] : '') . ' ';
+ $html_output .= ' ';
+ //Displays hidden fields
+ $html_output .= '
';
+ $html_output .= ' ';
+ $html_output .= ' ';
+ }//end for
+ return $html_output;
+ }
+
+ /**
+ * Generates HTML for displaying fields table in search form
+ *
+ * @return string the generated HTML
+ */
+ private function _getFieldsTableHtml()
+ {
+ $html_output = '';
+ $html_output .= '
_searchType == 'zoom' ? ' id="tableFieldsId"' : '') . '>';
+ $html_output .= $this->_getTableHeader();
+ $html_output .= '';
+
+ if ($this->_searchType == 'zoom') {
+ $html_output .= $this->_getRowsZoom();
+ } else {
+ $html_output .= $this->_getRowsNormal();
+ }
+
+ $html_output .= '
';
+ return $html_output;
+ }
+
+ /**
+ * Provides the form tag for table search form
+ * (normal search or zoom search)
+ *
+ * @param string $goto Goto URL
+ *
+ * @return string the HTML for form tag
+ */
+ private function _getFormTag($goto)
+ {
+ $html_output = '';
+ $scriptName = ($this->_searchType == 'zoom' ? 'tbl_zoom_select.php' : 'tbl_select.php');
+ $formId = ($this->_searchType == 'zoom' ? 'zoom_search_form' : 'tbl_search_form');
+
+ $html_output .= '
';
+ if ($this->_searchType == 'zoom') {
+ $html_output = '
'
+ . $html_output . '';
+ } else {
+ $html_output .= '
';
+ }
+ return $html_output;
+ }
+
+ /**
+ * Provides form for displaying point data and also the scatter plot
+ * (for tbl_zoom_select.php)
+ *
+ * @param string $goto Goto URL
+ * @param array $data Array containing SQL query data
+ *
+ * @return string form's html
+ */
+ public function getZoomResultsForm($goto, $data)
+ {
+ $html_output = '';
+ $titles['Browse'] = PMA_getIcon('b_browse.png', __('Browse foreign values'));
+ $html_output .= '
';
+ return $html_output;
+ }
+}
+?>
diff --git a/libraries/Theme.class.php b/libraries/Theme.class.php
index cdb91b5334..4658cb67da 100644
--- a/libraries/Theme.class.php
+++ b/libraries/Theme.class.php
@@ -429,35 +429,39 @@ class PMA_Theme
}
/**
- * prints out the preview for this theme
+ * Renders the preview for this theme
*
- * @return void
+ * @return string
* @access public
*/
- public function printPreview()
+ public function getPrintPreview()
{
- echo '
';
+ return $retval;
}
/**
diff --git a/libraries/Theme_Manager.class.php b/libraries/Theme_Manager.class.php
index 3aa286c119..2ecfb05c6a 100644
--- a/libraries/Theme_Manager.class.php
+++ b/libraries/Theme_Manager.class.php
@@ -400,16 +400,18 @@ class PMA_Theme_Manager
}
/**
- * prints out preview for every theme
+ * Renders the previews for all themes
*
- * @return void
+ * @return string
* @access public
*/
- public function printPreviews()
+ public function getPrintPreviews()
{
+ $retval = '';
foreach ($this->themes as $each_theme) {
- $each_theme->printPreview();
+ $retval .= $each_theme->getPrintPreview();
} // end 'open themes'
+ return $retval;
}
/**
diff --git a/libraries/auth/config.auth.lib.php b/libraries/auth/config.auth.lib.php
index fbe39e7c8b..da81d5c73a 100644
--- a/libraries/auth/config.auth.lib.php
+++ b/libraries/auth/config.auth.lib.php
@@ -68,21 +68,18 @@ function PMA_auth_set_user()
function PMA_auth_fails()
{
$conn_error = PMA_DBI_getError();
- if (!$conn_error) {
+ 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';
- ?>
+ $response = PMA_Response::getInstance();
+ $response->getFooter()->setMinimal();
+ $header = $response->getHeader();
+ $header->setTitle(__('Access denied'));
+ $header->disableMenu();
-
-
-
+?>
@@ -91,9 +88,7 @@ function PMA_auth_fails()
' . "\n";
- include './libraries/footer.inc.php';
+ exit;
return true;
} // end of the 'PMA_auth_fails()' function
diff --git a/libraries/auth/cookie.auth.lib.php b/libraries/auth/cookie.auth.lib.php
index 0d1c48533a..c4f5d2fc35 100644
--- a/libraries/auth/cookie.auth.lib.php
+++ b/libraries/auth/cookie.auth.lib.php
@@ -130,6 +130,17 @@ function PMA_auth()
{
global $conn_error;
+ $response = PMA_Response::getInstance();
+ if ($response->isAjax()) {
+ $response->isSuccess(false);
+ if (! empty($conn_error)) {
+ $response->addJSON('message', $conn_error);
+ } else {
+ $response->addJSON('message', PMA_Message::error(__('Your session has expired. Please login again.')));
+ }
+ exit;
+ }
+
/* Perform logout to custom URL */
if (! empty($_REQUEST['old_usr'])
&& ! empty($GLOBALS['cfg']['Server']['LogoutURL'])
@@ -154,20 +165,13 @@ function PMA_auth()
$cell_align = ($GLOBALS['text_dir'] == 'ltr') ? 'left' : 'right';
- // Defines the charset to be used
- header('Content-Type: text/html; charset=utf-8');
+ $response->getFooter()->setMinimal();
+ $header = $response->getHeader();
+ $header->setBodyId('loginform');
+ $header->setTitle('phpMyAdmin');
+ $header->disableMenu();
+ $header->disableWarnings();
- /* 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';
- ?>
-
-
-
-
- ' . $page_title . ''
+ 'phpMyAdmin '
);
?>
@@ -306,13 +310,11 @@ function PMA_auth()
-
-