| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478 |
- <?php
- /* vim: set expandtab sw=4 ts=4 sts=4: */
- /**
- * Handles Table search and Zoom search
- *
- * @package PhpMyAdmin
- */
- if (! defined('PHPMYADMIN')) {
- exit;
- }
- /**
- * Class to handle normal-search
- * and zoom-search in a table
- *
- * @package PhpMyAdmin
- */
- class PMA_TableSearch
- {
- /**
- * Database name
- *
- * @access private
- * @var string
- */
- private $_db;
- /**
- * Table name
- *
- * @access private
- * @var string
- */
- private $_table;
- /**
- * Normal search or Zoom search
- *
- * @access private
- * @var string
- */
- private $_searchType;
- /**
- * Names of columns
- *
- * @access private
- * @var array
- */
- private $_columnNames;
- /**
- * Types of columns
- *
- * @access private
- * @var array
- */
- private $_columnTypes;
- /**
- * Collations of columns
- *
- * @access private
- * @var array
- */
- private $_columnCollations;
- /**
- * Null Flags of columns
- *
- * @access private
- * @var array
- */
- private $_columnNullFlags;
- /**
- * Whether a geometry column is present
- *
- * @access private
- * @var boolean
- */
- private $_geomColumnFlag;
- /**
- * Foreign Keys
- *
- * @access private
- * @var array
- */
- private $_foreigners;
- /**
- * Public Constructor
- *
- * @param string $db Database name
- * @param string $table Table name
- * @param string $searchType Whether normal or zoom search
- */
- public function __construct($db, $table, $searchType)
- {
- $this->_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();
- }
- /**
- * 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 void
- */
- private function _loadTableInfo()
- {
- // Gets the list and number of columns
- $columns = $GLOBALS['dbi']->getColumns(
- $this->_db, $this->_table, null, true
- );
- // Get details about the geometry fucntions
- $geom_types = PMA_Util::getGISDatatypes();
- foreach ($columns as $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 string 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 = '<th>' . __('Function') . '</th>';
- }
- return '<thead>
- <tr>' . $func . '<th>' . __('Column') . '</th>
- <th>' . __('Type') . '</th>
- <th>' . __('Collation') . '</th>
- <th>' . __('Operator') . '</th>
- <th>' . __('Value') . '</th>
- </tr>
- </thead>';
- }
- /**
- * Returns an array with necessary configurations to create
- * sub-tabs in the table_select page.
- *
- * @return array Array containing configuration (icon, text, link, id, args)
- * of sub-tabs
- */
- 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';
- $subtabs['replace']['icon'] = 'b_find_replace.png';
- $subtabs['replace']['link'] = 'tbl_find_replace.php';
- $subtabs['replace']['text'] = __('Find and Replace');
- $subtabs['replace']['id'] = 'find_replace_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 string HTML elements.
- */
- private function _getGeometricalInputBox($column_index, $in_fbs)
- {
- $html_output = '<input type="text" name="criteriaValues['
- . $column_index . ']"'
- . ' size="40" class="textfield" id="field_' . $column_index . '" />';
- if ($in_fbs) {
- $edit_url = 'gis_data_editor.php?' . PMA_URL_getCommon();
- $edit_str = PMA_Util::getIcon('b_edit.png', __('Edit/Insert'));
- $html_output .= '<span class="open_search_gis_editor">';
- $html_output .= PMA_Util::linkOrButton(
- $edit_url, $edit_str, array(), false, false, '_blank'
- );
- $html_output .= '</span>';
- }
- 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 string 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 .= '<select name="criteriaValues[' . $column_index . ']"'
- . ' id="' . $column_id . $column_index . '">';
- $html_output .= PMA_foreignDropdown(
- $foreignData['disp_row'], $foreignData['foreign_field'],
- $foreignData['foreign_display'], '', $foreignMaxLimit
- );
- $html_output .= '</select>';
- } elseif ($foreignData['foreign_link'] == true) {
- $html_output .= '<input type="text" id="' . $column_id
- . $column_index . '"'
- . ' name="criteriaValues[' . $column_index . ']" id="field_'
- . md5($column_name) . '[' . $column_index . ']" class="textfield"'
- . (isset($criteriaValues[$column_index])
- && is_string($criteriaValues[$column_index])
- ? (' value="' . $criteriaValues[$column_index] . '"')
- : '')
- . ' />';
- $html_output .= <<<EOT
- <a target="_blank" onclick="window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes'); return false" href="browse_foreigners.php?
- EOT;
- $html_output .= '' . PMA_URL_getCommon($this->_db, $this->_table)
- . '&field=' . urlencode($column_name) . '&fieldkey='
- . $column_index . '&fromsearch=1"';
- if ($in_zoom_search_edit) {
- $html_output .= ' class="browse_foreign"';
- }
- $html_output .= '>' . str_replace("'", "\'", $titles['Browse']) . '</a>';
- }
- 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 string 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 .= '<select name="criteriaValues[' . ($column_index)
- . ']" id="' . $column_id . $column_index . '">';
- } else {
- $html_output .= '<select name="criteriaValues[' . $column_index . ']"'
- . ' id="' . $column_id . $column_index . '" multiple="multiple"'
- . ' size="' . min(3, $cnt_value) . '">';
- }
- //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 .= '<option value="' . $value[$j] . '" Selected>'
- . $value[$j] . '</option>';
- } else {
- $html_output .= '<option value="' . $value[$j] . '">'
- . $value[$j] . '</option>';
- }
- } // end for
- $html_output .= '</select>';
- 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 foreign 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_Util::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 .= '<input type="text" name="criteriaValues[' . $column_index . ']"'
- . ' size="40" class="' . $the_class . '" id="'
- . $column_id . $column_index . '"'
- . (isset($criteriaValues[$column_index])
- && is_string($criteriaValues[$column_index])
- ? (' value="' . $criteriaValues[$column_index] . '"')
- : '')
- . ' />';
- }
- return $str;
- }
- /**
- * Return the where clause in case column's type is ENUM.
- *
- * @param mixed $criteriaValues Search criteria input
- * @param string $func_type Search function/operator
- *
- * @return string part of where clause.
- */
- private function _getEnumWhereClause($criteriaValues, $func_type)
- {
- 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_Util::sqlAddSlashes($criteriaValues[0]) . '\'';
- for ($e = 1; $e < $enum_selected_count; $e++) {
- $enum_where .= ', \''
- . PMA_Util::sqlAddSlashes($criteriaValues[$e]) . '\'';
- }
- return ' ' . $func_type . ' ' . $parens_open
- . $enum_where . $parens_close;
- }
- /**
- * 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 function/operator
- * @param string $types Type of the field
- * @param bool $geom_func Whether geometry functions should be applied
- *
- * @return string part of where clause.
- */
- private function _getGeomWhereClause($criteriaValues, $names,
- $func_type, $types, $geom_func = null
- ) {
- $geom_unary_functions = array(
- 'IsEmpty' => 1,
- 'IsSimple' => 1,
- 'IsRing' => 1,
- 'IsClosed' => 1,
- );
- $where = '';
- // Get details about the geometry functions
- $geom_funcs = PMA_Util::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_Util::backquote($names) . ')';
- } else {
- // If the function takes two parameters
- // create gis data from the criteria input
- $gis_data = PMA_Util::createGISData($criteriaValues);
- $where = $geom_func . '(' . PMA_Util::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_Util::getGISDatatypes())
- && ! empty($criteriaValues)
- ) {
- // create gis data from the criteria input
- $gis_data = PMA_Util::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 function/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, $types, $geom_func
- );
- }
- $backquoted_name = PMA_Util::backquote($names);
- $where = '';
- if ($unaryFlag) {
- $where = $backquoted_name . ' ' . $func_type;
- } elseif (strncasecmp($types, 'enum', 4) == 0 && ! empty($criteriaValues)) {
- $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 ('IN (...)' != $func_type
- && 'NOT IN (...)' != $func_type
- && 'BETWEEN' != $func_type
- && 'NOT BETWEEN' != $func_type
- ) {
- if ($func_type == 'LIKE %...%' || $func_type == 'LIKE') {
- $where = $backquoted_name . ' ' . $func_type . ' ' . $quot
- . PMA_Util::sqlAddSlashes($criteriaValues, true) . $quot;
- } else {
- $where = $backquoted_name . ' ' . $func_type . ' ' . $quot
- . PMA_Util::sqlAddSlashes($criteriaValues) . $quot;
- }
- return $where;
- }
- $func_type = str_replace(' (...)', '', $func_type);
- //Don't explode if this is already an array
- //(Case for (NOT) IN/BETWEEN.)
- if (is_array($criteriaValues)) {
- $values = $criteriaValues;
- } else {
- $values = explode(',', $criteriaValues);
- }
- // quote values one by one
- $emptyKey = false;
- foreach ($values as $key => &$value) {
- if ('' === $value) {
- $emptyKey = $key;
- $value = 'NULL';
- continue;
- }
- $value = $quot . PMA_Util::sqlAddSlashes(trim($value))
- . $quot;
- }
- if ('BETWEEN' == $func_type || 'NOT BETWEEN' == $func_type) {
- $where = $backquoted_name . ' ' . $func_type . ' '
- . (isset($values[0]) ? $values[0] : '')
- . ' AND ' . (isset($values[1]) ? $values[1] : '');
- } else { //[NOT] IN
- if (false !== $emptyKey) {
- unset($values[$emptyKey]);
- }
- $wheres = array();
- if (!empty($values)) {
- $wheres[] = $backquoted_name . ' ' . $func_type
- . ' (' . implode(',', $values) . ')';
- }
- if (false !== $emptyKey) {
- $wheres[] = $backquoted_name . ' IS NULL';
- }
- $where = implode(' OR ', $wheres);
- if (1 < count($wheres)) {
- $where = '(' . $where . ')';
- }
- }
- } // 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']) || ! empty($_POST['displayAllColumns'])) {
- $sql_query .= '* ';
- } else {
- $sql_query .= implode(
- ', ',
- PMA_Util::backquote($_POST['columnsToDisplay'])
- );
- } // end if
- $sql_query .= ' FROM '
- . PMA_Util::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_Util::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()
- {
- if (isset($_POST['customWhereClause'])
- && trim($_POST['customWhereClause']) != ''
- ) {
- return ' WHERE ' . $_POST['customWhereClause'];
- }
- // If there are no search criteria set or no unary criteria operators,
- // return
- if (! isset($_POST['criteriaValues'])
- && ! isset($_POST['criteriaColumnOperators'])
- ) {
- return '';
- }
- // 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) {
- return ' WHERE ' . implode(' AND ', $fullWhereClause);
- }
- return '';
- }
- /**
- * 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 .= '<td>';
- $geom_types = PMA_Util::getGISDatatypes();
- // if a geometry column is present
- if (in_array($this->_columnTypes[$column_index], $geom_types)) {
- $html_output .= '<select class="geom_func" name="geom_func['
- . $column_index . ']">';
- // get the relevant list of GIS functions
- $funcs = PMA_Util::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 .= '<option value="' . htmlspecialchars($name) . '">'
- . htmlspecialchars($name) . '</option>';
- }
- $html_output .= '</select>';
- } else {
- $html_output .= ' ';
- }
- $html_output .= '</td>';
- 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_Util::getDivForSliderEffect(
- 'searchoptions', __('Options')
- );
- /**
- * Displays columns select list for selecting distinct columns in the search
- */
- $html_output .= '<fieldset id="fieldset_select_fields">'
- . '<legend>' . __('Select columns (at least one):') . '</legend>'
- . '<select name="columnsToDisplay[]"'
- . ' size="' . min(count($this->_columnNames), 10) . '"'
- . ' multiple="multiple">';
- // Displays the list of the fields
- foreach ($this->_columnNames as $each_field) {
- $html_output .= ' '
- . '<option value="' . htmlspecialchars($each_field) . '"'
- . ' selected="selected">' . htmlspecialchars($each_field)
- . '</option>' . "\n";
- } // end for
- $html_output .= '</select>'
- . '<input type="checkbox" name="distinct" value="DISTINCT"'
- . ' id="oDistinct" />'
- . '<label for="oDistinct">DISTINCT</label></fieldset>';
- /**
- * Displays input box for custom 'Where' clause to be used in the search
- */
- $html_output .= '<fieldset id="fieldset_search_conditions">'
- . '<legend>' . '<em>' . __('Or') . '</em> '
- . __('Add search conditions (body of the "where" clause):') . '</legend>';
- $html_output .= PMA_Util::showMySQLDocu('Functions');
- $html_output .= '<input type="text" name="customWhereClause"'
- . ' class="textfield" size="64" />';
- $html_output .= '</fieldset>';
- /**
- * Displays option of changing default number of rows displayed per page
- */
- $html_output .= '<fieldset id="fieldset_limit_rows">'
- . '<legend>' . __('Number of rows per page') . '</legend>'
- . '<input type="number" name="session_max_rows" required="required" '
- . 'min="1" '
- . 'value="' . $GLOBALS['cfg']['MaxRows'] . '" class="textfield" />'
- . '</fieldset>';
- /**
- * Displays option for ordering search results
- * by a column value (Asc or Desc)
- */
- $html_output .= '<fieldset id="fieldset_display_order">'
- . '<legend>' . __('Display order:') . '</legend>'
- . '<select name="orderByColumn"><option value="--nil--"></option>';
- foreach ($this->_columnNames as $each_field) {
- $html_output .= ' '
- . '<option value="' . htmlspecialchars($each_field) . '">'
- . htmlspecialchars($each_field) . '</option>' . "\n";
- } // end for
- $html_output .= '</select>';
- $choices = array(
- 'ASC' => __('Ascending'),
- 'DESC' => __('Descending')
- );
- $html_output .= PMA_Util::getRadioFields(
- 'order', $choices, 'ASC', false, true, "formelement"
- );
- unset($choices);
- $html_output .= '</fieldset><br style="clear: both;"/></div>';
- 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 .= '<table class="data">';
- //Select options for datalabel
- $html_output .= '<tr>';
- $html_output .= '<td><label for="dataLabel">'
- . __("Use this column to label each point") . '</label></td>';
- $html_output .= '<td><select name="dataLabel" id="dataLabel" >'
- . '<option value = "">' . __('None') . '</option>';
- for ($j = 0, $nb = count($this->_columnNames); $j < $nb; $j++) {
- if (isset($dataLabel)
- && $dataLabel == htmlspecialchars($this->_columnNames[$j])
- ) {
- $html_output .= '<option value="'
- . htmlspecialchars($this->_columnNames[$j])
- . '" selected="selected">'
- . htmlspecialchars($this->_columnNames[$j])
- . '</option>';
- } else {
- $html_output .= '<option value="'
- . htmlspecialchars($this->_columnNames[$j]) . '" >'
- . htmlspecialchars($this->_columnNames[$j]) . '</option>';
- }
- }
- $html_output .= '</select></td>';
- $html_output .= '</tr>';
- //Inputbox for changing default maximum rows to plot
- $html_output .= '<tr>';
- $html_output .= '<td><label for="maxRowPlotLimit">'
- . __("Maximum rows to plot") . '</label></td>';
- $html_output .= '<td>';
- $html_output .= '<input type="number" name="maxPlotLimit"'
- . ' id="maxRowPlotLimit" required="required"'
- . ' value="' . ((! empty($_POST['maxPlotLimit']))
- ? htmlspecialchars($_POST['maxPlotLimit'])
- : $GLOBALS['cfg']['maxRowPlotLimit'])
- . '" />';
- $html_output .= '</td></tr>';
- $html_output .= '</table>';
- 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 = array(
- 'Browse' => PMA_Util::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 = '<select name="criteriaColumnOperators['
- . $search_index . ']" onchange="changeValueFieldType(this, '
- . $search_index . ')">';
- $func .= $GLOBALS['PMA_Types']->getTypeOperatorsHtml(
- preg_replace('@\(.*@s', '', $this->_columnTypes[$column_index]),
- $this->_columnNullFlags[$column_index], $selected_operator
- );
- $func .= '</select>';
- //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, $nb = count($this->_columnNames);
- $column_index < $nb;
- $column_index++
- ) {
- $html_output .= '<tr class="noclick '
- . ($odd_row ? 'odd' : 'even')
- . '">';
- $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 .= '<th>'
- . htmlspecialchars($this->_columnNames[$column_index]) . '</th>';
- $properties = $this->getColumnProperties($column_index, $column_index);
- $html_output .= '<td>' . $properties['type'] . '</td>';
- $html_output .= '<td>' . $properties['collation'] . '</td>';
- $html_output .= '<td>' . $properties['func'] . '</td>';
- // here, the data-type attribute is needed for a date/time picker
- $html_output .= '<td data-type="' . $properties['type'] . '"'
- . '>' . $properties['value'] . '</td>';
- $html_output .= '</tr>';
- //Displays hidden fields
- $html_output .= '<tr><td>';
- $html_output .= '<input type="hidden"'
- . ' name="criteriaColumnNames[' . $column_index . ']"'
- . ' value="' . htmlspecialchars($this->_columnNames[$column_index])
- . '" />';
- $html_output .= '<input type="hidden"'
- . ' name="criteriaColumnTypes[' . $column_index . ']"'
- . ' value="' . $this->_columnTypes[$column_index] . '" />';
- $html_output .= '<input type="hidden"'
- . ' name="criteriaColumnCollations[' . $column_index . ']"'
- . ' value="' . $this->_columnCollations[$column_index] . '" />';
- $html_output .= '</td></tr>';
- } // 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 = '';
- $type = array();
- $collation = array();
- $func = array();
- $value = array();
- /**
- * 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 .= '<tr><td>';
- $html_output .= __("Additional search criteria");
- $html_output .= '</td></tr>';
- }
- $html_output .= '<tr class="noclick '
- . ($odd_row ? 'odd' : 'even')
- . '">';
- $odd_row = ! $odd_row;
- //Select options for column names
- $html_output .= '<th><select name="criteriaColumnNames[]" id="'
- . 'tableid_' . $i . '" >';
- $html_output .= '<option value="' . 'pma_null' . '">' . __('None')
- . '</option>';
- for ($j = 0, $nb = count($this->_columnNames); $j < $nb; $j++) {
- if (isset($_POST['criteriaColumnNames'][$i])
- && $_POST['criteriaColumnNames'][$i] == htmlspecialchars($this->_columnNames[$j])
- ) {
- $html_output .= '<option value="'
- . htmlspecialchars($this->_columnNames[$j])
- . '" selected="selected">'
- . htmlspecialchars($this->_columnNames[$j])
- . '</option>';
- } else {
- $html_output .= '<option value="'
- . htmlspecialchars($this->_columnNames[$j]) . '">'
- . htmlspecialchars($this->_columnNames[$j]) . '</option>';
- }
- }
- $html_output .= '</select></th>';
- 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 .= '<td>' . (isset($type[$i]) ? $type[$i] : '') . '</td>';
- //Column Collation
- $html_output .= '<td>' . (isset($collation[$i]) ? $collation[$i] : '')
- . '</td>';
- //Select options for column operators
- $html_output .= '<td>' . (isset($func[$i]) ? $func[$i] : '') . '</td>';
- //Inputbox for search criteria value
- $html_output .= '<td>' . (isset($value[$i]) ? $value[$i] : '') . '</td>';
- $html_output .= '</tr>';
- //Displays hidden fields
- $html_output .= '<tr><td>';
- $html_output
- .= '<input type="hidden" name="criteriaColumnTypes[' . $i . ']"'
- . ' id="types_' . $i . '" ';
- if (isset($_POST['criteriaColumnTypes'][$i])) {
- $html_output .= 'value="' . $_POST['criteriaColumnTypes'][$i] . '" ';
- }
- $html_output .= '/>';
- $html_output .= '<input type="hidden" name="criteriaColumnCollations['
- . $i . ']" id="collations_' . $i . '" />';
- $html_output .= '</td></tr>';
- }//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 .= '<table class="data"'
- . ($this->_searchType == 'zoom' ? ' id="tableFieldsId"' : '') . '>';
- $html_output .= $this->_getTableHeader();
- $html_output .= '<tbody>';
- if ($this->_searchType == 'zoom') {
- $html_output .= $this->_getRowsZoom();
- } else {
- $html_output .= $this->_getRowsNormal();
- }
- $html_output .= '</tbody></table>';
- 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 = '';
- $formId = '';
- switch ($this->_searchType) {
- case 'normal' :
- $scriptName = 'tbl_select.php';
- $formId = 'tbl_search_form';
- break;
- case 'zoom' :
- $scriptName = 'tbl_zoom_select.php';
- $formId = 'zoom_search_form';
- break;
- case 'replace' :
- $scriptName = 'tbl_find_replace.php';
- $formId = 'find_replace_form';
- break;
- }
- $html_output .= '<form method="post" action="' . $scriptName . '" '
- . 'name="insertForm" id="' . $formId . '" '
- . 'class="ajax"' . '>';
- $html_output .= PMA_URL_getHiddenInputs($this->_db, $this->_table);
- $html_output .= '<input type="hidden" name="goto" value="' . $goto . '" />';
- $html_output .= '<input type="hidden" name="back" value="' . $scriptName
- . '" />';
- return $html_output;
- }
- /**
- * Returns the HTML for secondary levels tabs of the table search page
- *
- * @return string HTML for secondary levels tabs
- */
- public function getSecondaryTabs()
- {
- $url_params = array();
- $url_params['db'] = $this->_db;
- $url_params['table'] = $this->_table;
- $html_output = '<ul id="topmenu2">';
- foreach ($this->_getSubTabs() as $tab) {
- $html_output .= PMA_Util::getHtmlTab($tab, $url_params);
- }
- $html_output .= '</ul>';
- $html_output .= '<div class="clearfloat"></div>';
- return $html_output;
- }
- /**
- * Generates the table search form under table search tab
- *
- * @param string $goto Goto URL
- * @param string $dataLabel Label for points in zoom plot
- *
- * @return string the generated HTML for table search form
- */
- public function getSelectionForm($goto, $dataLabel = null)
- {
- $html_output = $this->_getFormTag($goto);
- if ($this->_searchType == 'zoom') {
- $html_output .= '<fieldset id="fieldset_zoom_search">';
- $html_output .= '<fieldset id="inputSection">';
- $html_output .= '<legend>'
- . __('Do a "query by example" (wildcard: "%") for two different columns')
- . '</legend>';
- $html_output .= $this->_getFieldsTableHtml();
- $html_output .= $this->_getOptionsZoom($dataLabel);
- $html_output .= '</fieldset>';
- $html_output .= '</fieldset>';
- } else if ($this->_searchType == 'normal') {
- $html_output .= '<fieldset id="fieldset_table_search">';
- $html_output .= '<fieldset id="fieldset_table_qbe">';
- $html_output .= '<legend>'
- . __('Do a "query by example" (wildcard: "%")')
- . '</legend>';
- $html_output .= $this->_getFieldsTableHtml();
- $html_output .= '<div id="gis_editor"></div>';
- $html_output .= '<div id="popup_background"></div>';
- $html_output .= '</fieldset>';
- $html_output .= $this->_getOptions();
- $html_output .= '</fieldset>';
- } else if ($this->_searchType == 'replace') {
- $html_output .= '<fieldset id="fieldset_find_replace">';
- $html_output .= '<fieldset id="fieldset_find">';
- $html_output .= '<legend>' . __('Find and Replace') . '</legend>';
- $html_output .= $this->_getSearchAndReplaceHTML();
- $html_output .= '</fieldset>';
- $html_output .= '</fieldset>';
- }
- /**
- * Displays selection form's footer elements
- */
- $html_output .= '<fieldset class="tblFooters">';
- $html_output .= '<input type="submit" name="'
- . ($this->_searchType == 'zoom' ? 'zoom_submit' : 'submit')
- . ($this->_searchType == 'zoom' ? '" id="inputFormSubmitId"' : '" ')
- . 'value="' . __('Go') . '" />';
- $html_output .= '</fieldset></form>';
- $html_output .= '<div id="sqlqueryresults"></div>';
- 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 = array(
- 'Browse' => PMA_Util::getIcon(
- 'b_browse.png',
- __('Browse foreign values')
- )
- );
- $html_output .= '<form method="post" action="tbl_zoom_select.php"'
- . ' name="displayResultForm" id="zoom_display_form"'
- . ' class="ajax"' . '>';
- $html_output .= PMA_URL_getHiddenInputs($this->_db, $this->_table);
- $html_output .= '<input type="hidden" name="goto" value="' . $goto . '" />';
- $html_output
- .= '<input type="hidden" name="back" value="tbl_zoom_select.php" />';
- $html_output .= '<fieldset id="displaySection">';
- $html_output .= '<legend>' . __('Browse/Edit the points') . '</legend>';
- //JSON encode the data(query result)
- $html_output .= '<center>';
- if (isset($_POST['zoom_submit']) && ! empty($data)) {
- $html_output .= '<div id="resizer">';
- $html_output .= '<center><a href="#" onclick="displayHelp();">'
- . __('How to use') . '</a></center>';
- $html_output .= '<div id="querydata" style="display:none">'
- . json_encode($data) . '</div>';
- $html_output .= '<div id="querychart"></div>';
- $html_output .= '<button class="button-reset">'
- . __('Reset zoom') . '</button>';
- $html_output .= '</div>';
- }
- $html_output .= '</center>';
- //Displays rows in point edit form
- $html_output .= '<div id="dataDisplay" style="display:none">';
- $html_output .= '<table><thead>';
- $html_output .= '<tr>';
- $html_output .= '<th>' . __('Column') . '</th>'
- . '<th>' . __('Null') . '</th>'
- . '<th>' . __('Value') . '</th>';
- $html_output .= '</tr>';
- $html_output .= '</thead>';
- $html_output .= '<tbody>';
- $odd_row = true;
- for (
- $column_index = 0, $nb = count($this->_columnNames);
- $column_index < $nb;
- $column_index++
- ) {
- $fieldpopup = $this->_columnNames[$column_index];
- $foreignData = PMA_getForeignData(
- $this->_foreigners,
- $fieldpopup,
- false,
- '',
- ''
- );
- $html_output
- .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
- $odd_row = ! $odd_row;
- //Display column Names
- $html_output
- .= '<th>' . htmlspecialchars($this->_columnNames[$column_index])
- . '</th>';
- //Null checkbox if column can be null
- $html_output .= '<th>'
- . (($this->_columnNullFlags[$column_index] == 'YES')
- ? '<input type="checkbox" class="checkbox_null"'
- . ' name="criteriaColumnNullFlags[' . $column_index . ']"'
- . ' id="edit_fields_null_id_' . $column_index . '" />'
- : '');
- $html_output .= '</th>';
- //Column's Input box
- $html_output .= '<th>';
- $html_output .= $this->_getInputbox(
- $foreignData, $fieldpopup, $this->_columnTypes[$column_index],
- $column_index, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'],
- '', false, true
- );
- $html_output .= '</th></tr>';
- }
- $html_output .= '</tbody></table>';
- $html_output .= '</div>';
- $html_output .= '<input type="hidden" id="queryID" name="sql_query" />';
- $html_output .= '</form>';
- return $html_output;
- }
- /**
- * Displays the 'Find and Replace' form
- *
- * @return string HTML for 'Find and Replace' form
- */
- function _getSearchAndReplaceHTML()
- {
- $htmlOutput = __('Find:')
- . '<input type="text" value="" name="find" required />';
- $htmlOutput .= __('Replace with:')
- . '<input type="text" value="" name="replaceWith" required />';
- $htmlOutput .= __('Column:') . '<select name="columnIndex">';
- for ($i = 0, $nb = count($this->_columnNames); $i < $nb; $i++) {
- $type = preg_replace('@\(.*@s', '', $this->_columnTypes[$i]);
- if ($GLOBALS['PMA_Types']->getTypeClass($type) == 'CHAR') {
- $column = $this->_columnNames[$i];
- $htmlOutput .= '<option value="' . $i . '">'
- . htmlspecialchars($column) . '</option>';
- }
- }
- $htmlOutput .= '</select>';
- return $htmlOutput;
- }
- /**
- * Returns HTML for prviewing strings found and their replacements
- *
- * @param int $columnIndex index of the column
- * @param string $find string to find in the column
- * @param string $replaceWith string to replace with
- * @param string $charSet character set of the connection
- *
- * @return string HTML for prviewing strings found and their replacements
- */
- function getReplacePreview($columnIndex, $find, $replaceWith, $charSet)
- {
- $column = $this->_columnNames[$columnIndex];
- $sql_query = "SELECT "
- . PMA_Util::backquote($column) . ","
- . " REPLACE("
- . PMA_Util::backquote($column) . ", '" . $find . "', '" . $replaceWith
- . "'),"
- . " COUNT(*)"
- . " FROM " . PMA_Util::backquote($this->_db)
- . "." . PMA_Util::backquote($this->_table)
- . " WHERE " . PMA_Util::backquote($column)
- . " LIKE '%" . $find . "%' COLLATE " . $charSet . "_bin"; // here we
- // change the collation of the 2nd operand to a case sensitive
- // binary collation to make sure that the comparison is case sensitive
- $sql_query .= " GROUP BY " . PMA_Util::backquote($column)
- . " ORDER BY " . PMA_Util::backquote($column) . " ASC";
- $resultSet = $GLOBALS['dbi']->query(
- $sql_query, null, PMA_DatabaseInterface::QUERY_STORE
- );
- $htmlOutput = '<form method="post" action="tbl_find_replace.php"'
- . ' name="previewForm" id="previewForm" class="ajax">';
- $htmlOutput .= PMA_URL_getHiddenInputs($this->_db, $this->_table);
- $htmlOutput .= '<input type="hidden" name="replace" value="true" />';
- $htmlOutput .= '<input type="hidden" name="columnIndex" value="'
- . $columnIndex . '" />';
- $htmlOutput .= '<input type="hidden" name="findString"'
- . ' value="' . $find . '" />';
- $htmlOutput .= '<input type="hidden" name="replaceWith"'
- . ' value="' . $replaceWith . '" />';
- $htmlOutput .= '<fieldset id="fieldset_find_replace_preview">';
- $htmlOutput .= '<legend>' . __('Find and replace - preview') . '</legend>';
- $htmlOutput .= '<table id="previewTable">'
- . '<thead><tr>'
- . '<th>' . __('Count') . '</th>'
- . '<th>' . __('Original string') . '</th>'
- . '<th>' . __('Replaced string') . '</th>'
- . '</tr></thead>';
- $htmlOutput .= '<tbody>';
- $odd = true;
- while ($row = $GLOBALS['dbi']->fetchRow($resultSet)) {
- $val = $row[0];
- $replaced = $row[1];
- $count = $row[2];
- $htmlOutput .= '<tr class="' . ($odd ? 'odd' : 'even') . '">';
- $htmlOutput .= '<td class="right">' . htmlspecialchars($count) . '</td>';
- $htmlOutput .= '<td>' . htmlspecialchars($val) . '</td>';
- $htmlOutput .= '<td>' . htmlspecialchars($replaced) . '</td>';
- $htmlOutput .= '</tr>';
- $odd = ! $odd;
- }
- $htmlOutput .= '</tbody>';
- $htmlOutput .= '</table>';
- $htmlOutput .= '</fieldset>';
- $htmlOutput .= '<fieldset class="tblFooters">';
- $htmlOutput .= '<input type="submit" name="replace"'
- . ' value="' . __('Replace') . '" />';
- $htmlOutput .= '</fieldset>';
- $htmlOutput .= '</form>';
- return $htmlOutput;
- }
- /**
- * Replaces a given string in a column with a give replacement
- *
- * @param int $columnIndex index of the column
- * @param string $find string to find in the column
- * @param string $replaceWith string to replace with
- * @param string $charSet character set of the connection
- *
- * @return void
- */
- function replace($columnIndex, $find, $replaceWith, $charSet)
- {
- $column = $this->_columnNames[$columnIndex];
- $sql_query = "UPDATE " . PMA_Util::backquote($this->_db)
- . "." . PMA_Util::backquote($this->_table)
- . " SET " . PMA_Util::backquote($column) . " ="
- . " REPLACE("
- . PMA_Util::backquote($column) . ", '" . $find . "', '" . $replaceWith
- . "')"
- . " WHERE " . PMA_Util::backquote($column)
- . " LIKE '%" . $find . "%' COLLATE " . $charSet . "_bin"; // here we
- // change the collation of the 2nd operand to a case sensitive
- // binary collation to make sure that the comparison is case sensitive
- $GLOBALS['dbi']->query(
- $sql_query, null, PMA_DatabaseInterface::QUERY_STORE
- );
- $GLOBALS['sql_query'] = $sql_query;
- }
- }
- ?>
|