/phpmyadmin/libraries/DisplayResults.class.php
PHP | 5769 lines | 3321 code | 858 blank | 1590 comment | 601 complexity | 7abde8c08b12edb0e43917c75c4d827e MD5 | raw file
Possible License(s): Apache-2.0, AGPL-1.0, GPL-2.0, LGPL-3.0, BSD-3-Clause, Unlicense, MPL-2.0, GPL-3.0, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- <?php
- /* vim: set expandtab sw=4 ts=4 sts=4: */
- /**
- * Hold the PMA_DisplayResults class
- *
- * @package PhpMyAdmin
- */
- if (! defined('PHPMYADMIN')) {
- exit;
- }
- require_once './libraries/transformations.lib.php';
- /**
- * Handle all the functionalities related to displaying results
- * of sql queries, stored procedure, browsing sql processes or
- * displaying binary log.
- *
- * @package PhpMyAdmin
- */
- class PMA_DisplayResults
- {
- // Define constants
- const NO_EDIT_OR_DELETE = 'nn';
- const UPDATE_ROW = 'ur';
- const DELETE_ROW = 'dr';
- const KILL_PROCESS = 'kp';
- const POSITION_LEFT = 'left';
- const POSITION_RIGHT = 'right';
- const POSITION_BOTH = 'both';
- const POSITION_NONE = 'none';
- const PLACE_TOP_DIRECTION_DROPDOWN = 'top_direction_dropdown';
- const PLACE_BOTTOM_DIRECTION_DROPDOWN = 'bottom_direction_dropdown';
- const DISPLAY_FULL_TEXT = 'F';
- const DISPLAY_PARTIAL_TEXT = 'P';
- const HEADER_FLIP_TYPE_AUTO = 'auto';
- const HEADER_FLIP_TYPE_CSS = 'css';
- const HEADER_FLIP_TYPE_FAKE = 'fake';
- const DATE_FIELD = 'date';
- const DATETIME_FIELD = 'datetime';
- const TIMESTAMP_FIELD = 'timestamp';
- const TIME_FIELD = 'time';
- const STRING_FIELD = 'string';
- const GEOMETRY_FIELD = 'geometry';
- const BLOB_FIELD = 'BLOB';
- const BINARY_FIELD = 'BINARY';
- const RELATIONAL_KEY = 'K';
- const RELATIONAL_DISPLAY_COLUMN = 'D';
- const GEOMETRY_DISP_GEOM = 'GEOM';
- const GEOMETRY_DISP_WKT = 'WKT';
- const GEOMETRY_DISP_WKB = 'WKB';
- const SMART_SORT_ORDER = 'SMART';
- const ASCENDING_SORT_DIR = 'ASC';
- const DESCENDING_SORT_DIR = 'DESC';
- const TABLE_TYPE_INNO_DB = 'InnoDB';
- const ALL_ROWS = 'all';
- const QUERY_TYPE_SELECT = 'SELECT';
- const ROUTINE_PROCEDURE = 'procedure';
- const ROUTINE_FUNCTION = 'function';
- const ACTION_LINK_CONTENT_ICONS = 'icons';
- const ACTION_LINK_CONTENT_TEXT = 'text';
- // Declare global fields
- /** array with properties of the class */
- private $_property_array = array(
- /** string Database name */
- 'db' => null,
- /** string Table name */
- 'table' => null,
- /** string the URL to go back in case of errors */
- 'goto' => null,
- /** string the SQL query */
- 'sql_query' => null,
- /**
- * integer the total number of rows returned by the SQL query without any
- * appended "LIMIT" clause programmatically
- */
- 'unlim_num_rows' => null,
- /** array meta information about fields */
- 'fields_meta' => null,
- /** boolean */
- 'is_count' => null,
- /** integer */
- 'is_export' => null,
- /** boolean */
- 'is_func' => null,
- /** integer */
- 'is_analyse' => null,
- /** integer the total number of rows returned by the SQL query */
- 'num_rows' => null,
- /** integer the total number of fields returned by the SQL query */
- 'fields_cnt' => null,
- /** double time taken for execute the SQL query */
- 'querytime' => null,
- /** string path for theme images directory */
- 'pma_theme_image' => null,
- /** string */
- 'text_dir' => null,
- /** boolean */
- 'is_maint' => null,
- /** boolean */
- 'is_explain' => null,
- /** boolean */
- 'is_show' => null,
- /** boolean */
- 'is_browse_distinct' => null,
- /** array table definitions */
- 'showtable' => null,
- /** string */
- 'printview' => null,
- /** string URL query */
- 'url_query' => null,
- /** array column names to highlight */
- 'highlight_columns' => null,
- /** array holding various display information */
- 'display_params' => null,
- /** array mime types information of fields */
- 'mime_map' => null,
- /** boolean */
- 'editable' => null,
- /** random unique ID to distinguish result set */
- 'unique_id' => null,
- /** where clauses for each row, each table in the row */
- 'whereClauseMap' => array(),
- );
- /**
- * This variable contains the column transformation information
- * for some of the system databases.
- * One element of this array represent all relevant columns in all tables in
- * one specific database
- */
- public $transformation_info;
- /**
- * Get any property of this class
- *
- * @param string $property name of the property
- *
- * @return mixed|void if property exist, value of the relevant property
- */
- public function __get($property)
- {
- if (array_key_exists($property, $this->_property_array)) {
- return $this->_property_array[$property];
- }
- }
- /**
- * Set values for any property of this class
- *
- * @param string $property name of the property
- * @param mixed $value value to set
- *
- * @return void
- */
- public function __set($property, $value)
- {
- if (array_key_exists($property, $this->_property_array)) {
- $this->_property_array[$property] = $value;
- }
- }
- /**
- * Constructor for PMA_DisplayResults class
- *
- * @param string $db the database name
- * @param string $table the table name
- * @param string $goto the URL to go back in case of errors
- * @param string $sql_query the SQL query
- *
- * @access public
- */
- public function __construct($db, $table, $goto, $sql_query)
- {
- $this->_setDefaultTransformations();
- $this->__set('db', $db);
- $this->__set('table', $table);
- $this->__set('goto', $goto);
- $this->__set('sql_query', $sql_query);
- $this->__set('unique_id', rand());
- }
- /**
- * Sets default transformations for some columns
- *
- * @return void
- */
- private function _setDefaultTransformations()
- {
- $json_highlighting_data = array(
- 'libraries/plugins/transformations/output/Text_Plain_Json.class.php',
- 'Text_Plain_Json',
- 'Text_Plain'
- );
- $sql_highlighting_data = array(
- 'libraries/plugins/transformations/output/Text_Plain_Sql.class.php',
- 'Text_Plain_Sql',
- 'Text_Plain'
- );
- $blob_sql_highlighting_data = array(
- 'libraries/plugins/transformations/output/Text_Octetstream_Sql.class.php',
- 'Text_Octetstream_Sql',
- 'Text_Octetstream'
- );
- $link_data = array(
- 'libraries/plugins/transformations/Text_Plain_Link.class.php',
- 'Text_Plain_Link',
- 'Text_Plain'
- );
- $this->transformation_info = array(
- 'information_schema' => array(
- 'events' => array(
- 'event_definition' => $sql_highlighting_data
- ),
- 'processlist' => array(
- 'info' => $sql_highlighting_data
- ),
- 'routines' => array(
- 'routine_definition' => $sql_highlighting_data
- ),
- 'triggers' => array(
- 'action_statement' => $sql_highlighting_data
- ),
- 'views' => array(
- 'view_definition' => $sql_highlighting_data
- )
- ),
- 'mysql' => array(
- 'event' => array(
- 'body' => $blob_sql_highlighting_data,
- 'body_utf8' => $blob_sql_highlighting_data
- ),
- 'general_log' => array(
- 'argument' => $sql_highlighting_data
- ),
- 'help_category' => array(
- 'url' => $link_data
- ),
- 'help_topic' => array(
- 'example' => $sql_highlighting_data,
- 'url' => $link_data
- ),
- 'proc' => array(
- 'param_list' => $blob_sql_highlighting_data,
- 'returns' => $blob_sql_highlighting_data,
- 'body' => $blob_sql_highlighting_data,
- 'body_utf8' => $blob_sql_highlighting_data
- ),
- 'slow_log' => array(
- 'sql_text' => $sql_highlighting_data
- )
- )
- );
- $cfgRelation = PMA_getRelationsParam();
- if ($cfgRelation['db']) {
- $this->transformation_info[$cfgRelation['db']] = array();
- $relDb = &$this->transformation_info[$cfgRelation['db']];
- if (! empty($cfgRelation['history'])) {
- $relDb[$cfgRelation['history']] = array(
- 'sqlquery' => $sql_highlighting_data
- );
- }
- if (! empty($cfgRelation['bookmark'])) {
- $relDb[$cfgRelation['bookmark']] = array(
- 'query' => $sql_highlighting_data
- );
- }
- if (! empty($cfgRelation['tracking'])) {
- $relDb[$cfgRelation['tracking']] = array(
- 'schema_sql' => $sql_highlighting_data,
- 'data_sql' => $sql_highlighting_data
- );
- }
- if (! empty($cfgRelation['favorite'])) {
- $relDb[$cfgRelation['favorite']] = array(
- 'tables' => $json_highlighting_data
- );
- }
- if (! empty($cfgRelation['recent'])) {
- $relDb[$cfgRelation['recent']] = array(
- 'tables' => $json_highlighting_data
- );
- }
- if (! empty($cfgRelation['savedsearches'])) {
- $relDb[$cfgRelation['savedsearches']] = array(
- 'search_data' => $json_highlighting_data
- );
- }
- if (! empty($cfgRelation['designer_settings'])) {
- $relDb[$cfgRelation['designer_settings']] = array(
- 'settings_data' => $json_highlighting_data
- );
- }
- if (! empty($cfgRelation['table_uiprefs'])) {
- $relDb[$cfgRelation['table_uiprefs']] = array(
- 'prefs' => $json_highlighting_data
- );
- }
- if (! empty($cfgRelation['userconfig'])) {
- $relDb[$cfgRelation['userconfig']] = array(
- 'config_data' => $json_highlighting_data
- );
- }
- if (! empty($cfgRelation['export_templates'])) {
- $relDb[$cfgRelation['export_templates']] = array(
- 'template_data' => $json_highlighting_data
- );
- }
- }
- }
- /**
- * Set properties which were not initialized at the constructor
- *
- * @param integer $unlim_num_rows the total number of rows returned by
- * the SQL query without any appended
- * "LIMIT" clause programmatically
- * @param array $fields_meta meta information about fields
- * @param boolean $is_count statement is SELECT COUNT
- * @param integer $is_export statement contains INTO OUTFILE
- * @param boolean $is_func statement contains a function like SUM()
- * @param integer $is_analyse statement contains PROCEDURE ANALYSE
- * @param integer $num_rows total no. of rows returned by SQL query
- * @param integer $fields_cnt total no.of fields returned by SQL query
- * @param double $querytime time taken for execute the SQL query
- * @param string $pmaThemeImage path for theme images directory
- * @param string $text_dir text direction
- * @param boolean $is_maint statement contains a maintenance command
- * @param boolean $is_explain statement contains EXPLAIN
- * @param boolean $is_show statement contains SHOW
- * @param array $showtable table definitions
- * @param string $printview print view was requested
- * @param string $url_query URL query
- * @param boolean $editable whether the results set is editable
- * @param boolean $is_browse_dist whether browsing distinct values
- *
- * @return void
- *
- * @see sql.php
- */
- public function setProperties(
- $unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
- $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage, $text_dir,
- $is_maint, $is_explain, $is_show, $showtable, $printview, $url_query,
- $editable, $is_browse_dist
- ) {
- $this->__set('unlim_num_rows', $unlim_num_rows);
- $this->__set('fields_meta', $fields_meta);
- $this->__set('is_count', $is_count);
- $this->__set('is_export', $is_export);
- $this->__set('is_func', $is_func);
- $this->__set('is_analyse', $is_analyse);
- $this->__set('num_rows', $num_rows);
- $this->__set('fields_cnt', $fields_cnt);
- $this->__set('querytime', $querytime);
- $this->__set('pma_theme_image', $pmaThemeImage);
- $this->__set('text_dir', $text_dir);
- $this->__set('is_maint', $is_maint);
- $this->__set('is_explain', $is_explain);
- $this->__set('is_show', $is_show);
- $this->__set('showtable', $showtable);
- $this->__set('printview', $printview);
- $this->__set('url_query', $url_query);
- $this->__set('editable', $editable);
- $this->__set('is_browse_distinct', $is_browse_dist);
- } // end of the 'setProperties()' function
- /**
- * Defines the parts to display for a print view
- *
- * @param array $displayParts the parts to display
- *
- * @return array $displayParts the modified display parts
- *
- * @access private
- *
- */
- private function _setDisplayPartsForPrintView($displayParts)
- {
- // set all elements to false!
- $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no edit link
- $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link
- $displayParts['sort_lnk'] = (string) '0';
- $displayParts['nav_bar'] = (string) '0';
- $displayParts['bkm_form'] = (string) '0';
- $displayParts['text_btn'] = (string) '0';
- $displayParts['pview_lnk'] = (string) '0';
- return $displayParts;
- }
- /**
- * Defines the parts to display for a SHOW statement
- *
- * @param array $displayParts the parts to display
- *
- * @return array $displayParts the modified display parts
- *
- * @access private
- *
- */
- private function _setDisplayPartsForShow($displayParts)
- {
- preg_match(
- '@^SHOW[[:space:]]+(VARIABLES|(FULL[[:space:]]+)?'
- . 'PROCESSLIST|STATUS|TABLE|GRANTS|CREATE|LOGS|DATABASES|FIELDS'
- . ')@i',
- $this->__get('sql_query'), $which
- );
- $bIsProcessList = isset($which[1]);
- if ($bIsProcessList) {
- $str = ' ' . strtoupper($which[1]);
- $bIsProcessList = $bIsProcessList
- && strpos($str, 'PROCESSLIST') > 0;
- }
- if ($bIsProcessList) {
- // no edit link
- $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE;
- // "kill process" type edit link
- $displayParts['del_lnk'] = self::KILL_PROCESS;
- } else {
- // Default case -> no links
- // no edit link
- $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE;
- // no delete link
- $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE;
- }
- // Other settings
- $displayParts['sort_lnk'] = (string) '0';
- $displayParts['nav_bar'] = (string) '0';
- $displayParts['bkm_form'] = (string) '1';
- $displayParts['text_btn'] = (string) '1';
- $displayParts['pview_lnk'] = (string) '1';
- return $displayParts;
- }
- /**
- * Defines the parts to display for statements not related to data
- *
- * @param array $displayParts the parts to display
- *
- * @return array $displayParts the modified display parts
- *
- * @access private
- *
- */
- private function _setDisplayPartsForNonData($displayParts)
- {
- // Statement is a "SELECT COUNT", a
- // "CHECK/ANALYZE/REPAIR/OPTIMIZE/CHECKSUM", an "EXPLAIN" one or
- // contains a "PROC ANALYSE" part
- $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE; // no edit link
- $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE; // no delete link
- $displayParts['sort_lnk'] = (string) '0';
- $displayParts['nav_bar'] = (string) '0';
- $displayParts['bkm_form'] = (string) '1';
- if ($this->__get('is_maint')) {
- $displayParts['text_btn'] = (string) '1';
- } else {
- $displayParts['text_btn'] = (string) '0';
- }
- $displayParts['pview_lnk'] = (string) '1';
- return $displayParts;
- }
- /**
- * Defines the parts to display for other statements (probably SELECT)
- *
- * @param array $displayParts the parts to display
- *
- * @return array $displayParts the modified display parts
- *
- * @access private
- *
- */
- private function _setDisplayPartsForSelect($displayParts)
- {
- // Other statements (ie "SELECT" ones) -> updates
- // $displayParts['edit_lnk'], $displayParts['del_lnk'] and
- // $displayParts['text_btn'] (keeps other default values)
- $fields_meta = $this->__get('fields_meta');
- $prev_table = '';
- $displayParts['text_btn'] = (string) '1';
- $number_of_columns = $this->__get('fields_cnt');
- for ($i = 0; $i < $number_of_columns; $i++) {
- $is_link = ($displayParts['edit_lnk'] != self::NO_EDIT_OR_DELETE)
- || ($displayParts['del_lnk'] != self::NO_EDIT_OR_DELETE)
- || ($displayParts['sort_lnk'] != '0');
- // Displays edit/delete/sort/insert links?
- if ($is_link
- && $prev_table != ''
- && $fields_meta[$i]->table != ''
- && $fields_meta[$i]->table != $prev_table
- ) {
- // don't display links
- $displayParts['edit_lnk'] = self::NO_EDIT_OR_DELETE;
- $displayParts['del_lnk'] = self::NO_EDIT_OR_DELETE;
- /**
- * @todo May be problematic with same field names
- * in two joined table.
- */
- // $displayParts['sort_lnk'] = (string) '0';
- if ($displayParts['text_btn'] == '1') {
- break;
- }
- } // end if
- // Always display print view link
- $displayParts['pview_lnk'] = (string) '1';
- if ($fields_meta[$i]->table != '') {
- $prev_table = $fields_meta[$i]->table;
- }
- } // end for
- return $displayParts;
- }
- /**
- * Defines the parts to display for the results of a SQL query
- *
- * @param array $displayParts the parts to display (see a few
- * lines above for explanations)
- * @param integer &$the_total the total number of rows returned by the SQL
- * query without any programmatically appended
- * LIMIT clause
- * (just a copy of $unlim_num_rows if it exists,
- * elsecomputed inside this function)
- *
- * @return array an array with explicit indexes for all the display
- * elements
- *
- * @access private
- *
- * @see getTable()
- */
- private function _setDisplayParts($displayParts, &$the_total)
- {
- // 1. Following variables are needed for use in isset/empty or
- // use with array indexes or safe use in foreach
- $db = $this->__get('db');
- $table = $this->__get('table');
- $unlim_num_rows = $this->__get('unlim_num_rows');
- $num_rows = $this->__get('num_rows');
- $printview = $this->__get('printview');
- // 2. Updates the display parts
- if ($printview == '1') {
- $displayParts = $this->_setDisplayPartsForPrintView($displayParts);
- } elseif ($this->__get('is_count') || $this->__get('is_analyse')
- || $this->__get('is_maint') || $this->__get('is_explain')
- ) {
- $displayParts = $this->_setDisplayPartsForNonData($displayParts);
- } elseif ($this->__get('is_show')) {
- $displayParts = $this->_setDisplayPartsForShow($displayParts);
- } else {
- $displayParts = $this->_setDisplayPartsForSelect($displayParts);
- } // end if..elseif...else
- // 3. Gets the total number of rows if it is unknown
- if (isset($unlim_num_rows) && $unlim_num_rows != '') {
- $the_total = $unlim_num_rows;
- } elseif ((($displayParts['nav_bar'] == '1')
- || ($displayParts['sort_lnk'] == '1'))
- && (/*overload*/mb_strlen($db) && !empty($table))
- ) {
- $the_total = $GLOBALS['dbi']->getTable($db, $table)->countRecords();
- }
- // if for COUNT query, number of rows returned more than 1
- // (may be being used GROUP BY)
- if ($this->__get('is_count') && isset($num_rows) && $num_rows > 1) {
- $displayParts['nav_bar'] = (string) '1';
- $displayParts['sort_lnk'] = (string) '1';
- }
- // 4. If navigation bar or sorting fields names URLs should be
- // displayed but there is only one row, change these settings to
- // false
- if ($displayParts['nav_bar'] == '1' || $displayParts['sort_lnk'] == '1') {
- // - Do not display sort links if less than 2 rows.
- // - For a VIEW we (probably) did not count the number of rows
- // so don't test this number here, it would remove the possibility
- // of sorting VIEW results.
- $_table = new PMA_Table($table, $db);
- if (isset($unlim_num_rows)
- && ($unlim_num_rows < 2)
- && ! $_table->isView()
- ) {
- $displayParts['sort_lnk'] = (string) '0';
- }
- } // end if (3)
- return $displayParts;
- } // end of the 'setDisplayParts()' function
- /**
- * Return true if we are executing a query in the form of
- * "SELECT * FROM <a table> ..."
- *
- * @param array $analyzed_sql_results analyzed sql results
- *
- * @return boolean
- *
- * @access private
- *
- * @see _getTableHeaders(), _getColumnParams()
- */
- private function _isSelect($analyzed_sql_results)
- {
- return ! ($this->__get('is_count')
- || $this->__get('is_export')
- || $this->__get('is_func')
- || $this->__get('is_analyse'))
- && !empty($analyzed_sql_results['select_from'])
- && !empty($analyzed_sql_results['statement']->from)
- && (count($analyzed_sql_results['statement']->from) == 1)
- && !empty($analyzed_sql_results['statement']->from[0]->table);
- }
- /**
- * Get a navigation button
- *
- * @param string $caption iconic caption for button
- * @param string $title text for button
- * @param integer $pos position for next query
- * @param string $html_sql_query query ready for display
- * @param boolean $back whether 'begin' or 'previous'
- * @param string $onsubmit optional onsubmit clause
- * @param string $input_for_real_end optional hidden field for special treatment
- * @param string $onclick optional onclick clause
- *
- * @return string html content
- *
- * @access private
- *
- * @see _getMoveBackwardButtonsForTableNavigation(),
- * _getMoveForwardButtonsForTableNavigation()
- */
- private function _getTableNavigationButton(
- $caption, $title, $pos, $html_sql_query, $back, $onsubmit = '',
- $input_for_real_end = '', $onclick = ''
- ) {
- $caption_output = '';
- if ($back) {
- if (PMA_Util::showIcons('TableNavigationLinksMode')) {
- $caption_output .= $caption;
- }
- if (PMA_Util::showText('TableNavigationLinksMode')) {
- $caption_output .= ' ' . $title;
- }
- } else {
- if (PMA_Util::showText('TableNavigationLinksMode')) {
- $caption_output .= $title;
- }
- if (PMA_Util::showIcons('TableNavigationLinksMode')) {
- $caption_output .= ' ' . $caption;
- }
- }
- $title_output = ' title="' . $title . '"';
- return '<td>'
- . '<form action="sql.php" method="post" ' . $onsubmit . '>'
- . PMA_URL_getHiddenInputs(
- $this->__get('db'), $this->__get('table')
- )
- . '<input type="hidden" name="sql_query" value="'
- . $html_sql_query . '" />'
- . '<input type="hidden" name="pos" value="' . $pos . '" />'
- . '<input type="hidden" name="is_browse_distinct" value="'
- . $this->__get('is_browse_distinct') . '" />'
- . '<input type="hidden" name="goto" value="' . $this->__get('goto')
- . '" />'
- . $input_for_real_end
- . '<input type="submit" name="navig"'
- . ' class="ajax" '
- . 'value="' . $caption_output . '" ' . $title_output . $onclick . ' />'
- . '</form>'
- . '</td>';
- } // end function _getTableNavigationButton()
- /**
- * Possibly return a page selector for table navigation
- *
- * @param string $table_navigation_html the current navigation HTML
- *
- * @return array ($table_navigation_html, $nbTotalPage)
- *
- * @access private
- *
- */
- private function _getHtmlPageSelector($table_navigation_html)
- {
- $pageNow = @floor(
- $_SESSION['tmpval']['pos']
- / $_SESSION['tmpval']['max_rows']
- ) + 1;
- $nbTotalPage = @ceil(
- $this->__get('unlim_num_rows')
- / $_SESSION['tmpval']['max_rows']
- );
- if ($nbTotalPage > 1) {
- $table_navigation_html .= '<td>';
- $_url_params = array(
- 'db' => $this->__get('db'),
- 'table' => $this->__get('table'),
- 'sql_query' => $this->__get('sql_query'),
- 'goto' => $this->__get('goto'),
- 'is_browse_distinct' => $this->__get('is_browse_distinct'),
- );
- //<form> to keep the form alignment of button < and <<
- // and also to know what to execute when the selector changes
- $table_navigation_html .= '<form action="sql.php'
- . PMA_URL_getCommon($_url_params)
- . '" method="post">';
- $table_navigation_html .= PMA_Util::pageselector(
- 'pos',
- $_SESSION['tmpval']['max_rows'],
- $pageNow, $nbTotalPage, 200, 5, 5, 20, 10
- );
- $table_navigation_html .= '</form>'
- . '</td>';
- }
- return array($table_navigation_html, $nbTotalPage);
- }
- /**
- * Get a navigation bar to browse among the results of a SQL query
- *
- * @param integer $pos_next the offset for the "next" page
- * @param integer $pos_prev the offset for the "previous" page
- * @param boolean $is_innodb whether its InnoDB or not
- *
- * @return string html content
- *
- * @access private
- *
- * @see _getTable()
- */
- private function _getTableNavigation(
- $pos_next, $pos_prev, $is_innodb
- ) {
- $table_navigation_html = '';
- // here, using htmlentities() would cause problems if the query
- // contains accented characters
- $html_sql_query = htmlspecialchars($this->__get('sql_query'));
- // Navigation bar
- $table_navigation_html .= '<table class="navigation nospacing nopadding print_ignore">'
- . '<tr>'
- . '<td class="navigation_separator"></td>';
- // Move to the beginning or to the previous page
- if ($_SESSION['tmpval']['pos']
- && ($_SESSION['tmpval']['max_rows'] != self::ALL_ROWS)
- ) {
- $table_navigation_html
- .= $this->_getMoveBackwardButtonsForTableNavigation(
- $html_sql_query, $pos_prev
- );
- } // end move back
- $nbTotalPage = 1;
- //page redirection
- // (unless we are showing all records)
- if ($_SESSION['tmpval']['max_rows'] != self::ALL_ROWS) {
- list(
- $table_navigation_html,
- $nbTotalPage
- ) = $this->_getHtmlPageSelector($table_navigation_html);
- }
- $showing_all = false;
- if ($_SESSION['tmpval']['max_rows'] == self::ALL_ROWS) {
- $showing_all = true;
- }
- // Move to the next page or to the last one
- $endpos = $_SESSION['tmpval']['pos']
- + $_SESSION['tmpval']['max_rows'];
- if (($endpos < $this->__get('unlim_num_rows'))
- && ($this->__get('num_rows') >= $_SESSION['tmpval']['max_rows'])
- && ($_SESSION['tmpval']['max_rows'] != self::ALL_ROWS)
- ) {
- $table_navigation_html
- .= $this->_getMoveForwardButtonsForTableNavigation(
- $html_sql_query, $pos_next, $is_innodb
- );
- } // end move toward
- // show separator if pagination happen
- if ($nbTotalPage > 1) {
- $table_navigation_html
- .= '<td><div class="navigation_separator">|</div></td>';
- }
- // Display the "Show all" button if allowed
- if ($GLOBALS['cfg']['ShowAll'] || ($this->__get('unlim_num_rows') <= 500) ) {
- $table_navigation_html .= $this->_getShowAllCheckboxForTableNavigation(
- $showing_all, $html_sql_query
- );
- $table_navigation_html
- .= '<td><div class="navigation_separator">|</div></td>';
- } // end show all
- $table_navigation_html .= '<td>'
- . '<div class="save_edited hide">'
- . '<input type="submit" value="' . __('Save edited data') . '" />'
- . '<div class="navigation_separator">|</div>'
- . '</div>'
- . '</td>'
- . '<td>'
- . '<div class="restore_column hide">'
- . '<input type="submit" value="' . __('Restore column order') . '" />'
- . '<div class="navigation_separator">|</div>'
- . '</div>'
- . '</td>';
- // if displaying a VIEW, $unlim_num_rows could be zero because
- // of $cfg['MaxExactCountViews']; in this case, avoid passing
- // the 5th parameter to checkFormElementInRange()
- // (this means we can't validate the upper limit
- $table_navigation_html .= '<td class="navigation_goto">';
- $table_navigation_html .= '<form action="sql.php" method="post" '
- . 'onsubmit="return '
- . '(checkFormElementInRange('
- . 'this, '
- . '\'session_max_rows\', '
- . '\''
- . str_replace('\'', '\\\'', __('%d is not valid row number.'))
- . '\', '
- . '1)'
- . ' && '
- . 'checkFormElementInRange('
- . 'this, '
- . '\'pos\', '
- . '\''
- . str_replace('\'', '\\\'', __('%d is not valid row number.'))
- . '\', '
- . '0'
- . (($this->__get('unlim_num_rows') > 0)
- ? ', ' . ($this->__get('unlim_num_rows') - 1)
- : ''
- )
- . ')'
- . ')'
- . '">';
- $table_navigation_html .= PMA_URL_getHiddenInputs(
- $this->__get('db'), $this->__get('table')
- );
- $table_navigation_html .= $this->_getAdditionalFieldsForTableNavigation(
- $html_sql_query
- );
- $table_navigation_html .= '</form>'
- . '</td>'
- . '<td class="navigation_separator"></td>'
- . '<td>'
- . '<span>' . __('Filter rows') . ':</span>'
- . '<input type="text" class="filter_rows"'
- . ' placeholder="' . __('Search this table') . '"'
- . ' data-for="' . $this->__get('unique_id') . '" />'
- . '</td>'
- . '<td class="navigation_separator"></td>'
- . '</tr>'
- . '</table>';
- return $table_navigation_html;
- } // end of the '_getTableNavigation()' function
- /**
- * Prepare move backward buttons - previous and first
- *
- * @param string $html_sql_query the sql encoded by html special characters
- * @param integer $pos_prev the offset for the "previous" page
- *
- * @return string html content
- *
- * @access private
- *
- * @see _getTableNavigation()
- */
- private function _getMoveBackwardButtonsForTableNavigation(
- $html_sql_query, $pos_prev
- ) {
- return $this->_getTableNavigationButton(
- '<<', _pgettext('First page', 'Begin'), 0, $html_sql_query, true
- )
- . $this->_getTableNavigationButton(
- '<', _pgettext('Previous page', 'Previous'), $pos_prev,
- $html_sql_query, true
- );
- } // end of the '_getMoveBackwardButtonsForTableNavigation()' function
- /**
- * Prepare Show All checkbox for table navigation
- *
- * @param bool $showing_all whether all rows are shown currently
- * @param string $html_sql_query the sql encoded by html special characters
- *
- * @return string html content
- *
- * @access private
- *
- * @see _getTableNavigation()
- */
- private function _getShowAllCheckboxForTableNavigation(
- $showing_all, $html_sql_query
- ) {
- return "\n"
- . '<td>'
- . '<form action="sql.php" method="post">'
- . PMA_URL_getHiddenInputs(
- $this->__get('db'), $this->__get('table')
- )
- . '<input type="hidden" name="sql_query" value="'
- . $html_sql_query . '" />'
- . '<input type="hidden" name="pos" value="0" />'
- . '<input type="hidden" name="is_browse_distinct" value="'
- . $this->__get('is_browse_distinct') . '" />'
- . '<input type="hidden" name="session_max_rows" value="'
- . (! $showing_all ? 'all' : $GLOBALS['cfg']['MaxRows']) . '" />'
- . '<input type="hidden" name="goto" value="' . $this->__get('goto')
- . '" />'
- . '<input type="checkbox" name="navig"'
- . ' id="showAll_' . $this->__get('unique_id') . '" class="showAllRows"'
- . (! $showing_all ? '' : ' checked="checked"') . ' value="all" />'
- . '<label for="showAll_' . $this->__get('unique_id') . '">'
- . __('Show all') . '</label>'
- . '</form>'
- . '</td>';
- } // end of the '_getShowAllButtonForTableNavigation()' function
- /**
- * Prepare move forward buttons - next and last
- *
- * @param string $html_sql_query the sql encoded by htmlspecialchars()
- * @param integer $pos_next the offset for the "next" page
- * @param boolean $is_innodb whether it's InnoDB or not
- *
- * @return string $buttons_html html content
- *
- * @access private
- *
- * @see _getTableNavigation()
- */
- private function _getMoveForwardButtonsForTableNavigation(
- $html_sql_query, $pos_next, $is_innodb
- ) {
- // display the Next button
- $buttons_html = $this->_getTableNavigationButton(
- '>',
- _pgettext('Next page', 'Next'),
- $pos_next,
- $html_sql_query,
- false
- );
- // prepare some options for the End button
- if ($is_innodb
- && $this->__get('unlim_num_rows') > $GLOBALS['cfg']['MaxExactCount']
- ) {
- $input_for_real_end = '<input id="real_end_input" type="hidden" '
- . 'name="find_real_end" value="1" />';
- // no backquote around this message
- $onclick = '';
- } else {
- $input_for_real_end = $onclick = '';
- }
- $maxRows = $_SESSION['tmpval']['max_rows'];
- $onsubmit = 'onsubmit="return '
- . ($_SESSION['tmpval']['pos']
- + $maxRows
- < $this->__get('unlim_num_rows')
- && $this->__get('num_rows') >= $maxRows)
- ? 'true'
- : 'false' . '"';
- // display the End button
- $buttons_html .= $this->_getTableNavigationButton(
- '>>',
- _pgettext('Last page', 'End'),
- @((ceil(
- $this->__get('unlim_num_rows')
- / $_SESSION['tmpval']['max_rows']
- )- 1) * $maxRows),
- $html_sql_query, false, $onsubmit, $input_for_real_end, $onclick
- );
- return $buttons_html;
- } // end of the '_getMoveForwardButtonsForTableNavigation()' function
- /**
- * Prepare fields for table navigation
- * Number of rows
- *
- * @param string $html_sql_query the sql encoded by htmlspecialchars()
- *
- * @return string $additional_fields_html html content
- *
- * @access private
- *
- * @see _getTableNavigation()
- */
- private function _getAdditionalFieldsForTableNavigation(
- $html_sql_query
- ) {
- $additional_fields_html = '';
- $additional_fields_html .= '<input type="hidden" name="sql_query" '
- . 'value="' . $html_sql_query . '" />'
- . '<input type="hidden" name="goto" value="' . $this->__get('goto')
- . '" />'
- . '<input type="hidden" name="pos" size="3" value="'
- // Do not change the position when changing the number of rows
- . $_SESSION['tmpval']['pos'] . '" />'
- . '<input type="hidden" name="is_browse_distinct" value="'
- . $this->__get('is_browse_distinct') . '" />' ;
- $numberOfRowsPlaceholder = null;
- if ($_SESSION['tmpval']['max_rows'] == self::ALL_ROWS) {
- $numberOfRowsPlaceholder = __('All');
- }
- $numberOfRowsChoices = array(
- '25' => 25,
- '50' => 50,
- '100' => 100,
- '250' => 250,
- '500' => 500
- );
- $additional_fields_html .= __('Number of rows:') . ' ';
- $additional_fields_html .= PMA_Util::getDropdown(
- 'session_max_rows', $numberOfRowsChoices,
- $_SESSION['tmpval']['max_rows'], '',
- 'autosubmit', $numberOfRowsPlaceholder
- );
- return $additional_fields_html;
- } // end of the '_getAdditionalFieldsForTableNavigation()' function
- /**
- * Get the headers of the results table, for all of the columns
- *
- * @param array $displayParts which elements to display
- * @param array $analyzed_sql_results analyzed sql results
- * @param array $sort_expression sort expression
- * @param string $sort_expression_nodirection sort expression
- * without direction
- * @param string $sort_direction sort direction
- * @param boolean $is_limited_display with limited operations
- * or not
- * @param string $unsorted_sql_query query without the sort part
- *
- * @return string html content
- *
- * @access private
- *
- * @see getTableHeaders()
- */
- private function _getTableHeadersForColumns(
- $displayParts, $analyzed_sql_results, $sort_expression,
- $sort_expression_nodirection, $sort_direction, $is_limited_display,
- $unsorted_sql_query
- ) {
- $html = '';
- // required to generate sort links that will remember whether the
- // "Show all" button has been clicked
- $sql_md5 = md5($this->__get('sql_query'));
- $session_max_rows = $is_limited_display
- ? 0
- : $_SESSION['tmpval']['query'][$sql_md5]['max_rows'];
- // Following variable are needed for use in isset/empty or
- // use with array indexes/safe use in the for loop
- $highlight_columns = $this->__get('highlight_columns');
- $fields_meta = $this->__get('fields_meta');
- // Prepare Display column comments if enabled
- // ($GLOBALS['cfg']['ShowBrowseComments']).
- $comments_map = $this->_getTableCommentsArray($analyzed_sql_results);
- list($col_order, $col_visib) = $this->_getColumnParams($analyzed_sql_results);
- // optimize: avoid calling a method on each iteration
- $number_of_columns = $this->__get('fields_cnt');
- for ($j = 0; $j < $number_of_columns; $j++) {
- // assign $i with the appropriate column order
- $i = $col_order ? $col_order[$j] : $j;
- // See if this column should get highlight because it's used in the
- // where-query.
- $condition_field = (isset($highlight_columns[$fields_meta[$i]->name])
- || isset(
- $highlight_columns[PMA_Util::backquote($fields_meta[$i]->name)])
- )
- ? true
- : false;
- // Prepare comment-HTML-wrappers for each row, if defined/enabled.
- $comments = $this->_getCommentForRow($comments_map, $fields_meta[$i]);
- $display_params = $this->__get('display_params');
- if (($displayParts['sort_lnk'] == '1') && ! $is_limited_display) {
- list($order_link, $sorted_header_html)
- = $this->_getOrderLinkAndSortedHeaderHtml(
- $fields_meta[$i], $sort_expression,
- $sort_expression_nodirection, $i, $unsorted_sql_query,
- $session_max_rows, $comments,
- $sort_direction, $col_visib,
- $col_visib[$j]
- );
- $html .= $sorted_header_html;
- $display_params['desc'][] = ' <th '
- . 'class="draggable'
- . ($condition_field ? ' condition' : '')
- . '" data-column="' . htmlspecialchars($fields_meta[$i]->name)
- . '">' . "\n" . $order_link . $comments . ' </th>' . "\n";
- } else {
- // Results can't be sorted
- $html
- .= $this->_getDraggableClassForNonSortableColumns(
- $col_visib, $col_visib[$j], $condition_field,
- $fields_meta[$i], $comments
- );
- $display_params['desc'][] = ' <th '
- . 'class="draggable'
- . ($condition_field ? ' condition"' : '')
- . '" data-column="' . htmlspecialchars($fields_meta[$i]->name)
- . '">' . ' '
- . htmlspecialchars($fields_meta[$i]->name)
- . $comments . ' </th>';
- } // end else
- $this->__set('display_params', $display_params);
- } // end for
- return $html;
- }
- /**
- * Get the headers of the results table
- *
- * @param array &$displayParts which elements to display
- * @param array $analyzed_sql_results analyzed sql results
- * @param array $sort_expression sort expression
- * @param string $sort_expression_nodirection sort expression
- * without direction
- * @param string $sort_direction sort direction
- * @param boolean $is_limited_display with limited operations
- * or not
- *
- * @return string html content
- *
- * @access private
- *
- * @see getTable()
- */
- private function _getTableHeaders(
- &$displayParts, $analyzed_sql_results, $sort_expression = array(),
- $sort_expression_nodirection = '', $sort_direction = '',
- $is_limited_display = false
- ) {
- $table_headers_html = '';
- // Needed for use in isset/empty or
- // use with array indexes/safe use in foreach
- $printview = $this->__get('printview');
- $display_params = $this->__get('display_params');
- // can the result be sorted?
- if ($displayParts['sort_lnk'] == '1') {
- // At this point, $sort_expression is an array but we only verify
- // the first element in case we could find that the table is
- // sorted by one of the choices listed in the
- // "Sort by key" drop-down
- list($unsorted_sql_query, $drop_down_html)
- = $this->_getUnsortedSqlAndSortByKeyDropDown(
- $analyzed_sql_results, $sort_expression[0]
- );
- $table_headers_html .= $drop_down_html;
- } else {
- $unsorted_sql_query = '';
- }
- // Output data needed for grid editing
- $table_headers_html .= '<input class="save_cells_at_once" type="hidden"'
- . ' value="' . $GLOBALS['cfg']['SaveCellsAtOnce'] . '" />'
- . '<div class="common_hidden_inputs">'
- . PMA_URL_getHiddenInputs(
- $this->__get('db'), $this->__get('table')
- )
- . '</div>';
- // Output data needed for column reordering and show/hide column
- if ($this->_isSelect($analyzed_sql_results)) {
- $table_headers_html .= $this->_getDataForResettingColumnOrder();
- }
- $display_params['emptypre'] = 0;
- $display_params['emptyafter'] = 0;
- $display_params['textbtn'] = '';
- $full_or_partial_text_link = null;
- $this->__set('display_params', $display_params);
- // Display options (if we are not in print view)
- if (! (isset($printview) && ($printview == '1')) && ! $is_limited_display) {
- $table_headers_html .= $this->_getOptionsBlock();
- // prepare full/partial text button or link
- $full_or_partial_text_link = $this->_getFullOrPartialTextButtonOrLink();
- }
- // Start of form for multi-rows edit/delete/export
- $table_headers_html .= $this->_getFormForMultiRowOperations(
- $displayParts['del_lnk']
- );
- // 1. Set $colspan and generate html with full/partial
- // text button or link
- list($colspan, $button_html)
- = $this->_getFieldVisibilityParams(
- $displayParts, $full_or_partial_text_link
- );
- $table_headers_html .= $button_html;
- // 2. Displays the fields' name
- // 2.0 If sorting links should be used, checks if the query is a "JOIN"
- // statement (see 2.1.3)
- // See if we have to highlight any header fields of a WHERE query.
- // Uses SQL-Parser results.
- $this->_setHighlightedColumnGlobalField($analyzed_sql_results);
- // Get the headers for all of the columns
- $table_headers_html .= $this->_getTableHeadersForColumns(
- $displayParts, $analyzed_sql_results, $sort_expression,
- $sort_expression_nodirection, $sort_direction,
- $is_limited_display, $unsorted_sql_query
- );
- // Display column at rightside - checkboxes or empty column
- if (! $printview) {
- $table_headers_html .= $this->_getColumnAtRightSide(
- $displayParts, $full_or_partial_text_link, $colspan
- );
- }
- $table_headers_html .= '</tr>' . '</thead>';
- return $table_headers_html;
- } // end of the '_getTableHeaders()' function
- /**
- * Prepare unsorted sql query and sort by key drop down
- *
- * @param array $analyzed_sql_results analyzed sql results
- * @param string $sort_expression sort expression
- *
- * @return array two element array - $unsorted_sql_query, $drop_down_html
- *
- * @access private
- *
- * @see _getTableHeaders()
- */
- private function _getUnsortedSqlAndSortByKeyDropDown(
- $analyzed_sql_results, $sort_expression
- ) {
- $drop_down_html = '';
- $unsorted_sql_query = SqlParser\Utils\Query::replaceClause(
- $analyzed_sql_results['statement'],
- $analyzed_sql_results['parser']->list,
- 'ORDER BY',
- ''
- );
- // Data is sorted by indexes only if it there is only one table.
- if ($this->_isSelect($analyzed_sql_results)) {
- // grab indexes data:
- $indexes = PMA_Index::getFromTable(
- $this->__get('table'),
- $this->__get('db')
- );
- // do we have any index?
- if (! empty($indexes)) {
- $drop_down_html = $this->_getSortByKeyDropDown(
- $indexes, $sort_expression,
- $unsorted_sql_query
- );
- }
- }
- return array($uns…
Large files files are truncated, but you can click here to view the full file