misc = $this->misc; $plugin_manager = $this->plugin_manager; if ('dobrowsefk' == $this->action) { return $this->doBrowseFK(); } set_time_limit(0); $scripts = ''; $scripts .= ''.PHP_EOL; $footer_template = 'footer.twig'; $header_template = 'header.twig'; ob_start(); switch ($this->action) { case 'editrow': $header_template = 'header_sqledit.twig'; $footer_template = 'footer_sqledit.twig'; if (isset($_POST['save'])) { $this->doEditRow(); } else { $this->doBrowse(); } break; case 'confeditrow': $this->formEditRow(); break; case 'delrow': $header_template = 'header_sqledit.twig'; $footer_template = 'footer_sqledit.twig'; if (isset($_POST['yes'])) { $this->doDelRow(false); } else { $this->doBrowse(); } break; case 'confdelrow': $this->doDelRow(true); break; default: $header_template = 'header_sqledit.twig'; $footer_template = 'footer_sqledit.twig'; $this->doBrowse(); break; } $output = ob_get_clean(); $subject = $this->coalesceArr($_REQUEST, 'subject', 'table')['subject']; $object = null; $object = $this->setIfIsset($object, $_REQUEST[$subject]); // Set the title based on the subject of the request if ('table' == $subject) { $title = $this->headerTitle('strtables', '', $object); } elseif ('view' == $subject) { $title = $this->headerTitle('strviews', '', $object); } elseif ('matview' == $subject) { $title = $this->headerTitle('strviews', 'M', $object); } elseif ('column' == $subject) { $title = $this->headerTitle('strcolumn', '', $object); } else { $title = $this->headerTitle('strqueryresults'); } $this->printHeader($title, $scripts, true, $header_template); $this->printBody(); echo $output; $this->printFooter(true, $footer_template); } /** * Displays requested data. * * @param mixed $msg */ public function doBrowse($msg = '') { $this->misc = $this->misc; $data = $this->misc->getDatabaseAccessor(); // If current page is not set, default to first page $page = $this->coalesceArr($_REQUEST, 'page', 1)['page']; $save_history = !isset($_REQUEST['nohistory']); $subject = $this->coalesceArr($_REQUEST, 'subject', 'table')['subject']; $object = $this->coalesceArr($_REQUEST, $subject)[$subject]; if ($subject === 'column' && $object && isset($_REQUEST['f_schema'], $_REQUEST['f_table'])) { $f_schema = $_REQUEST['f_schema']; $f_table = $_REQUEST['f_table']; $_REQUEST['query'] = "SELECT \"{$object}\", count(*) AS \"count\" FROM \"{$f_schema}\".\"{$f_table}\" GROUP BY \"{$object}\" ORDER BY \"{$object}\""; } elseif ($subject === 'table' && !isset($_REQUEST['query'])) { $show = $this->getPostParam('show', []); $values = $this->getPostParam('values', []); $ops = $this->getPostParam('ops', []); $query = $data->getSelectSQL( $_REQUEST['table'], array_keys($show), $values, $ops ); $_REQUEST['query'] = $query; $_REQUEST['return'] = 'selectrows'; } //$object = $this->setIfIsset($object, $_REQUEST[$subject]); $this->printTrail($subject); $tabsPosition = 'browse'; if ($subject === 'database') { $tabsPosition = 'sql'; } elseif ($subject === 'column') { $tabsPosition = 'colproperties'; } $this->printTabs($subject, $tabsPosition); list($query, $title, $type) = $this->getQueryTitleAndType($data, $object); $this->printTitle($this->lang[$title]); //$this->prtrace($subject, $object, $query, $_SESSION['sqlquery']); $this->printMsg($msg); // If 'sortkey' is not set, default to '' $sortkey = $this->coalesceArr($_REQUEST, 'sortkey', '')['sortkey']; // If 'sortdir' is not set, default to '' $sortdir = $this->coalesceArr($_REQUEST, 'sortdir', '')['sortdir']; // If 'strings' is not set, default to collapsed $strings = $this->coalesceArr($_REQUEST, 'strings', 'collapsed')['strings']; $this->coalesceArr($_REQUEST, 'schema')['schema']; $search_path = $this->coalesceArr($_REQUEST, 'search_path')['search_path']; // Set the schema search path if (isset($search_path) && (0 != $data->setSearchPath(array_map('trim', explode(',', $search_path))))) { return; } try { // Retrieve page from query. $max_pages is returned by reference. $resultset = $data->browseQuery( $type, $object, $query, $sortkey, $sortdir, $page, $this->conf['max_rows'], $max_pages ); } catch (\PHPPgAdmin\ADOdbException $e) { return $this->halt($e->getMessage()); } // Build strings for GETs in array $_gets = [ 'server' => $_REQUEST['server'], 'database' => $_REQUEST['database'], ]; $this->coalesceArr($_REQUEST, 'query'); $this->coalesceArr($_REQUEST, 'count'); $this->coalesceArr($_REQUEST, 'return'); $this->coalesceArr($_REQUEST, 'table'); $this->coalesceArr($_REQUEST, 'nohistory'); $this->setIfIsset($_gets['schema'], $_REQUEST['schema'], null, false); $this->setIfIsset($_gets[$subject], $object, null, false); $this->setIfIsset($_gets['subject'], $subject, null, false); $this->setIfIsset($_gets['query'], $_REQUEST['query'], null, false); $this->setIfIsset($_gets['count'], $_REQUEST['count'], null, false); $this->setIfIsset($_gets['return'], $_REQUEST['return'], null, false); $this->setIfIsset($_gets['search_path'], $_REQUEST['search_path'], null, false); $this->setIfIsset($_gets['table'], $_REQUEST['table'], null, false); $this->setIfIsset($_gets['nohistory'], $_REQUEST['nohistory'], null, false); $_gets['sortkey'] = $sortkey; $_gets['sortdir'] = $sortdir; $_gets['strings'] = $strings; if ($save_history && is_object($resultset) && ('QUERY' == $type)) { //{ $this->misc->saveScriptHistory($_REQUEST['query']); } $query = $query ? $query : sprintf('SELECT * FROM %s.%s', $_REQUEST['schema'], $object); //$query = isset($_REQUEST['query'])? $_REQUEST['query'] : "select * from {$_REQUEST['schema']}.{$_REQUEST['table']};"; //$this->prtrace($query); //die(htmlspecialchars($query)); echo '
'; echo $this->misc->form; if ($object) { echo ''.PHP_EOL; } echo '
'; echo '
'; $this->printResultsTable($resultset, $page, $max_pages, $_gets, $object); // Navigation links $navlinks = $this->getBrowseNavLinks($type, $_gets, $page, $subject, $object, $resultset); $this->printNavLinks($navlinks, 'display-browse', get_defined_vars()); } public function getQueryTitleAndType($data, $object) { $fkey = $this->coalesceArr($_REQUEST, 'fkey')['fkey']; $query = $this->coalesceArr($_REQUEST, 'query')['query']; // This code is used when browsing FK in pure-xHTML (without js) if ($fkey) { $ops = []; foreach (array_keys($fkey) as $x) { $ops[$x] = '='; } $query = $data->getSelectSQL($_REQUEST['table'], [], $fkey, $ops); $_REQUEST['query'] = $query; } $title = 'strqueryresults'; $type = 'QUERY'; if ($object && $query) { $_SESSION['sqlquery'] = $query; $title = 'strselect'; $type = 'SELECT'; } elseif ($object) { $title = 'strselect'; $type = 'TABLE'; } elseif (isset($_SESSION['sqlquery'])) { $query = $_SESSION['sqlquery']; } return [$query, $title, $type]; } public function getBrowseNavLinks($type, $_gets, $page, $subject, $object, $resultset) { $fields = [ 'server' => $_REQUEST['server'], 'database' => $_REQUEST['database'], ]; $this->setIfIsset($fields['schema'], $_REQUEST['schema'], null, false); $navlinks = []; $strings = $_gets['strings']; // Return if (isset($_REQUEST['return'])) { $urlvars = $this->misc->getSubjectParams($_REQUEST['return']); $navlinks['back'] = [ 'attr' => [ 'href' => [ 'url' => $urlvars['url'], 'urlvars' => $urlvars['params'], ], ], 'content' => $this->lang['strback'], ]; } // Edit SQL link if ('QUERY' == $type) { $navlinks['edit'] = [ 'attr' => [ 'href' => [ 'url' => 'database', 'urlvars' => array_merge( $fields, [ 'action' => 'sql', 'paginate' => 'on', ] ), ], ], 'content' => $this->lang['streditsql'], ]; } $navlinks['collapse'] = [ 'attr' => [ 'href' => [ 'url' => 'display', 'urlvars' => array_merge( $_gets, [ 'strings' => 'expanded', 'page' => $page, ] ), ], ], 'content' => $this->lang['strexpand'], ]; // Expand/Collapse if ('expanded' == $strings) { $navlinks['collapse'] = [ 'attr' => [ 'href' => [ 'url' => 'display', 'urlvars' => array_merge( $_gets, [ 'strings' => 'collapsed', 'page' => $page, ] ), ], ], 'content' => $this->lang['strcollapse'], ]; } // Create view and download if (isset($_REQUEST['query'], $resultset) && is_object($resultset) && $resultset->recordCount() > 0) { // Report views don't set a schema, so we need to disable create view in that case if (isset($_REQUEST['schema'])) { $navlinks['createview'] = [ 'attr' => [ 'href' => [ 'url' => 'views', 'urlvars' => array_merge( $fields, [ 'action' => 'create', 'formDefinition' => $_REQUEST['query'], ] ), ], ], 'content' => $this->lang['strcreateview'], ]; } $urlvars = []; $this->setIfIsset($urlvars['search_path'], $_REQUEST['search_path'], null, false); $navlinks['download'] = [ 'attr' => [ 'href' => [ 'url' => 'dataexport', 'urlvars' => array_merge($fields, $urlvars), ], ], 'content' => $this->lang['strdownload'], ]; } // Insert if (isset($object) && (isset($subject) && 'table' == $subject)) { $navlinks['insert'] = [ 'attr' => [ 'href' => [ 'url' => 'tables', 'urlvars' => array_merge( $fields, [ 'action' => 'confinsertrow', 'table' => $object, ] ), ], ], 'content' => $this->lang['strinsert'], ]; } // Refresh $navlinks['refresh'] = [ 'attr' => [ 'href' => [ 'url' => 'display', 'urlvars' => array_merge( $_gets, [ 'strings' => $strings, 'page' => $page, ] ), ], ], 'content' => $this->lang['strrefresh'], ]; return $navlinks; } private function _getKeyAndActions($resultset, $object, $data, $page, $_gets) { $key = []; $strings = $_gets['strings']; $plugin_manager = $this->plugin_manager; // Fetch unique row identifier, if this is a table browse request. if ($object) { $key = $data->getRowIdentifier($object); } // Check that the key is actually in the result set. This can occur for select // operations where the key fields aren't part of the select. XXX: We should // be able to support this, somehow. foreach ($key as $v) { // If a key column is not found in the record set, then we // can't use the key. if (!array_key_exists($v, $resultset->fields)) { $key = []; break; } } $buttons = [ 'edit' => [ 'content' => $this->lang['stredit'], 'attr' => [ 'href' => [ 'url' => 'display', 'urlvars' => array_merge( [ 'action' => 'confeditrow', 'strings' => $strings, 'page' => $page, ], $_gets ), ], ], ], 'delete' => [ 'content' => $this->lang['strdelete'], 'attr' => [ 'href' => [ 'url' => 'display', 'urlvars' => array_merge( [ 'action' => 'confdelrow', 'strings' => $strings, 'page' => $page, ], $_gets ), ], ], ], ]; $actions = [ 'actionbuttons' => &$buttons, 'place' => 'display-browse', ]; $plugin_manager->doHook('actionbuttons', $actions); foreach (array_keys($actions['actionbuttons']) as $action) { $actions['actionbuttons'][$action]['attr']['href']['urlvars'] = array_merge( $actions['actionbuttons'][$action]['attr']['href']['urlvars'], $_gets ); } return [$actions, $key]; } public function printResultsTable($resultset, $page, $max_pages, $_gets, $object) { if (!is_object($resultset) || $resultset->recordCount() <= 0) { echo "

{$this->lang['strnodata']}

".PHP_EOL; return; } $data = $this->misc->getDatabaseAccessor(); list($actions, $key) = $this->_getKeyAndActions($resultset, $object, $data, $page, $_gets); $fkey_information = $this->getFKInfo(); // Show page navigation $paginator = $this->_printPages($page, $max_pages, $_gets); echo $paginator; echo ''.PHP_EOL; echo ''; // Display edit and delete actions if we have a key $display_action_column = (count($actions['actionbuttons']) > 0 && count($key) > 0); echo $display_action_column ? "".PHP_EOL : ''; // we show OIDs only if we are in TABLE or SELECT type browsing $this->printTableHeaderCells($resultset, $_gets, isset($object)); echo ''.PHP_EOL; reset($resultset->fields); $trclass = 'data2'; $buttonclass = 'opbutton2'; while (!$resultset->EOF) { $trclass = ($trclass === 'data2') ? 'data1' : 'data2'; $buttonclass = ($buttonclass === 'opbutton2') ? 'opbutton1' : 'opbutton2'; echo sprintf('', $trclass).PHP_EOL; $this->_printResultsTableActionButtons($resultset, $key, $actions, $display_action_column, $buttonclass); $this->printTableRowCells($resultset, $fkey_information, isset($object)); echo ''.PHP_EOL; $resultset->moveNext(); } echo '
{$this->lang['stractions']}
'.PHP_EOL; echo '

', $resultset->recordCount(), " {$this->lang['strrows']}

".PHP_EOL; // Show page navigation echo $paginator; } private function _printResultsTableActionButtons($resultset, $key, $actions, $display_action_column, $buttonclass) { if (!$display_action_column) { return; } $edit_params = isset($actions['actionbuttons']['edit']) ? $actions['actionbuttons']['edit'] : []; $delete_params = isset($actions['actionbuttons']['delete']) ? $actions['actionbuttons']['delete'] : []; $keys_array = []; $has_nulls = false; foreach ($key as $v) { if (null === $resultset->fields[$v]) { $has_nulls = true; break; } $keys_array["key[{$v}]"] = $resultset->fields[$v]; } if ($has_nulls) { echo ' '.PHP_EOL; return; } // Display edit and delete links if we have a key if (isset($actions['actionbuttons']['edit'])) { $actions['actionbuttons']['edit'] = $edit_params; $actions['actionbuttons']['edit']['attr']['href']['urlvars'] = array_merge( $actions['actionbuttons']['edit']['attr']['href']['urlvars'], $keys_array ); } if (isset($actions['actionbuttons']['delete'])) { $actions['actionbuttons']['delete'] = $delete_params; $actions['actionbuttons']['delete']['attr']['href']['urlvars'] = array_merge( $actions['actionbuttons']['delete']['attr']['href']['urlvars'], $keys_array ); } echo sprintf('', $buttonclass); foreach ($actions['actionbuttons'] as $action) { $this->printLink($action, true, __METHOD__); } echo ''.PHP_EOL; } /** * Print table header cells. * * @param \PHPPgAdmin\ADORecordSet $resultset set of results from getRow operation * @param array|bool $args - associative array for sort link parameters, or false if there isn't any * @param bool $withOid either to display OIDs or not */ public function printTableHeaderCells(&$resultset, $args, $withOid) { $data = $this->misc->getDatabaseAccessor(); if (!is_object($resultset) || $resultset->recordCount() <= 0) { return; } foreach (array_keys($resultset->fields) as $index => $key) { if (($key === $data->id) && (!($withOid && $this->conf['show_oids']))) { continue; } $finfo = $resultset->fetchField($index); if (false === $args) { echo '', $this->misc->printVal($finfo->name), ''.PHP_EOL; continue; } $args['page'] = $_REQUEST['page']; $args['sortkey'] = $index + 1; // Sort direction opposite to current direction, unless it's currently '' $args['sortdir'] = ('asc' == $_REQUEST['sortdir'] && $_REQUEST['sortkey'] == ($index + 1)) ? 'desc' : 'asc'; $sortLink = http_build_query($args); echo ""; echo $this->misc->printVal($finfo->name); if ($_REQUEST['sortkey'] == ($index + 1)) { $icon = ('asc' == $_REQUEST['sortdir']) ? $this->misc->icon('RaiseArgument') : $this->misc->icon('LowerArgument'); echo sprintf('%s', $icon, $_REQUEST['sortdir']); } echo ''.PHP_EOL; } reset($resultset->fields); } /** * Print table rows. * * @param \PHPPgAdmin\ADORecordSet $resultset The resultset * @param array $fkey_information The fkey information * @param bool $withOid either to display OIDs or not */ public function printTableRowCells(&$resultset, &$fkey_information, $withOid) { $data = $this->misc->getDatabaseAccessor(); $j = 0; $this->coalesceArr($_REQUEST, 'strings', 'collapsed'); foreach ($resultset->fields as $k => $v) { $finfo = $resultset->fetchField($j++); if (($k === $data->id) && (!($withOid && $this->conf['show_oids']))) { continue; } $printvalOpts = ['null' => true, 'clip' => ('collapsed' == $_REQUEST['strings'])]; if (null !== $v && '' == $v) { echo ' '; } else { echo ''; $this->_printFKLinks($resultset, $fkey_information, $k, $v, $printvalOpts); $val = $this->misc->printVal($v, $finfo->type, $printvalOpts); echo $val; echo ''; } } } private function _printFKLinks($resultset, $fkey_information, $k, $v, &$printvalOpts) { if ((null === $v) || !isset($fkey_information['byfield'][$k])) { return; } foreach ($fkey_information['byfield'][$k] as $conid) { $query_params = $fkey_information['byconstr'][$conid]['url_data']; foreach ($fkey_information['byconstr'][$conid]['fkeys'] as $p_field => $f_field) { $query_params .= '&'.urlencode("fkey[{$f_field}]").'='.urlencode($resultset->fields[$p_field]); } // $fkey_information['common_url'] is already urlencoded $query_params .= '&'.$fkey_information['common_url']; $title = htmlentities($fkey_information['byconstr'][$conid]['consrc'], ENT_QUOTES, 'UTF-8'); echo '
'; echo sprintf('', htmlentities($conid, ENT_QUOTES, 'UTF-8'), $query_params); echo sprintf('[fk]', $this->misc->icon('ForeignKey'), $title); echo ''; echo '
'; } $printvalOpts['class'] = 'fk_value'; } private function _unserializeIfNotArray($the_array, $key) { if (!isset($the_array[$key])) { return []; } if (is_array($the_array[$key])) { return $the_array[$key]; } return unserialize(urldecode($the_array[$key])); } /** * Show form to edit row. * * @param string $msg message to display on top of the form or after performing edition */ public function formEditRow($msg = '') { $data = $this->misc->getDatabaseAccessor(); $key = $this->_unserializeIfNotArray($_REQUEST, 'key'); $this->printTrail($_REQUEST['subject']); $this->printTitle($this->lang['streditrow']); $this->printMsg($msg); $attrs = $data->getTableAttributes($_REQUEST['table']); $resultset = $data->browseRow($_REQUEST['table'], $key); $fksprops = $this->_getFKProps(); echo '
'.PHP_EOL; $elements = 0; $error = true; if (1 == $resultset->recordCount() && $attrs->recordCount() > 0) { echo ''.PHP_EOL; // Output table header echo ""; echo "".PHP_EOL; echo ""; $i = 0; while (!$attrs->EOF) { $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); $id = (0 == ($i % 2) ? '1' : '2'); // Initialise variables if (!isset($_REQUEST['format'][$attrs->fields['attname']])) { $_REQUEST['format'][$attrs->fields['attname']] = 'VALUE'; } echo "".PHP_EOL; echo ''; echo ''; ++$elements; echo '".PHP_EOL; ++$elements; echo ''.PHP_EOL; ++$elements; } else { echo ' '; } echo "'; ++$elements; echo ''.PHP_EOL; ++$i; $attrs->moveNext(); } echo '
{$this->lang['strcolumn']}{$this->lang['strtype']}{$this->lang['strformat']}{$this->lang['strnull']}{$this->lang['strvalue']}
', $this->misc->printVal($attrs->fields['attname']), ''.PHP_EOL; echo $this->misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])); echo ''.PHP_EOL; echo '\n'; // Output null box if the column allows nulls (doesn't look at CHECKs or ASSERTIONS) if (!$attrs->fields['attnotnull']) { // Set initial null values if ( 'confeditrow' == $_REQUEST['action'] && null === $resultset->fields[$attrs->fields['attname']] ) { $_REQUEST['nulls'][$attrs->fields['attname']] = 'on'; } echo "fields['attnum']}\" style=\"white-space:nowrap;\">"; $extras = []; // If the column allows nulls, then we put a JavaScript action on the data field to unset the // NULL checkbox as soon as anything is entered in the field. We use the $elements variable to // keep track of which element offset we're up to. We can't refer to the null checkbox by name // as it contains '[' and ']' characters. if (!$attrs->fields['attnotnull']) { $extras['class'] = 'insert_row_input'; } if ((false !== $fksprops) && isset($fksprops['byfield'][$attrs->fields['attnum']])) { $extras['id'] = "attr_{$attrs->fields['attnum']}"; $extras['autocomplete'] = 'off'; } echo $data->printField("values[{$attrs->fields['attname']}]", $resultset->fields[$attrs->fields['attname']], $attrs->fields['type'], $extras); echo '
'.PHP_EOL; $error = false; } elseif (1 != $resultset->recordCount()) { echo "

{$this->lang['strrownotunique']}

".PHP_EOL; } else { echo "

{$this->lang['strinvalidparam']}

".PHP_EOL; } echo ''.PHP_EOL; echo $this->misc->form; echo isset($_REQUEST['table']) ? sprintf('%s', htmlspecialchars($_REQUEST['table']), PHP_EOL) : ''; echo isset($_REQUEST['subject']) ? sprintf('%s', htmlspecialchars($_REQUEST['subject']), PHP_EOL) : ''; echo isset($_REQUEST['query']) ? sprintf('%s', htmlspecialchars($_REQUEST['query']), PHP_EOL) : ''; echo isset($_REQUEST['count']) ? sprintf('%s', htmlspecialchars($_REQUEST['count']), PHP_EOL) : ''; echo isset($_REQUEST['return']) ? sprintf('%s', htmlspecialchars($_REQUEST['return']), PHP_EOL) : ''; echo ''.PHP_EOL; echo ''.PHP_EOL; echo ''.PHP_EOL; echo ''.PHP_EOL; echo ''.PHP_EOL; echo '

'; if (!$error) { echo "lang['strsave']}\" />".PHP_EOL; } echo "lang['strcancel']}\" />".PHP_EOL; if (false !== $fksprops) { $autocomplete_string = ""; if ('default off' != $this->conf['autocomplete']) { $autocomplete_string = ""; } echo $autocomplete_string.PHP_EOL; } echo '

'.PHP_EOL; echo '
'.PHP_EOL; echo ''; } /** * Performs actual edition of row. */ public function doEditRow() { $data = $this->misc->getDatabaseAccessor(); $key = $this->_unserializeIfNotArray($_REQUEST, 'key'); $this->coalesceArr($_POST, 'values', []); $this->coalesceArr($_POST, 'nulls', []); $status = $data->editRow( $_POST['table'], $_POST['values'], $_POST['nulls'], $_POST['format'], $_POST['types'], $key ); if (0 == $status) { return $this->doBrowse($this->lang['strrowupdated']); } if ($status == -2) { return $this->formEditRow($this->lang['strrownotunique']); } return $this->formEditRow($this->lang['strrowupdatedbad']); } /** * Show confirmation of drop and perform actual drop. * * @param mixed $confirm */ public function doDelRow($confirm) { $data = $this->misc->getDatabaseAccessor(); if ($confirm) { $this->printTrail($_REQUEST['subject']); $this->printTitle($this->lang['strdeleterow']); $resultset = $data->browseRow($_REQUEST['table'], $_REQUEST['key']); echo '
'.PHP_EOL; echo $this->misc->form; if (1 == $resultset->recordCount()) { echo "

{$this->lang['strconfdeleterow']}

".PHP_EOL; $fkinfo = []; echo ''; $this->printTableHeaderCells($resultset, false, true); echo ''; echo ''.PHP_EOL; $this->printTableRowCells($resultset, $fkinfo, true); echo ''.PHP_EOL; echo '
'.PHP_EOL; echo '
'.PHP_EOL; echo ''.PHP_EOL; echo "lang['stryes']}\" />".PHP_EOL; echo "lang['strno']}\" />".PHP_EOL; } elseif (1 != $resultset->recordCount()) { echo "

{$this->lang['strrownotunique']}

".PHP_EOL; echo "lang['strcancel']}\" />".PHP_EOL; } else { echo "

{$this->lang['strinvalidparam']}

".PHP_EOL; echo "lang['strcancel']}\" />".PHP_EOL; } if (isset($_REQUEST['table'])) { echo ''.PHP_EOL; } if (isset($_REQUEST['subject'])) { echo ''.PHP_EOL; } if (isset($_REQUEST['query'])) { echo ''.PHP_EOL; } if (isset($_REQUEST['count'])) { echo ''.PHP_EOL; } if (isset($_REQUEST['return'])) { echo ''.PHP_EOL; } echo ''.PHP_EOL; echo ''.PHP_EOL; echo ''.PHP_EOL; echo ''.PHP_EOL; echo ''.PHP_EOL; echo '
'.PHP_EOL; } else { $status = $data->deleteRow($_POST['table'], unserialize(urldecode($_POST['key']))); if (0 == $status) { $this->doBrowse($this->lang['strrowdeleted']); } elseif ($status == -2) { $this->doBrowse($this->lang['strrownotunique']); } else { $this->doBrowse($this->lang['strrowdeletedbad']); } } } /** * Build & return the FK information data structure * used when deciding if a field should have a FK link or not. * * @return array associative array describing the FK */ public function &getFKInfo() { $data = $this->misc->getDatabaseAccessor(); // Get the foreign key(s) information from the current table $fkey_information = ['byconstr' => [], 'byfield' => []]; if (isset($_REQUEST['table'])) { $constraints = $data->getConstraintsWithFields($_REQUEST['table']); if ($constraints->recordCount() > 0) { $fkey_information['common_url'] = $this->misc->getHREF('schema').'&subject=table'; // build the FK constraints data structure while (!$constraints->EOF) { $constr = &$constraints->fields; if ('f' == $constr['contype']) { if (!isset($fkey_information['byconstr'][$constr['conid']])) { $fkey_information['byconstr'][$constr['conid']] = [ 'url_data' => 'table='.urlencode($constr['f_table']).'&schema='.urlencode($constr['f_schema']), 'fkeys' => [], 'consrc' => $constr['consrc'], ]; } $fkey_information['byconstr'][$constr['conid']]['fkeys'][$constr['p_field']] = $constr['f_field']; if (!isset($fkey_information['byfield'][$constr['p_field']])) { $fkey_information['byfield'][$constr['p_field']] = []; } $fkey_information['byfield'][$constr['p_field']][] = $constr['conid']; } $constraints->moveNext(); } } } return $fkey_information; } // Print the FK row, used in ajax requests public function doBrowseFK() { $data = $this->misc->getDatabaseAccessor(); $ops = []; foreach ($_REQUEST['fkey'] as $x => $y) { $ops[$x] = '='; } $query = $data->getSelectSQL($_REQUEST['table'], [], $_REQUEST['fkey'], $ops); $_REQUEST['query'] = $query; $fkinfo = $this->getFKInfo(); $max_pages = 1; // Retrieve page from query. $max_pages is returned by reference. $resultset = $data->browseQuery( 'SELECT', $_REQUEST['table'], $_REQUEST['query'], null, null, 1, 1, $max_pages ); echo '[delete]'.PHP_EOL; echo '
'; if (is_object($resultset) && $resultset->recordCount() > 0) { /* we are browsing a referenced table here * we should show OID if show_oids is true * so we give true to withOid in functions bellow */ echo ''; $this->printTableHeaderCells($resultset, false, true); echo ''; echo ''.PHP_EOL; $this->printTableRowCells($resultset, $fkinfo, true); echo ''.PHP_EOL; echo '
'.PHP_EOL; } else { echo $this->lang['strnodata']; } echo '
'; } private function _getMinMaxPages($page, $pages) { $window = 10; if ($page <= $window) { $min_page = 1; $max_page = min(2 * $window, $pages); } elseif ($page > $window && $pages >= $page + $window) { $min_page = ($page - $window) + 1; $max_page = $page + $window; } else { $min_page = ($page - (2 * $window - ($pages - $page))) + 1; $max_page = $pages; } // Make sure min_page is always at least 1 // and max_page is never greater than $pages $min_page = max($min_page, 1); $max_page = min($max_page, $pages); return [$min_page, $max_page]; } /** * Do multi-page navigation. Displays the prev, next and page options. * * @param int $page - the page currently viewed * @param int $pages - the maximum number of pages * @param array $gets - the parameters to include in the link to the wanted page * @param int $max_width - the number of pages to make available at any one time (default = 20) * * @return string the pagination links */ private function _printPages($page, $pages, $gets, $max_width = 20) { $lang = $this->lang; $page = (int) $page; if ($page < 0 || $page > $pages || $pages <= 1 || $max_width <= 0) { return; } unset($gets['page']); $url = http_build_query($gets); $result = '

'.PHP_EOL; if ($page != 1) { $result .= sprintf('%s%s ', $url, $lang['strfirst'], PHP_EOL); $result .= sprintf('%s%s', $url, $page - 1, $lang['strprev'], PHP_EOL); } list($min_page, $max_page) = $this->_getMinMaxPages($page, $pages); for ($i = $min_page; $i <= $max_page; ++$i) { $result .= (($i === $page) ? $i : sprintf('%s', $url, $i, $i)).PHP_EOL; } if ($page != $pages) { $result .= sprintf('%s%s', $url, $page + 1, $lang['strnext'], PHP_EOL); $result .= sprintf(' %s%s', $url, $pages, $lang['strlast'], PHP_EOL); } $result .= '

'.PHP_EOL; return $result; } }