diff --git a/libraries/TableSearch.class.php b/libraries/TableSearch.class.php
new file mode 100644
index 0000000000..8b3b2f14d2
--- /dev/null
+++ b/libraries/TableSearch.class.php
@@ -0,0 +1,1197 @@
+_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);
+ }
+
+ /**
+ * 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 .= '';
+
+ } 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 .= '