From 23b05fc8823bbab2f79480968c2783266df3d971 Mon Sep 17 00:00:00 2001 From: chriskl Date: Mon, 2 May 2005 15:47:23 +0000 Subject: [PATCH] Merge DEV_TREE into HEAD. May as well get this ball rolling. --- CREDITS | 2 +- HISTORY | 5 + TRANSLATORS | 8 +- aggregates.php | 24 +- all_db.php | 47 +- bottombar.php | 16 - browser.php | 355 +----- classes/ArrayRecordSet.php | 32 + classes/Misc.php | 659 ++++++++-- classes/Reports.php | 15 +- classes/database/Postgres.php | 18 +- classes/database/Postgres71.php | 12 +- classes/database/Postgres72.php | 6 +- classes/database/Postgres73.php | 6 +- classes/database/Postgres80.php | 12 +- constraints.php | 10 +- conversions.php | 24 +- database.php | 101 +- dataexport.php | 61 +- dbexport.php | 46 +- display.php | 8 +- domains.php | 31 +- functions.php | 56 +- groups.php | 11 +- images/themes/default/I.png | Bin 0 -> 105 bytes images/themes/default/L.png | Bin 0 -> 110 bytes images/themes/default/Lminus.png | Bin 0 -> 125 bytes images/themes/default/Lplus.png | Bin 0 -> 130 bytes images/themes/default/T.png | Bin 0 -> 109 bytes images/themes/default/Tminus.png | Bin 0 -> 126 bytes images/themes/default/Tplus.png | Bin 0 -> 131 bytes images/themes/default/blank.png | Bin 0 -> 100 bytes images/themes/default/file.png | Bin 0 -> 209 bytes images/themes/default/folder.png | Bin 0 -> 185 bytes images/themes/default/folderOpen.png | Bin 0 -> 205 bytes images/themes/default/loading.gif | Bin 0 -> 834 bytes images/themes/default/root.png | Bin 0 -> 185 bytes images/themes/default/title.png | Bin 3726 -> 3679 bytes index.php | 35 +- indexes.php | 4 +- intro.php | 39 +- lang/english.php | 14 +- lang/translations.php | 73 ++ libraries/decorator.inc.php | 206 ++++ libraries/errorhandler.inc.php | 4 +- libraries/lib.inc.php | 152 ++- login.php | 196 +-- opclasses.php | 27 +- operators.php | 38 +- redirect.php | 7 +- reports.php | 27 +- sequences.php | 31 +- servers.php | 133 ++ sqledit.php | 118 +- tables.php | 35 +- tablespaces.php | 20 +- tblproperties.php | 21 +- themes/default/global.css | 57 +- topbar.php | 56 - triggers.php | 4 +- types.php | 47 +- users.php | 29 +- viewproperties.php | 13 +- views.php | 36 +- xloadtree/xloadtree2.js | 534 +++++++++ xloadtree/xmlextras.js | 232 ++++ xloadtree/xtree2.js | 1664 ++++++++++++++++++++++++++ 67 files changed, 4385 insertions(+), 1032 deletions(-) delete mode 100644 bottombar.php create mode 100644 classes/ArrayRecordSet.php create mode 100644 images/themes/default/I.png create mode 100644 images/themes/default/L.png create mode 100644 images/themes/default/Lminus.png create mode 100644 images/themes/default/Lplus.png create mode 100644 images/themes/default/T.png create mode 100644 images/themes/default/Tminus.png create mode 100644 images/themes/default/Tplus.png create mode 100644 images/themes/default/blank.png create mode 100644 images/themes/default/file.png create mode 100644 images/themes/default/folder.png create mode 100644 images/themes/default/folderOpen.png create mode 100644 images/themes/default/loading.gif create mode 100644 images/themes/default/root.png create mode 100644 lang/translations.php create mode 100644 libraries/decorator.inc.php create mode 100644 servers.php delete mode 100755 topbar.php create mode 100644 xloadtree/xloadtree2.js create mode 100644 xloadtree/xmlextras.js create mode 100644 xloadtree/xtree2.js diff --git a/CREDITS b/CREDITS index 6d4f23d2..45caa9e0 100644 --- a/CREDITS +++ b/CREDITS @@ -57,4 +57,4 @@ Contributors Third Party Libraries - Highlight.php (Jacob D. Cohen of rafb.net) - +- XLoadTree2 (Erik Arvidsson & Emil A Eklund of webfx.eae.net) diff --git a/HISTORY b/HISTORY index 9c4f1d42..bc6c3c8c 100644 --- a/HISTORY +++ b/HISTORY @@ -15,6 +15,11 @@ Features * primary key and unique key at table creation (Andreas Huber) * Add row|statement level options to create trigger for >= 7.4 (Robert Treat) * Allow altering name (for >= 7.4) and owner (for >= 8.0) of a database (Bryan Encina) +* Allow login to several servers simultaneously +* Rearrange frame layout to suit multi-server support +* New browser tree with dynamically loading branches + (Using XLoadTree from http://webfx.eae.net/) +* Allow language change on the fly Bugs * Tree Icons are displayed middle instead of top diff --git a/TRANSLATORS b/TRANSLATORS index ba0aad6f..f4bffe6b 100644 --- a/TRANSLATORS +++ b/TRANSLATORS @@ -54,11 +54,11 @@ find the rest of these steps too difficult. language's characters as well as the characters of the language in your database. -8. To add your language to phpPgAdmin's login screen, edit the - libraries/lib.inc.php file and add your language to the $appLangFiles array. +8. To add your language to phpPgAdmin, edit the lang/translations.php file + and add your language to the $appLangFiles array. You must include the HTML encoded version of your language's name. You can - get this from the recoded version of your translated strings file. Also, - edit the login.php and add your language to the list of languages for + get this from the recoded version of your translated strings file. + Also, add your language to the $availableLanguages array for browser auto detection. 9. Send your contribution to us. We need the lib.inc.php entry as well as the diff --git a/aggregates.php b/aggregates.php index e7ab25a1..81a6d21e 100644 --- a/aggregates.php +++ b/aggregates.php @@ -3,7 +3,7 @@ /** * Manage aggregates in a database * - * $Id: aggregates.php,v 1.10 2004/09/20 14:41:38 jollytoad Exp $ + * $Id: aggregates.php,v 1.11 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -46,6 +46,28 @@ $misc->printTable($aggregates, $columns, $actions, $lang['strnoaggregates']); } + /** + * Generate XML for the browser tree. + */ + function doTree() { + global $misc, $data; + + $aggregates = &$data->getAggregates(); + + $proto = concat(field('proname'), ' (', field('proargtypes'), ')'); + + $attrs = array( + 'text' => $proto, + 'icon' => 'functions', + 'toolTip'=> field('aggcomment'), + ); + + $misc->printTreeXML($aggregates, $attrs); + exit; + } + + if ($action == 'tree') doTree(); + $misc->printHeader($lang['straggregates']); $misc->printBody(); diff --git a/all_db.php b/all_db.php index fe763240..28eb728d 100644 --- a/all_db.php +++ b/all_db.php @@ -3,7 +3,7 @@ /** * Manage databases within a server * - * $Id: all_db.php,v 1.37 2005/04/30 18:01:58 soranzo Exp $ + * $Id: all_db.php,v 1.38 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -82,8 +82,8 @@ echo "

", sprintf($lang['strconfdropdatabase'], $misc->printVal($_REQUEST['dropdatabase'])), "

\n"; echo "
\n"; echo "\n"; - echo "\n"; + echo "\n"; + echo "\n"; echo "\n"; echo "\n"; echo "
\n"; @@ -159,6 +159,7 @@ echo "\n"; echo "

\n"; + echo $misc->form; echo "\n"; echo "

\n"; echo "\n"; @@ -229,7 +230,7 @@ echo "
{$lang['strdownload']}

\n"; echo "

\n"; - echo "

\n"; + echo "

\n"; echo $misc->form; echo "

\n"; echo "\n"; @@ -277,17 +278,17 @@ $actions = array( 'properties' => array( 'title' => $lang['strproperties'], - 'url' => 'redirect.php?section=database&', + 'url' => "redirect.php?subject=database&{$misc->href}&", 'vars' => array('database' => 'datname'), ), 'drop' => array( 'title' => $lang['strdrop'], - 'url' => "{$PHP_SELF}?action=confirm_drop&subject=database&", + 'url' => "{$PHP_SELF}?action=confirm_drop&subject=database&{$misc->href}&", 'vars' => array('dropdatabase' => 'datname'), ), 'privileges' => array( 'title' => $lang['strprivileges'], - 'url' => "privileges.php?subject=database&", + 'url' => "privileges.php?subject=database&{$misc->href}&", 'vars' => array('database' => 'datname'), ) ); @@ -304,10 +305,40 @@ $misc->printTable($databases, $columns, $actions, $lang['strnodatabases']); - echo "

{$lang['strcreatedatabase']}

\n"; + echo "

href}\">{$lang['strcreatedatabase']}

\n"; } + + function doTree() { + global $misc, $data, $lang; + + $databases = &$data->getDatabases(); + + $reqvars = $misc->getRequestVars('database'); + + $attrs = array( + 'text' => field('datname'), + 'icon' => 'database', + 'toolTip'=> field('datcomment'), + 'action' => url('redirect.php', + $reqvars, + array('database' => field('datname')) + ), + 'branch' => url('database.php', + $reqvars, + array( + 'action' => 'tree', + 'database' => field('datname') + ) + ), + ); + + $misc->printTreeXML($databases, $attrs); + exit; + } + if ($action == 'tree') doTree(); + $misc->printHeader($lang['strdatabases']); $misc->printBody(); diff --git a/bottombar.php b/bottombar.php deleted file mode 100644 index 10191c7f..00000000 --- a/bottombar.php +++ /dev/null @@ -1,16 +0,0 @@ -printHeader(); - $misc->printBody('bottombar'); - $misc->printFooter(); -?> diff --git a/browser.php b/browser.php index 6b7d1d8d..df42006f 100644 --- a/browser.php +++ b/browser.php @@ -5,316 +5,71 @@ * if you click on a database it shows a list of database objects in that * database. * - * $Id: browser.php,v 1.45 2005/03/11 04:32:10 chriskl Exp $ + * $Id: browser.php,v 1.46 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions + $_no_db_connection = true; include_once('./libraries/lib.inc.php'); - // Include tree classe - include_once('./classes/HTML_TreeMenu/TreeMenu.php'); - // Output header - $misc->printHeader('', "\n"); + $misc->printHeader('', "\n\n"); $misc->printBody('browser'); echo "
\n"; - - // Construct expanding tree - $menu = new HTML_TreeMenu(null, array('usePersistence' => false)); - $root = new HTML_TreeNode(array( - 'text' => $misc->printVal(($conf['servers'][$_SESSION['webdbServerID']]['desc'])), - 'link' => addslashes('redirect.php?section=server&' . SID), - 'icon' => 'folder.gif', - 'expandedIcon' => 'folder-expanded.gif', - 'expanded' => true, - 'linkTarget' => 'detail')); - - // Add root node to menu - $menu->addItem($root); - - /** - * Helper function for adding nodes - * @param $schemanode Node onto which to add - */ - function addNodes(&$schemanode, $querystr) { - global $data, $misc, $lang, $conf; - - // Tables - $table_node = &new HTML_TreeNode(array( - 'text' => $lang['strtables'], - 'link' => addslashes(htmlspecialchars("tables.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/tables.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/tables.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add table folder to schema - $schemanode->addItem($table_node); - - $tables = &$data->getTables(); - while (!$tables->EOF) { - $return_url = urlencode("tblproperties.php?table=" . urlencode($tables->f['relname']) . "&{$querystr}"); - $item_node = &new HTML_TreeNode(array( - 'text' => $misc->printVal($tables->f['relname']), - 'link' => addslashes(htmlspecialchars("redirect.php?section=table&{$querystr}&table=" . urlencode($tables->f['relname']))), - 'icon' => "../../../images/themes/{$conf['theme']}/tables.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/tables.png", - 'expanded' => false, - 'linkTarget' => 'detail', - 'iconLink' => addslashes(htmlspecialchars('display.php?table=' . urlencode($tables->f['relname']) . '&subject=table&' . $querystr . "&return_url={$return_url}&return_desc=" . urlencode($lang['strback']))) - )); - // Add table folder to schema - $table_node->addItem($item_node); - - $tables->moveNext(); - } - - // Views - $view_node = &new HTML_TreeNode(array( - 'text' => $lang['strviews'], - 'link' => addslashes(htmlspecialchars("views.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/views.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/views.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add view folder to schema - $schemanode->addItem($view_node); - - $views = &$data->getViews(); - while (!$views->EOF) { - $return_url = urlencode("viewproperties.php?view=" . urlencode($views->f['relname']) . "&{$querystr}"); - $item_node = &new HTML_TreeNode(array( - 'text' => $misc->printVal($views->f['relname']), - 'link' => addslashes(htmlspecialchars("redirect.php?section=view&{$querystr}&view=" . - urlencode($views->f['relname']))), - 'icon' => "../../../images/themes/{$conf['theme']}/views.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/views.png", - 'expanded' => false, - 'linkTarget' => 'detail', - // XXX: FIX BROWSE - 'iconLink' => addslashes(htmlspecialchars('display.php?view='.urlencode($views->f['relname']).'&subject=view&'.$querystr. - "&return_url={$return_url}&return_desc=" . urlencode($lang['strback']))) - )); - // Add view folder to schema - $view_node->addItem($item_node); - - $views->moveNext(); - } - - // Sequences - $seq_node = &new HTML_TreeNode(array( - 'text' => $lang['strsequences'], - 'link' => addslashes(htmlspecialchars("sequences.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/sequences.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/sequences.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add folder to schema - $schemanode->addItem($seq_node); - - // Functions - $func_node = &new HTML_TreeNode(array( - 'text' => $lang['strfunctions'], - 'link' => addslashes(htmlspecialchars("functions.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/functions.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/functions.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add folder to schema - $schemanode->addItem($func_node); - - // Domains - if ($data->hasDomains()) { - $dom_node = &new HTML_TreeNode(array( - 'text' => $lang['strdomains'], - 'link' => addslashes(htmlspecialchars("domains.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/domains.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/domains.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - - // Add folder to schema - $schemanode->addItem($dom_node); - } - - // Advanced - if ($conf['show_advanced']) { - $adv_node = &new HTML_TreeNode(array( - 'text' => $lang['stradvanced'], -# 'link' => ($data->hasSchemas()) ? addslashes(htmlspecialchars("schema.php?{$querystr}&" . SID)) : null, - 'icon' => 'folder.gif', - 'expandedIcon' => 'folder-expanded.gif', - 'linkTarget' => 'detail')); - // Add folder to schema - $schemanode->addItem($adv_node); - - // Aggregates - $agg_node = &new HTML_TreeNode(array( - 'text' => $lang['straggregates'], - 'link' => addslashes(htmlspecialchars("aggregates.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add folder to schema - $adv_node->addItem($agg_node); - - // Types - $type_node = &new HTML_TreeNode(array( - 'text' => $lang['strtypes'], - 'link' => addslashes(htmlspecialchars("types.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add folder to schema - $adv_node->addItem($type_node); - - // Operators - $opr_node = &new HTML_TreeNode(array( - 'text' => $lang['stroperators'], - 'link' => addslashes(htmlspecialchars("operators.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/operators.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/operators.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add folder to schema - $adv_node->addItem($opr_node); - - // Operator Classes - $opc_node = &new HTML_TreeNode(array( - 'text' => $lang['stropclasses'], - 'link' => addslashes(htmlspecialchars("opclasses.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/operators.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/operators.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add folder to schema - $adv_node->addItem($opc_node); - - // Conversions - if ($data->hasConversions()) { - $con_node = &new HTML_TreeNode(array( - 'text' => $lang['strconversions'], - 'link' => addslashes(htmlspecialchars("conversions.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - - // Add folder to schema - $adv_node->addItem($con_node); - } - } - } - - $databases = &$data->getDatabases(isset($_REQUEST['database']) ? $_REQUEST['database'] : NULL); - while (!$databases->EOF) { - // If database is selected, show folder, otherwise show document - if (isset($_REQUEST['database']) && $_REQUEST['database'] == $databases->f['datname']) { - // Very ugly hack to work around the fact that the PEAR HTML_Tree can't have links with embedded - // apostrophes create the get string we need to append - $querystr = 'database=' . urlencode($databases->f['datname']) . '&' . SID; - $db_node = &new HTML_TreeNode(array( - 'text' => $misc->printVal($databases->f['datname']), - 'link' => addslashes(htmlspecialchars("redirect.php?section=database&{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/database.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/database.png", - 'expanded' => true, - 'linkTarget' => 'detail')); - - // If database supports schemas, add the extra level of hierarchy - if ($data->hasSchemas()) { - $schemas = &$data->getSchemas(); - while (!$schemas->EOF) { - $data->setSchema($schemas->f['nspname']); - // Construct database & schema query string - $querystr = 'database=' . urlencode($databases->f['datname']). '&schema=' . - urlencode($schemas->f['nspname']) . '&' . SID; - $schemanode = &new HTML_TreeNode(array( - 'text' => $misc->printVal($schemas->f['nspname']), - 'link' => addslashes(htmlspecialchars("redirect.php?section=schema&{$querystr}")), - 'icon' => 'folder.gif', - 'expandedIcon' => 'folder-expanded.gif', - // Auto-expand your personal schema, if it exists. Also expand schema if there is - // only one schema in the database. - 'expanded' => ($schemas->f['nspname'] == $_SESSION['webdbUsername'] - || $schemas->recordCount() == 1), - 'linkTarget' => 'detail')); - - addNodes($schemanode, $querystr); - - // Add schema to database - $db_node->addItem($schemanode); - - $schemas->moveNext(); - } - } - // Database doesn't support schemas - else { - // Construct database query string - $querystr = 'database=' . urlencode($databases->f['datname']) . '&' . SID; - - addNodes($db_node, $querystr); - } - - // Reset database query string - $querystr = 'database=' . urlencode($databases->f['datname']) . '&' . SID; - - // Languages - if ($conf['show_advanced']) { - $lang_node = &new HTML_TreeNode(array( - 'text' => $lang['strlanguages'], - 'link' => addslashes(htmlspecialchars("languages.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - // Add folder to database - $db_node->addItem($lang_node); - - // Casts - if ($data->hasCasts()) { - $cast_node = &new HTML_TreeNode(array( - 'text' => $lang['strcasts'], - 'link' => addslashes(htmlspecialchars("casts.php?{$querystr}")), - 'icon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png", - 'expanded' => false, - 'linkTarget' => 'detail')); - - // Add folder to database - $db_node->addItem($cast_node); - } - } - - // Add node to menu - $root->addItem($db_node); +?> - } else { - // Very ugly hack to work around the fact that the PEAR HTML_Tree can't have links with embedded - // apostrophes create the get string we need to append - $jsLink = '?database=' . addslashes(htmlspecialchars(urlencode($databases->f['datname']) . '&' . SID)); - $jsLink = "javascript:updateLinks(' + \"'{$jsLink}'\" + ')"; - $db_node = &new HTML_TreeNode(array( - 'text' => $misc->printVal($databases->f['datname']), - 'link' => $jsLink, - 'icon' => "../../../images/themes/{$conf['theme']}/database.png", - 'expandedIcon' => "../../../images/themes/{$conf['theme']}/database.png", - 'expanded' => false, - 'linkTarget' => '_self')); - - // Add node to menu - $root->addItem($db_node); - } - - $databases->moveNext(); - } - // Create the presentation class - $treeMenu = &new HTML_TreeMenu_DHTML($menu, array('images' => 'classes/HTML_TreeMenu/images', 'defaultClass' => 'treeMenuDefault')); - - // Actually display the menu - $treeMenu->printMenu(); + + + + +\n"; $misc->printFooter(); diff --git a/classes/ArrayRecordSet.php b/classes/ArrayRecordSet.php new file mode 100644 index 00000000..f05e0dbd --- /dev/null +++ b/classes/ArrayRecordSet.php @@ -0,0 +1,32 @@ +_array = $data; + $this->_count = count($this->_array); + $this->f = reset($this->_array); + if ($this->f === false) $this->EOF = true; + } + + function recordCount() { + return $this->_count; + } + + function moveNext() { + $this->f = next($this->_array); + if ($this->f === false) $this->EOF = true; + } +} + +?> diff --git a/classes/Misc.php b/classes/Misc.php index 5c604992..1cd892f7 100644 --- a/classes/Misc.php +++ b/classes/Misc.php @@ -2,7 +2,7 @@ /** * Class to hold various commonly used functions * - * $Id: Misc.php,v 1.99 2005/04/11 15:15:44 chriskl Exp $ + * $Id: Misc.php,v 1.100 2005/05/02 15:47:25 chriskl Exp $ */ class Misc { @@ -21,45 +21,32 @@ * @return True, dumps are set up, false otherwise */ function isDumpEnabled($all = false) { - global $conf; - - if ($all) - return ($conf['servers'][$_SESSION['webdbServerID']]['pg_dumpall_path'] !== null - && $conf['servers'][$_SESSION['webdbServerID']]['pg_dumpall_path'] != ''); - else - return ($conf['servers'][$_SESSION['webdbServerID']]['pg_dump_path'] !== null - && $conf['servers'][$_SESSION['webdbServerID']]['pg_dump_path'] != ''); + $info = $this->getServerInfo(); + return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']); } /** - * Checks whether a login is allowed - * @return True if login is allowed to be used + * Sets the href tracking variable */ - function checkExtraSecurity() { - global $conf; - - // Disallowed logins if extra_login_security is enabled. These must be lowercase. - $bad_usernames = array('pgsql', 'postgres', 'root', 'administrator'); - - // If extra security is off, return true - if (!$conf['extra_login_security']) return true; - elseif ($_SESSION['webdbPassword'] == '') return false; - else { - $username = strtolower($_SESSION['webdbUsername']); - return !in_array($username, $bad_usernames); - } + function setHREF() { + $this->href = $this->getHREF(); } - + /** - * Sets the href tracking variable + * Get a href query string, excluding objects below the given object type (inclusive) */ - function setHREF() { - $this->href = ''; - if (isset($_REQUEST['database'])) { - $this->href .= 'database=' . urlencode($_REQUEST['database']); - if (isset($_REQUEST['schema'])) - $this->href .= '&schema=' . urlencode($_REQUEST['schema']); + function getHREF($exclude_from = null) { + $href = ''; + if (isset($_REQUEST['server']) && $exclude_from != 'server') { + $href .= 'server=' . urlencode($_REQUEST['server']); + if (isset($_REQUEST['database']) && $exclude_from != 'database') { + $href .= '&database=' . urlencode($_REQUEST['database']); + if (isset($_REQUEST['schema']) && $exclude_from != 'schema') { + $href .= '&schema=' . urlencode($_REQUEST['schema']); + } + } } + return $href; } /** @@ -67,10 +54,14 @@ */ function setForm() { $this->form = ''; - if (isset($_REQUEST['database'])) { - $this->form .= "\n"; - if (isset($_REQUEST['schema'])) - $this->form .= "\n"; + if (isset($_REQUEST['server'])) { + $this->form .= "\n"; + if (isset($_REQUEST['database'])) { + $this->form .= "\n"; + if (isset($_REQUEST['schema'])) { + $this->form .= "\n"; + } + } } } @@ -264,27 +255,50 @@ /** * Creates a database accessor */ - function &getDatabaseAccessor($database) { - global $conf; + function &getDatabaseAccessor($database, $server_id = null) { + global $lang, $conf, $misc; + + $server_info = $this->getServerInfo($server_id); + // Perform extra security checks if this config option is set + if ($conf['extra_login_security']) { + // Disallowed logins if extra_login_security is enabled. + // These must be lowercase. + $bad_usernames = array('pgsql', 'postgres', 'root', 'administrator'); + + $username = strtolower($server_info['username']); + + if ($server_info['password'] == '' || in_array($username, $bad_usernames)) { + unset($_SESSION['webdbLogin'][$_REQUEST['server']]); + $msg = $lang['strlogindisallowed']; + include('./login.php'); + exit; + } + } + // Create the connection object and make the connection $_connection = new Connection( - $conf['servers'][$_SESSION['webdbServerID']]['host'], - $conf['servers'][$_SESSION['webdbServerID']]['port'], - $_SESSION['webdbUsername'], - $_SESSION['webdbPassword'], + $server_info['host'], + $server_info['port'], + $server_info['username'], + $server_info['password'], $database ); - // Get the name of the database driver we need to use. The description - // of the server is returned and placed into the conf array. - $_type = $_connection->getDriver($desc); - // XXX: NEED TO CHECK RETURN STATUS HERE - + // Get the name of the database driver we need to use. + // The description of the server is returned in $platform. + $_type = $_connection->getDriver($platform); + if ($_type === null) { + printf($lang['strpostgresqlversionnotsupported'], $postgresqlMinVer); + exit; + } + $this->setServerInfo('platform', $platform, $server_id); + // Create a database wrapper class for easy manipulation of the // connection. include_once('./classes/database/' . $_type . '.php'); - $data = &new $_type($_connection->conn); + $data =& new $_type($_connection->conn); + $data->platform = $_connection->platform; return $data; } @@ -405,7 +419,7 @@ $active = ($tab_id == $activetab) ? ' active' : ''; if (!isset($tab['hide']) || $tab['hide'] !== true) { - $tablink = "printVal($tab['url'], 'nbsp') . "\">{$tab['title']}"; + $tablink = "printActionUrl($tab, $_REQUEST, 'href') . ">{$tab['title']}"; echo ""; @@ -428,271 +442,362 @@ function getNavTabs($section) { global $data, $lang, $conf; - $databasevar = isset($_REQUEST['database']) ? 'database=' . urlencode($_REQUEST['database']) : ''; - $schemavar = isset($_REQUEST['schema']) ? '&schema=' . urlencode($_REQUEST['schema']) : ''; +# $servervar = isset($_REQUEST['server']) ? 'server=' . urlencode($_REQUEST['server']) : ''; +# $databasevar = isset($_REQUEST['database']) ? '&database=' . urlencode($_REQUEST['database']) : ''; +# $schemavar = isset($_REQUEST['schema']) ? '&schema=' . urlencode($_REQUEST['schema']) : ''; $hide_advanced = ($conf['show_advanced'] === false); switch ($section) { + case 'root': + return array ( + 'intro' => array ( + 'title' => $lang['strintroduction'], + 'url' => "intro.php", + ), + 'servers' => array ( + 'title' => $lang['strservers'], + 'url' => "servers.php", + ), + ); + case 'server': - $hide_users = !$data->isSuperUser($_SESSION['webdbUsername']); +# $vars = $servervar . $databasevar . '&subject=server'; + $server_info = $this->getServerInfo(); + $hide_users = !$data->isSuperUser($server_info['username']); + #$hide_users = false; return array ( 'databases' => array ( 'title' => $lang['strdatabases'], - 'url' => "all_db.php", + 'url' => 'all_db.php', + 'urlvars' => array('subject' => 'server'), 'help' => 'pg.database', ), 'users' => array ( 'title' => $lang['strusers'], - 'url' => "users.php", + 'url' => 'users.php', + 'urlvars' => array('subject' => 'server'), 'hide' => $hide_users, 'help' => 'pg.user', ), 'groups' => array ( 'title' => $lang['strgroups'], - 'url' => "groups.php", + 'url' => 'groups.php', + 'urlvars' => array('subject' => 'server'), 'hide' => $hide_users, 'help' => 'pg.group', ), + 'account' => array ( + 'title' => $lang['straccount'], + 'url' => 'users.php', + 'urlvars' => array('subject' => 'server', 'action' => 'action'), + 'hide' => !$hide_users, + 'help' => 'pg.user', + ), 'tablespaces' => array ( 'title' => $lang['strtablespaces'], - 'url' => "tablespaces.php", + 'url' => 'tablespaces.php', + 'urlvars' => array('subject' => 'server'), 'hide' => (!$data->hasTablespaces()), 'help' => 'pg.tablespace', ), 'export' => array ( 'title' => $lang['strexport'], - 'url' => "all_db.php?action=export", + 'url' => 'all_db.php', + 'urlvars' => array('subject' => 'server', 'action' => 'export'), 'hide' => (!$this->isDumpEnabled()), ), + 'reports' => array ( + 'title' => $lang['strreports'], + 'url' => 'reports.php', + 'urlvars' => array('subject' => 'server'), + ), ); case 'database': - $vars = $databasevar . '&subject=database'; +# $vars = $servervar . $databasevar . '&subject=database'; return array ( 'schemas' => array ( 'title' => $lang['strschemas'], - 'url' => "database.php?{$vars}", + 'url' => 'database.php', + 'urlvars' => array('subject' => 'database'), 'hide' => (!$data->hasSchemas()), 'help' => 'pg.schema', ), 'sql' => array ( 'title' => $lang['strsql'], - 'url' => "database.php?{$vars}&action=sql", + 'url' => 'database.php', + 'urlvars' => array('subject' => 'database', 'action' => 'sql'), 'help' => 'pg.sql', ), 'find' => array ( 'title' => $lang['strfind'], - 'url' => "database.php?{$vars}&action=find", + 'url' => 'database.php', + 'urlvars' => array('subject' => 'database', 'action' => 'find'), ), 'variables' => array ( 'title' => $lang['strvariables'], - 'url' => "database.php?{$vars}&action=variables", + 'url' => 'database.php', + 'urlvars' => array('subject' => 'database', 'action' => 'variables'), 'hide' => (!$data->hasVariables()), 'help' => 'pg.variable', ), 'processes' => array ( 'title' => $lang['strprocesses'], - 'url' => "database.php?{$vars}&action=processes", + 'url' => 'database.php', + 'urlvars' => array('subject' => 'database', 'action' => 'processes'), 'hide' => (!$data->hasProcesses()), 'help' => 'pg.process', ), 'admin' => array ( 'title' => $lang['stradmin'], - 'url' => "database.php?{$vars}&action=admin", + 'url' => 'database.php', + 'urlvars' => array('subject' => 'database', 'action' => 'admin'), ), 'privileges' => array ( 'title' => $lang['strprivileges'], - 'url' => "privileges.php?{$vars}", + 'url' => 'privileges.php', + 'urlvars' => array('subject' => 'database'), 'hide' => (!isset($data->privlist['database'])), 'help' => 'pg.privilege', ), 'languages' => array ( 'title' => $lang['strlanguages'], - 'url' => "languages.php?{$vars}", + 'url' => 'languages.php', + 'urlvars' => array('subject' => 'database'), 'hide' => $hide_advanced, 'help' => 'pg.language', ), 'casts' => array ( 'title' => $lang['strcasts'], - 'url' => "casts.php?{$vars}", + 'url' => 'casts.php', + 'urlvars' => array('subject' => 'database'), 'hide' => ($hide_advanced || !$data->hasCasts()), 'help' => 'pg.cast', ), 'export' => array ( 'title' => $lang['strexport'], - 'url' => "database.php?{$vars}&action=export", + 'url' => 'database.php', + 'urlvars' => array('subject' => 'database', 'action' => 'export'), 'hide' => (!$this->isDumpEnabled()), ), ); case 'schema': - $vars = $databasevar . $schemavar . '&subject=schema'; +# $vars = $servervar . $databasevar . $schemavar . '&subject=schema'; return array ( 'tables' => array ( 'title' => $lang['strtables'], - 'url' => "tables.php?{$vars}", + 'url' => 'tables.php', + 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.table', + 'icon' => 'tables', ), 'views' => array ( 'title' => $lang['strviews'], - 'url' => "views.php?{$vars}", + 'url' => 'views.php', + 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.view', + 'icon' => 'views', ), 'sequences' => array ( 'title' => $lang['strsequences'], - 'url' => "sequences.php?{$vars}", + 'url' => 'sequences.php', + 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.sequence', + 'icon' => 'sequences', ), 'functions' => array ( 'title' => $lang['strfunctions'], - 'url' => "functions.php?{$vars}", + 'url' => 'functions.php', + 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.function', + 'icon' => 'functions', ), 'domains' => array ( 'title' => $lang['strdomains'], - 'url' => "domains.php?{$vars}", + 'url' => 'domains.php', + 'urlvars' => array('subject' => 'schema'), 'hide' => (!$data->hasDomains()), 'help' => 'pg.domain', + 'icon' => 'domains', ), 'aggregates' => array ( 'title' => $lang['straggregates'], - 'url' => "aggregates.php?{$vars}", + 'url' => 'aggregates.php', + 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.aggregate', + 'icon' => 'functions', ), 'types' => array ( 'title' => $lang['strtypes'], - 'url' => "types.php?{$vars}", + 'url' => 'types.php', + 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.type', + 'icon' => 'types', ), 'operators' => array ( 'title' => $lang['stroperators'], - 'url' => "operators.php?{$vars}", + 'url' => 'operators.php', + 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.operator', + 'icon' => 'operators', ), 'opclasses' => array ( 'title' => $lang['stropclasses'], - 'url' => "opclasses.php?{$vars}", + 'url' => 'opclasses.php', + 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.opclass', + 'icon' => 'operators', ), 'conversions' => array ( 'title' => $lang['strconversions'], - 'url' => "conversions.php?{$vars}", + 'url' => 'conversions.php', + 'urlvars' => array('subject' => 'schema'), 'hide' => ($hide_advanced || !$data->hasConversions()), 'help' => 'pg.conversion', + 'icon' => 'types', ), 'privileges' => array ( 'title' => $lang['strprivileges'], - 'url' => "privileges.php?{$vars}", + 'url' => 'privileges.php', + 'urlvars' => array('subject' => 'schema'), 'hide' => (!$data->hasSchemas()), 'help' => 'pg.privilege', ), ); case 'table': - $table = urlencode($_REQUEST['table']); - $vars = $databasevar . $schemavar . "&table={$table}&subject=table"; +# $table = urlencode($_REQUEST['table']); +# $vars = $servervar . $databasevar . $schemavar . "&table={$table}&subject=table"; return array ( 'columns' => array ( 'title' => $lang['strcolumns'], - 'url' => "tblproperties.php?{$vars}", + 'url' => 'tblproperties.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table')), ), 'indexes' => array ( 'title' => $lang['strindexes'], - 'url' => "indexes.php?{$vars}", + 'url' => 'indexes.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.index', ), 'constraints' => array ( 'title' => $lang['strconstraints'], - 'url' => "constraints.php?{$vars}", + 'url' => 'constraints.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.constraint', ), 'triggers' => array ( 'title' => $lang['strtriggers'], - 'url' => "triggers.php?{$vars}", + 'url' => 'triggers.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.trigger', ), 'rules' => array ( 'title' => $lang['strrules'], - 'url' => "rules.php?{$vars}", + 'url' => 'rules.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.rule', ), 'info' => array ( 'title' => $lang['strinfo'], - 'url' => "info.php?{$vars}", + 'url' => 'info.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table')), ), 'privileges' => array ( 'title' => $lang['strprivileges'], - 'url' => "privileges.php?{$vars}", + 'url' => 'privileges.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.privilege', ), 'import' => array ( 'title' => $lang['strimport'], - 'url' => "tblproperties.php?{$vars}&action=import", + 'url' => 'tblproperties.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table'), 'action' => 'import'), ), 'export' => array ( 'title' => $lang['strexport'], - 'url' => "tblproperties.php?{$vars}&action=export", + 'url' => 'tblproperties.php', + 'urlvars' => array('subject' => 'table', 'table' => field('table'), 'action' => 'export'), ), ); case 'view': - $view = urlencode($_REQUEST['view']); - $vars = $databasevar . $schemavar . "&view={$view}&subject=view"; +# $view = urlencode($_REQUEST['view']); +# $vars = $servervar . $databasevar . $schemavar . "&view={$view}&subject=view"; return array ( 'columns' => array ( 'title' => $lang['strcolumns'], - 'url' => "viewproperties.php?{$vars}", + 'url' => 'viewproperties.php', + 'urlvars' => array('subject' => 'view', 'view' => field('view')), ), 'definition' => array ( 'title' => $lang['strdefinition'], - 'url' => "viewproperties.php?{$vars}&action=definition", + 'url' => 'viewproperties.php', + 'urlvars' => array('subject' => 'view', 'view' => field('view'), 'action' => 'definition'), ), 'rules' => array ( 'title' => $lang['strrules'], - 'url' => "rules.php?{$vars}", + 'url' => 'rules.php', + 'urlvars' => array('subject' => 'view', 'view' => field('view')), 'help' => 'pg.rule', ), 'privileges' => array ( 'title' => $lang['strprivileges'], - 'url' => "privileges.php?{$vars}", + 'url' => 'privileges.php', + 'urlvars' => array('subject' => 'view', 'view' => field('view')), 'help' => 'pg.privilege', ), 'export' => array ( 'title' => $lang['strexport'], - 'url' => "viewproperties.php?{$vars}&action=export", + 'url' => 'viewproperties.php', + 'urlvars' => array('subject' => 'view', 'view' => field('view'), 'action' => 'export'), ), ); case 'function': - $funcnam = urlencode($_REQUEST['function']); - $funcoid = urlencode($_REQUEST['function_oid']); - $vars = $databasevar . $schemavar . "&function={$funcnam}&function_oid={$funcoid}&subject=function"; +# $funcnam = urlencode($_REQUEST['function']); +# $funcoid = urlencode($_REQUEST['function_oid']); +# $vars = $servervar . $databasevar . $schemavar . "&function={$funcnam}&function_oid={$funcoid}&subject=function"; return array ( 'definition' => array ( 'title' => $lang['strdefinition'], - 'url' => "functions.php?{$vars}&action=properties", + 'url' => 'functions.php', + 'urlvars' => array( + 'subject' => 'function', + 'function' => field('function'), + 'function_oid' => field('function_oid'), + 'action' => 'properties', + ), ), 'privileges' => array ( 'title' => $lang['strprivileges'], - 'url' => "privileges.php?{$vars}", + 'url' => 'privileges.php', + 'urlvars' => array( + 'subject' => 'function', + 'function' => field('function'), + 'function_oid' => field('function_oid'), + ), ), ); case 'popup': - $vars = $databasevar; +# $vars = $servervar . $databasevar; return array ( 'sql' => array ( 'title' => $lang['strsql'], - 'url' => "sqledit.php?{$vars}&action=sql", + 'url' => 'sqledit.php', + 'urlvars' => array('subject' => 'schema', 'action' => 'sql'), 'help' => 'pg.sql', ), 'find' => array ( 'title' => $lang['strfind'], - 'url' => "sqledit.php?{$vars}&action=find", + 'url' => 'sqledit.php', + 'urlvars' => array('subject' => 'schema', 'action' => 'find'), ), ); @@ -727,12 +832,70 @@ return isset($tab['url']) ? $tab['url'] : null; } + function printTopbar() { + global $lang, $conf, $appName, $appVersion, $appLangFiles; + + $server_info = $this->getServerInfo(); + + echo "
"; + + if (isset($_REQUEST['server'])) { + $url = "sqledit.php?{$this->href}&action="; + + $window_id = htmlspecialchars('sqledit:'.$_REQUEST['server']); + + echo ""; + } +/* + echo ""; +*/ + echo "
"; + + if ($server_info && isset($server_info['platform']) && isset($server_info['username'])) { + echo sprintf($lang['strtopbar'], + ''.htmlspecialchars($server_info['platform']).'', + ''.htmlspecialchars($server_info['host']).'', + ''.htmlspecialchars($server_info['port']).'', + ''.htmlspecialchars($server_info['username']).'', + ''.date($lang['strtimefmt']).''); + } else { + echo "$appName $appVersion"; + } + + echo ""; + + echo "{$lang['strsql']} | "; + + echo "{$lang['strfind']}"; + + echo ""; + + echo "
\n"; + echo "\n"; + foreach ($_GET as $key => $val) { + if ($key == 'language') continue; + echo "\n"; + } + echo "
\n"; + + echo "
\n"; + } + /** * Display a bread crumb trail. */ function printTrail($trail = array()) { global $lang; + $this->printTopbar(); + if (is_string($trail)) { $trail = $this->getTrail($trail); } @@ -768,26 +931,37 @@ * @param $object The type of object at the end of the trail. */ function getTrail($subject = null) { - global $lang, $conf; + global $lang, $conf, $data, $appName; $trail = array(); $vars = ''; $done = false; - $trail['server'] = array( - 'title' => $lang['strserver'], - 'text' => $conf['servers'][$_SESSION['webdbServerID']]['desc'], - 'url' => 'redirect.php?section=server', - 'help' => 'pg.server' + $trail['root'] = array( + 'text' => $appName, + 'url' => 'redirect.php?subject=root', ); + + if ($subject == 'root') $done = true; + + if (!$done) { + $vars = 'server='.urlencode($_REQUEST['server']).'&'; + $server_info = $this->getServerInfo(); + $trail['server'] = array( + 'title' => $lang['strserver'], + 'text' => $server_info['desc'], + 'url' => "redirect.php?subject=server&{$vars}", + 'help' => 'pg.server' + ); + } if ($subject == 'server') $done = true; if (isset($_REQUEST['database']) && !$done) { - $vars = 'database='.urlencode($_REQUEST['database']).'&'; + $vars .= 'database='.urlencode($_REQUEST['database']).'&'; $trail['database'] = array( 'title' => $lang['strdatabase'], 'text' => $_REQUEST['database'], - 'url' => "redirect.php?section=database&{$vars}", + 'url' => "redirect.php?subject=database&{$vars}", 'help' => 'pg.database' ); } @@ -798,14 +972,14 @@ $trail['schema'] = array( 'title' => $lang['strschema'], 'text' => $_REQUEST['schema'], - 'url' => "redirect.php?section=schema&{$vars}", + 'url' => "redirect.php?subject=schema&{$vars}", 'help' => 'pg.schema' ); } if ($subject == 'schema') $done = true; if (isset($_REQUEST['table']) && !$done) { - $vars .= "section=table&table=".urlencode($_REQUEST['table']); + $vars .= "subject=table&table=".urlencode($_REQUEST['table']); $trail['table'] = array( 'title' => $lang['strtable'], 'text' => $_REQUEST['table'], @@ -813,7 +987,7 @@ 'help' => 'pg.table' ); } elseif (isset($_REQUEST['view']) && !$done) { - $vars .= "section=view&view=".urlencode($_REQUEST['view']); + $vars .= "subject=view&view=".urlencode($_REQUEST['view']); $trail['view'] = array( 'title' => $lang['strview'], 'text' => $_REQUEST['view'], @@ -827,7 +1001,7 @@ switch ($subject) { case 'function': $vars .= "{$subject}_oid=".urlencode($_REQUEST[$subject.'_oid']).'&'; - $vars .= "section={$subject}&{$subject}=".urlencode($_REQUEST[$subject]); + $vars .= "subject={$subject}&{$subject}=".urlencode($_REQUEST[$subject]); $trail[$subject] = array( 'title' => $lang['str'.$subject], 'text' => $_REQUEST[$subject], @@ -918,7 +1092,7 @@ echo $str; if ($help) { echo "{$lang['strhelpicon']}"; } } @@ -934,6 +1108,18 @@ echo "-->\n"; echo "\n"; } + + /** + * Outputs JavaScript to set the name of the browser window. + * @param $name the window name + * @param $addServer if true (default) then the server id is + * attached to the name. + */ + function setWindowName($name, $addServer = true) { + echo "\n"; + } /** * Converts a PHP.INI size variable to bytes. Taken from publically available @@ -941,7 +1127,7 @@ * @param $strIniSize The PHP.INI variable * @return size in bytes, false on failure */ - function inisizeToBytes($strIniSize) { + function inisizeToBytes($strIniSize) { // This function will take the string value of an ini 'size' parameter, // and return a double (64-bit float) representing the number of bytes // that the parameter represents. Or false if $strIniSize is unparseable. @@ -965,8 +1151,73 @@ default: return $nSize; } - } + } + + /** + * Display a URL given an action associative array. + * @param $action An associative array of the follow properties: + * 'url' => The first part of the URL (before the ?) + * 'urlvars' => Associative array of (URL variable => field name) + * these are appended to the URL + * 'urlfn' => Function to apply to URL before display + * @param $fields Field data from which 'urlfield' and 'vars' are obtained. + * @param $attr If supplied then the URL will be quoted and prefixed with + * '$attr='. + */ + function printActionUrl(&$action, &$fields, $attr = null) { + $url = value($action['url'], $fields); + + if ($url === false) return ''; + + if (!empty($action['urlvars'])) { + $urlvars = value($action['urlvars'], $fields); + } else { + $urlvars = array(); + } + + if (isset($urlvars['subject'])) { + $subject = value($urlvars['subject'], $fields); + if (isset($_REQUEST['server']) && $subject != 'root') { + $urlvars['server'] = $_REQUEST['server']; + if (isset($_REQUEST['database']) && $subject != 'server') { + $urlvars['database'] = $_REQUEST['database']; + if (isset($_REQUEST['schema']) && $subject != 'database') { + $urlvars['schema'] = $_REQUEST['schema']; + } + } + } + } + + $sep = '?'; + foreach ($urlvars as $var => $varfield) { + $url .= $sep . value_url($var, $fields) . '=' . value_url($varfield, $fields); + $sep = '&'; + } + + $url = htmlentities($url); + + if ($attr !== null && $url != '') + return ' '.$attr.'="'.$url.'"'; + else + return $url; + } + function getRequestVars($subject = '') { + $v = array(); + if (!empty($subject)) + $v['subject'] = $subject; + if (isset($_REQUEST['server']) && $subject != 'root') { + $v['server'] = $_REQUEST['server']; + if (isset($_REQUEST['database']) && $subject != 'server') { + $v['database'] = $_REQUEST['database']; + if (isset($_REQUEST['schema']) && $subject != 'database') { + $v['schema'] = $_REQUEST['schema']; + } + } + } + return $v; + } + function printUrlVars(&$vars, &$fields) { foreach ($vars as $var => $varfield) { echo "{$var}=", urlencode($fields[$varfield]), "&"; @@ -1067,7 +1318,7 @@ switch ($column_id) { case 'actions': foreach ($alt_actions as $action) { - if (isset($action['disable'])) { + if (isset($action['disable']) && $action['disable'] === true) { echo ""; } else { echo ""; @@ -1079,15 +1330,17 @@ break; default; echo ""; - if (isset($column['url'])) { - echo "printUrlVars($column['vars'], $tabledata->f); - echo "\">"; - } + if (isset($tabledata->f[$column['field']])) { + if (isset($column['url'])) { + echo "printUrlVars($column['vars'], $tabledata->f); + echo "\">"; + } - $type = isset($column['type']) ? $column['type'] : null; - $params = isset($column['params']) ? $column['params'] : array(); - echo $misc->printVal($tabledata->f[$column['field']], $type, $params); + $type = isset($column['type']) ? $column['type'] : null; + $params = isset($column['params']) ? $column['params'] : array(); + echo $misc->printVal($tabledata->f[$column['field']], $type, $params); + } if (isset($column['url'])) echo ""; @@ -1112,6 +1365,69 @@ } } + /** Produce XML data for the browser tree + * @param $treedata A set of records to populate the tree. + * @param $attrs Attributes for tree items + * 'text' - the text for the tree node + * 'icon' - an icon for node + * 'openIcon' - an alternative icon when the node is expanded + * 'toolTip' - tool tip text for the node + * 'action' - URL to visit when single clicking the node + * 'branch' - URL for child nodes (tree XML) + * 'expand' - the action to return XML for the subtree + * 'nodata' - message to display when node has no children + */ + function printTreeXML(&$treedata, &$attrs) { + global $conf, $lang; + header("Content-Type: text/xml"); + header("Cache-Control: no-cache"); + + echo "\n"; + + echo "\n"; + + if ($treedata->recordCount() > 0) { + while (!$treedata->EOF) { + $rec =& $treedata->f; + + echo "icon(value($attrs['icon'], $rec)); + echo value_xml_attr('icon', $icon, $rec); + + if (!empty($attrs['openIcon'])) { + $icon = $this->icon(value($attrs['openIcon'], $rec)); + } + echo value_xml_attr('openIcon', $icon, $rec); + + echo value_xml_attr('toolTip', $attrs['toolTip'], $rec); + + echo "/>\n"; + + $treedata->moveNext(); + } + } else { + $msg = isset($attrs['nodata']) ? $attrs['nodata'] : $lang['strnoobjects']; + echo "icon('error'), "\"/>\n"; + } + + echo "\n"; + } + + function icon($icon) { + global $conf; + $path = "images/themes/{$conf['theme']}/{$icon}"; + if (file_exists($path.'.png')) return $path.'.png'; + if (file_exists($path.'.gif')) return $path.'.gif'; + $path = "images/themes/default/{$icon}"; + if (file_exists($path.'.png')) return $path.'.png'; + if (file_exists($path.'.gif')) return $path.'.gif'; + return ''; + } + /** * Function to escape command line parameters * @param $str The string to escape @@ -1150,5 +1466,88 @@ else return escapeshellcmd($str); } + + /** + * Get list of servers + * @param $recordset return as RecordSet suitable for printTable if true, + * otherwise just return an array. + */ + function &getServers($recordset = false) { + global $conf; + + $srvs = isset($_SESSION['webdbLogin']) && is_array($_SESSION['webdbLogin']) ? $_SESSION['webdbLogin'] : array(); + + foreach($conf['servers'] as $idx => $info) { + $server_id = $info['host'].':'.$info['port']; + + if (!isset($srvs[$server_id])) { + $srvs[$server_id] = $info; + } + $srvs[$server_id]['id'] = $server_id; + } + + function _cmp_desc($a, $b) { + return strcmp($a['desc'], $b['desc']); + } + uasort($srvs, '_cmp_desc'); + + if ($recordset) { + include_once('classes/ArrayRecordSet.php'); + return new ArrayRecordSet($srvs); + } + return $srvs; + } + + /** + * Get information on a server. + * If the parameter isn't supplied then the currently + * connected server is returned. + * @param $server_id A server identifier (host:port) + * @return An associative array of server properties + */ + function getServerInfo($server_id = null) { + global $conf; + + if ($server_id === null && isset($_REQUEST['server'])) + $server_id = $_REQUEST['server']; + + // Check for the server in the logged-in list + if (isset($_SESSION['webdbLogin'][$server_id])) + return $_SESSION['webdbLogin'][$server_id]; + + // Otherwise, look for it in the conf file + foreach($conf['servers'] as $idx => $info) { + if ($server_id == $info['host'].':'.$info['port']) + return $info; + } + + return null; + } + + /** + * Set server information. + * @param $key parameter name to set, or null to replace all + * params with the assoc-array in $value. + * @param $value the new value, or null to unset the parameter + * @param $server_id the server identifier, or null for current + * server. + */ + function setServerInfo($key, $value, $server_id = null) + { + if ($server_id === null && isset($_REQUEST['server'])) + $server_id = $_REQUEST['server']; + + if ($key === null) { + if ($value === null) + unset($_SESSION['webdbLogin'][$server_id]); + else + $_SESSION['webdbLogin'][$server_id] = $value; + } else { + if ($value === null) + unset($_SESSION['webdbLogin'][$server_id][$key]); + else + $_SESSION['webdbLogin'][$server_id][$key] = $value; + } + } } ?> diff --git a/classes/Reports.php b/classes/Reports.php index 8cabfcea..65fe2e19 100644 --- a/classes/Reports.php +++ b/classes/Reports.php @@ -4,7 +4,7 @@ * the functions provided by the database driver exclusively, and hence * will work with any database without modification. * - * $Id: Reports.php,v 1.11 2004/07/01 07:15:11 chriskl Exp $ + * $Id: Reports.php,v 1.12 2005/05/02 15:47:26 chriskl Exp $ */ class Reports { @@ -34,10 +34,11 @@ * @return A recordset */ function &getReports() { - global $conf; + global $conf, $misc; // Filter for owned reports if necessary if ($conf['owned_reports_only']) { - $filter['created_by'] = $_SESSION['webdbUsername']; + $server_info = $misc->getServerInfo(); + $filter['created_by'] = $server_info['username']; $ops = array('created_by' => '='); } else $filter = $ops = array(); @@ -71,10 +72,12 @@ * @return 0 success */ function createReport($report_name, $db_name, $descr, $report_sql) { + global $misc; + $server_info = $misc->getServerInfo(); $temp = array( 'report_name' => $report_name, 'db_name' => $db_name, - 'created_by' => $_SESSION['webdbUsername'], + 'created_by' => $server_info['username'], 'report_sql' => $report_sql ); if ($descr != '') $temp['descr'] = $descr; @@ -92,10 +95,12 @@ * @return 0 success */ function alterReport($report_id, $report_name, $db_name, $descr, $report_sql) { + global $misc; + $server_info = $misc->getServerInfo(); $temp = array( 'report_name' => $report_name, 'db_name' => $db_name, - 'created_by' => $_SESSION['webdbUsername'], + 'created_by' => $server_info['username'], 'report_sql' => $report_sql ); if ($descr != '') $temp['descr'] = $descr; diff --git a/classes/database/Postgres.php b/classes/database/Postgres.php index 30cf2da1..cf8c28d3 100755 --- a/classes/database/Postgres.php +++ b/classes/database/Postgres.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres.php,v 1.260 2005/04/30 18:01:59 soranzo Exp $ + * $Id: Postgres.php,v 1.261 2005/05/02 15:47:26 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -407,10 +407,12 @@ class Postgres extends ADODB_base { * @return A list of databases, sorted alphabetically */ function &getDatabases($currentdatabase = NULL) { - global $conf; + global $conf, $misc; - if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($_SESSION['webdbUsername'])) { - $username = $_SESSION['webdbUsername']; + $server_info = $misc->getServerInfo(); + + if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($server_info['username'])) { + $username = $server_info['username']; $this->clean($username); $clause = " AND pu.usename='{$username}'"; } @@ -3353,7 +3355,9 @@ class Postgres extends ADODB_base { pt.typname AS proresult, pl.lanname AS prolanguage, oidvectortypes(pc.proargtypes) AS proarguments, - (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment + (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment, + proname || ' (' || proarguments || ')' AS proproto, + CASE WHEN proretset THEN 'setof ' ELSE '' END || pt.typname AS proreturns FROM pg_proc pc, pg_user pu, pg_type pt, pg_language pl WHERE @@ -3368,7 +3372,9 @@ class Postgres extends ADODB_base { proretset, 'OPAQUE' AS proresult, oidvectortypes(pc.proargtypes) AS proarguments, - (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment + (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment, + proname || ' (' || proarguments || ')' AS proproto, + CASE WHEN proretset THEN 'setof ' ELSE '' END || 'OPAQUE' AS proreturns FROM pg_proc pc, pg_user pu, pg_type pt WHERE diff --git a/classes/database/Postgres71.php b/classes/database/Postgres71.php index bf828ac5..bf35f02f 100644 --- a/classes/database/Postgres71.php +++ b/classes/database/Postgres71.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres71.php,v 1.70 2005/02/06 20:03:20 soranzo Exp $ + * $Id: Postgres71.php,v 1.71 2005/05/02 15:47:26 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -86,10 +86,12 @@ class Postgres71 extends Postgres { * @return A list of databases, sorted alphabetically */ function &getDatabases($currentdatabase = NULL) { - global $conf; - - if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($_SESSION['webdbUsername'])) { - $username = $_SESSION['webdbUsername']; + global $conf, $misc; + + $server_info = $misc->getServerInfo(); + + if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($server_info['username'])) { + $username = $server_info['username']; $this->clean($username); $clause = " AND pu.usename='{$username}'"; } diff --git a/classes/database/Postgres72.php b/classes/database/Postgres72.php index 8f6da669..54d850a8 100644 --- a/classes/database/Postgres72.php +++ b/classes/database/Postgres72.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres72.php,v 1.78 2004/11/10 01:46:36 chriskl Exp $ + * $Id: Postgres72.php,v 1.79 2005/05/02 15:47:26 chriskl Exp $ */ @@ -324,7 +324,9 @@ class Postgres72 extends Postgres71 { false AS proretset, format_type(p.prorettype, NULL) AS proresult, oidvectortypes(p.proargtypes) AS proarguments, - (SELECT description FROM pg_description pd WHERE p.oid=pd.objoid) AS procomment + (SELECT description FROM pg_description pd WHERE p.oid=pd.objoid) AS procomment, + p.proname || ' (' || oidvectortypes(p.proargtypes) || ')' AS proproto, + format_type(p.prorettype, NULL) AS proreturns FROM pg_proc p WHERE diff --git a/classes/database/Postgres73.php b/classes/database/Postgres73.php index 14f3b9bd..0ea905c1 100644 --- a/classes/database/Postgres73.php +++ b/classes/database/Postgres73.php @@ -4,7 +4,7 @@ * A class that implements the DB interface for Postgres * Note: This class uses ADODB and returns RecordSets. * - * $Id: Postgres73.php,v 1.142 2004/12/06 02:48:34 chriskl Exp $ + * $Id: Postgres73.php,v 1.143 2005/05/02 15:47:26 chriskl Exp $ */ // @@@ THOUGHT: What about inherits? ie. use of ONLY??? @@ -720,7 +720,9 @@ class Postgres73 extends Postgres72 { pg_catalog.format_type(p.prorettype, NULL) AS proresult, pg_catalog.oidvectortypes(p.proargtypes) AS proarguments, pl.lanname AS prolanguage, - pg_catalog.obj_description(p.oid, 'pg_proc') AS procomment + pg_catalog.obj_description(p.oid, 'pg_proc') AS procomment, + p.proname || ' (' || pg_catalog.oidvectortypes(p.proargtypes) || ')' AS proproto, + CASE WHEN p.proretset THEN 'setof ' ELSE '' END || pg_catalog.format_type(p.prorettype, NULL) AS proreturns FROM pg_catalog.pg_proc p INNER JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace INNER JOIN pg_catalog.pg_language pl ON pl.oid = p.prolang diff --git a/classes/database/Postgres80.php b/classes/database/Postgres80.php index 9d9855fc..abba2611 100644 --- a/classes/database/Postgres80.php +++ b/classes/database/Postgres80.php @@ -3,7 +3,7 @@ /** * PostgreSQL 8.0 support * - * $Id: Postgres80.php,v 1.12 2005/04/30 18:02:01 soranzo Exp $ + * $Id: Postgres80.php,v 1.13 2005/05/02 15:47:26 chriskl Exp $ */ include_once('./classes/database/Postgres74.php'); @@ -48,10 +48,12 @@ class Postgres80 extends Postgres74 { * @return A list of databases, sorted alphabetically */ function &getDatabases($currentdatabase = NULL) { - global $conf; - - if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($_SESSION['webdbUsername'])) { - $username = $_SESSION['webdbUsername']; + global $conf, $misc; + + $server_info = $misc->getServerInfo(); + + if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($server_info['username'])) { + $username = $server_info['username']; $this->clean($username); $clause = " AND pu.usename='{$username}'"; } diff --git a/constraints.php b/constraints.php index 85776870..0dcdd954 100644 --- a/constraints.php +++ b/constraints.php @@ -3,7 +3,7 @@ /** * List constraints on a table * - * $Id: constraints.php,v 1.40 2004/09/07 13:58:21 jollytoad Exp $ + * $Id: constraints.php,v 1.41 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -478,13 +478,13 @@ $misc->printTable($constraints, $columns, $actions, $lang['strnoconstraints'], 'cnPre'); - echo "

href}&table=", urlencode($_REQUEST['table']), + echo "

href}&table=", urlencode($_REQUEST['table']), "\">{$lang['straddcheck']} |\n"; - echo "href}&table=", urlencode($_REQUEST['table']), + echo "href}&table=", urlencode($_REQUEST['table']), "\">{$lang['stradduniq']} |\n"; - echo "href}&table=", urlencode($_REQUEST['table']), + echo "href}&table=", urlencode($_REQUEST['table']), "\">{$lang['straddpk']} |\n"; - echo "href}&table=", urlencode($_REQUEST['table']), + echo "href}&table=", urlencode($_REQUEST['table']), "\">{$lang['straddfk']}

\n"; } diff --git a/conversions.php b/conversions.php index 7437e0dc..316bcb1a 100644 --- a/conversions.php +++ b/conversions.php @@ -3,7 +3,7 @@ /** * Manage conversions in a database * - * $Id: conversions.php,v 1.9 2004/09/01 16:35:58 jollytoad Exp $ + * $Id: conversions.php,v 1.10 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -54,7 +54,27 @@ $misc->printTable($conversions, $columns, $actions, $lang['strnoconversions']); } - + + /** + * Generate XML for the browser tree. + */ + function doTree() { + global $misc, $data; + + $conversions = &$data->getconversions(); + + $attrs = array( + 'text' => field('conname'), + 'icon' => 'conversions', + 'toolTip'=> field('concomment') + ); + + $misc->printTreeXML($conversions, $attrs); + exit; + } + + if ($action == 'tree') doTree(); + $misc->printHeader($lang['strconversions']); $misc->printBody(); diff --git a/database.php b/database.php index a3726770..a3aee0ca 100755 --- a/database.php +++ b/database.php @@ -3,7 +3,7 @@ /** * Manage schemas within a database * - * $Id: database.php,v 1.65 2004/11/29 01:48:38 chriskl Exp $ + * $Id: database.php,v 1.66 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -318,7 +318,7 @@ } echo "

\n"; echo "

\n"; - echo "

\n"; + echo "\n"; echo $misc->form; echo "

\n"; echo "\n"; @@ -389,11 +389,13 @@ if ($data->hasSignals()) { $columns['actions'] = array('title' => $lang['stractions']); - + + $href = $misc->getHREF('schema'); + $actions = array( 'cancel' => array( 'title' => $lang['strcancel'], - 'url' => "{$PHP_SELF}?action=signal&signal=CANCEL&database=" . urlencode($_REQUEST['database']) . "&", + 'url' => "{$PHP_SELF}?action=signal&signal=CANCEL&{$href}&", 'vars' => array('procpid' => 'procpid') ) ); @@ -427,7 +429,7 @@ $status = $data->recluster(); if ($status == 0) doAdmin('', $lang['strclusteredgood']); else doAdmin('', $lang['strclusteredbad']); - break; + break; case 'reindex'; $status = $data->reindex('DATABASE', $_REQUEST['database'], isset($_REQUEST['reindex_force'])); if ($status == 0) doAdmin('', $lang['strreindexgood']); @@ -549,6 +551,7 @@ echo "

", sprintf($lang['strconfdropschema'], $misc->printVal($_REQUEST['schema'])), "

\n"; echo "
\n"; + echo $misc->form; echo "\n"; echo "\n"; echo "\n"; @@ -579,8 +582,10 @@ global $data, $misc; global $PHP_SELF, $lang; + $server_info = $misc->getServerInfo(); + if (!isset($_POST['formName'])) $_POST['formName'] = ''; - if (!isset($_POST['formAuth'])) $_POST['formAuth'] = $_SESSION['webdbUsername']; + if (!isset($_POST['formAuth'])) $_POST['formAuth'] = $server_info['username']; if (!isset($_POST['formSpc'])) $_POST['formSpc'] = ''; if (!isset($_POST['formComment'])) $_POST['formComment'] = ''; @@ -592,6 +597,7 @@ $misc->printMsg($msg); echo "\n"; + echo $misc->form; echo "\n"; echo "\t\n\t\t\n"; echo "\t\t
{$lang['strname']}_maxNameLen}\" value=\"", @@ -673,39 +679,107 @@ ), ); + $href = $misc->getHREF('schema'); + $actions = array( 'properties' => array( 'title' => $lang['strproperties'], - 'url' => "redirect.php?section=schema&database=".urlencode($_REQUEST['database'])."&", + 'url' => "redirect.php?subject=schema&{$href}&", 'vars' => array('schema' => 'nspname'), ), 'drop' => array( 'title' => $lang['strdrop'], - 'url' => "{$PHP_SELF}?action=confirm_drop&database=".urlencode($_REQUEST['database'])."&", + 'url' => "{$PHP_SELF}?action=confirm_drop&{$href}&", 'vars' => array('schema' => 'nspname'), ), 'privileges' => array( 'title' => $lang['strprivileges'], - 'url' => "privileges.php?subject=schema&database=".urlencode($_REQUEST['database'])."&", + 'url' => "privileges.php?subject=schema&{$href}&", 'vars' => array('schema' => 'nspname'), ), 'alter' => array( 'title' => $lang['stralter'], - 'url' => "{$PHP_SELF}?action=alter_schema&database=".urlencode($_REQUEST['database'])."&", + 'url' => "{$PHP_SELF}?action=alter_schema&{$href}&", 'vars' => array('schema' => 'nspname'), ), ); $misc->printTable($schemas, $columns, $actions, $lang['strnoschemas']); - echo "

{$lang['strcreateschema']}

\n"; + echo "

{$lang['strcreateschema']}

\n"; } else { // If the database does not support schemas... echo "

{$lang['strnoschemas']}

\n"; } } + function doTree() { + global $misc, $data, $lang, $PHP_SELF; + + $schemas = &$data->getSchemas(); + + $reqvars = $misc->getRequestVars('schema'); + + $attrs = array( + 'text' => field('nspname'), + 'icon' => 'folder', + 'toolTip'=> field('nspcomment'), + 'action' => url('redirect.php', + $reqvars, + array( + 'subject' => 'schema', + 'schema' => field('nspname') + ) + ), + 'branch' => url('database.php', + $reqvars, + array( + 'action' => 'subtree', + 'schema' => field('nspname') + ) + ) + ); + + $misc->printTreeXML($schemas, $attrs); + exit; + } + + function doSubTree() { + global $misc, $data, $lang; + + include_once('classes/ArrayRecordSet.php'); + $tabs = $misc->getNavTabs('schema'); + + // Remove Privileges link + unset($tabs['privileges']); + + // Remove hidden links + foreach ($tabs as $i => $tab) { + if (isset($tab['hide']) && $tab['hide'] === true) + unset($tabs[$i]); + } + $items =& new ArrayRecordSet($tabs); + + $reqvars = $misc->getRequestVars('schema'); + + $attrs = array( + 'text' => noEscape(field('title')), + 'icon' => field('icon', 'folder'), + 'action' => url(field('url'), + $reqvars, + field('urlvars', array()) + ), + 'branch' => url(field('url'), + $reqvars, + field('urlvars'), + array('action' => 'tree') + ) + ); + + $misc->printTreeXML($items, $attrs); + exit; + } + /** * Display a form to permit editing schema properies. * TODO: permit changing name, owner @@ -753,6 +827,9 @@ doAlterSchema($lang['strschemaalteredbad']); } + if ($action == 'tree') doTree(); + if ($action == 'subtree') doSubTree(); + $misc->printHeader($lang['strschemas']); $misc->printBody(); diff --git a/dataexport.php b/dataexport.php index 983cba88..fc9212f3 100644 --- a/dataexport.php +++ b/dataexport.php @@ -4,7 +4,7 @@ * Does an export to the screen or as a download. This checks to * see if they have pg_dump set up, and will use it if possible. * - * $Id: dataexport.php,v 1.19 2005/03/04 02:27:29 chriskl Exp $ + * $Id: dataexport.php,v 1.20 2005/05/02 15:47:23 chriskl Exp $ */ $extensions = array( @@ -23,28 +23,19 @@ // What must we do in this case? Maybe redirect to the homepage? // If format is set, then perform the export - if (isset($_REQUEST['what'])) { - + if (isset($_REQUEST['what'])) { + // Include application functions $_no_output = true; include_once('./libraries/lib.inc.php'); - + switch ($_REQUEST['what']) { case 'dataonly': // Check to see if they have pg_dump set up and if they do, use that // instead of custom dump code if ($misc->isDumpEnabled() && ($_REQUEST['d_format'] == 'copy' || $_REQUEST['d_format'] == 'sql')) { - $url = 'dbexport.php?mode=database&database=' . urlencode($_REQUEST['database']); - $url .= '&what=' . urlencode($_REQUEST['what']); - $url .= '&table=' . urlencode($_REQUEST['table']); - if ($data->hasSchemas()) $url .= '&schema=' . urlencode($_REQUEST['schema']); - $url .= '&d_format=' . urlencode($_REQUEST['d_format']); - $url .= '&output=' . urlencode($_REQUEST['output']); - if (isset($_REQUEST['d_oids'])) $url .= '&d_oids=' . urlencode($_REQUEST['d_oids']); - $url .= "&" . SID; - - header("Location: {$url}"); + include('./dbexport.php'); exit; } else { @@ -56,15 +47,7 @@ // Check to see if they have pg_dump set up and if they do, use that // instead of custom dump code if ($misc->isDumpEnabled()) { - $url = 'dbexport.php?mode=database&database=' . urlencode($_REQUEST['database']); - $url .= '&what=' . urlencode($_REQUEST['what']); - $url .= '&table=' . urlencode($_REQUEST['table']); - if ($data->hasSchemas()) $url .= '&schema=' . urlencode($_REQUEST['schema']); - $url .= '&output=' . urlencode($_REQUEST['output']); - if (isset($_REQUEST['s_clean'])) $url .= '&s_clean=' . urlencode($_REQUEST['s_clean']); - $url .= "&" . SID; - - header("Location: {$url}"); + include('./dbexport.php'); exit; } else $clean = isset($_REQUEST['s_clean']); @@ -73,17 +56,7 @@ // Check to see if they have pg_dump set up and if they do, use that // instead of custom dump code if ($misc->isDumpEnabled()) { - $url = 'dbexport.php?mode=database&database=' . urlencode($_REQUEST['database']); - $url .= '&what=' . urlencode($_REQUEST['what']); - $url .= '&table=' . urlencode($_REQUEST['table']); - if ($data->hasSchemas()) $url .= '&schema=' . urlencode($_REQUEST['schema']); - $url .= '&sd_format=' . urlencode($_REQUEST['sd_format']); - $url .= '&output=' . urlencode($_REQUEST['output']); - if (isset($_REQUEST['sd_clean'])) $url .= '&sd_clean=' . urlencode($_REQUEST['sd_clean']); - if (isset($_REQUEST['sd_oids'])) $url .= '&sd_oids=' . urlencode($_REQUEST['sd_oids']); - $url .= "&" . SID; - - header("Location: {$url}"); + include('./dbexport.php'); exit; } else { @@ -101,7 +74,7 @@ if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS'])) { header('Content-Type: text/plain'); } - else { + else { header('Content-Type: application/download'); if (isset($extensions[$format])) @@ -118,6 +91,11 @@ if (isset($_REQUEST['query'])) $_REQUEST['query'] = trim(unserialize($_REQUEST['query'])); + // Set the schema search path + if ($data->hasSchemas() && isset($_REQUEST['search_path'])) { + $data->setSearchPath(array_map('trim',explode(',',$_REQUEST['search_path']))); + } + // Set up the dump transaction $status = $data->beginDump(); @@ -321,14 +299,14 @@ $status = $data->endDump(); } else { - if (!isset($msg)) $msg = null; - // Include application functions include_once('./libraries/lib.inc.php'); - $misc->printHeader($lang['strexport']); - echo "

", $misc->printVal($_REQUEST['database']), ": {$lang['strexport']}

\n"; - $misc->printMsg($msg); + $misc->printHeader($lang['strexport']); + $misc->printBody(); + $misc->printTrail(isset($_REQUEST['subject']) ? $_REQUEST['subject'] : 'database'); + $misc->printTitle($lang['strexport']); + if (isset($msg)) $misc->printMsg($msg); echo "\n"; echo "\n"; @@ -355,6 +333,9 @@ echo "\n"; } echo "\n"; + if (isset($_REQUEST['search_path'])) { + echo "\n"; + } echo $misc->form; echo "

\n"; echo "\n"; diff --git a/dbexport.php b/dbexport.php index b4c9662f..18cc0017 100644 --- a/dbexport.php +++ b/dbexport.php @@ -3,7 +3,7 @@ * Does an export of a database or a table (via pg_dump) * to the screen or as a download. * - * $Id: dbexport.php,v 1.20 2005/04/12 01:52:16 chriskl Exp $ + * $Id: dbexport.php,v 1.21 2005/05/02 15:47:23 chriskl Exp $ */ // Prevent timeouts on large exports (non-safe mode only) @@ -40,36 +40,32 @@ } // Set environmental variables that pg_dump uses - putenv('PGPASSWORD=' . $_SESSION['webdbPassword']); - putenv('PGUSER=' . $_SESSION['webdbUsername']); - $hostname = $conf['servers'][$_SESSION['webdbServerID']]['host']; + $server_info = $misc->getServerInfo(); + putenv('PGPASSWORD=' . $server_info['password']); + putenv('PGUSER=' . $server_info['username']); + $hostname = $server_info['host']; if ($hostname !== null && $hostname != '') { putenv('PGHOST=' . $hostname); } - $port = $conf['servers'][$_SESSION['webdbServerID']]['port']; + $port = $server_info['port']; if ($port !== null && $port != '') { putenv('PGPORT=' . $port); } - if ($_REQUEST['mode'] == 'database') { - putenv('PGDATABASE=' . $_REQUEST['database']); - } - // Check if we're doing a cluster-wide dump or just a per-database dump - if ($_REQUEST['mode'] == 'database') { - // Get path of the pg_dump executable. - $exe = $misc->escapeShellCmd($conf['servers'][$_SESSION['webdbServerID']]['pg_dump_path']); - } - else { - // Get path of the pg_dumpall executable. - $exe = $misc->escapeShellCmd($conf['servers'][$_SESSION['webdbServerID']]['pg_dumpall_path']); - } + // Are we doing a cluster-wide dump or just a per-database dump + $dumpall = ($_REQUEST['subject'] == 'server'); + + // Get the path og the pg_dump/pg_dumpall executable + $exe = $misc->escapeShellCmd($server_info[$dumpall ? 'pg_dumpall_path' : 'pg_dump_path']); // Build command for executing pg_dump. '-i' means ignore version differences. $cmd = $exe . " -i"; - // Check for a table specified - if (isset($_REQUEST['table']) && $_REQUEST['mode'] == 'database') { - + + // Check for a specified table/view + switch ($_REQUEST['subject']) { + case 'table': + case 'view': // Obtain the pg_dump version number $version = array(); preg_match("/(\d+(?:\.\d+)?)(?:\.\d+)?.*$/", exec($exe . " --version"), $version); @@ -78,7 +74,7 @@ // set dump schema as well. Also, mixed case dumping has been fixed // then.. if (((float) $version[1]) >= 7.4) { - $cmd .= " -t " . $misc->escapeShellArg($_REQUEST['table']); + $cmd .= " -t " . $misc->escapeShellArg($_REQUEST[$_REQUEST['subject']]); // Even though they're using a schema-enabled pg_dump, the backend database // may not support schemas. if ($data->hasSchemas()) { @@ -88,12 +84,12 @@ else { // This is an annoying hack needed to work around a bug in dumping // mixed case tables in pg_dump prior to 7.4 - $cmd .= " -t " . $misc->escapeShellArg('"' . $_REQUEST['table'] . '"'); + $cmd .= " -t " . $misc->escapeShellArg('"' . $_REQUEST[$_REQUEST['subject']] . '"'); } } // Check for GZIP compression specified - if ($_REQUEST['output'] == 'gzipped' && $_REQUEST['mode'] == 'database') { + if ($_REQUEST['output'] == 'gzipped' && !$dumpall) { $cmd .= " -Z 9"; } @@ -113,6 +109,10 @@ if (isset($_REQUEST['sd_clean'])) $cmd .= ' -c'; break; } + + if (!$dumpall) { + putenv('PGDATABASE=' . $_REQUEST['database']); + } // Execute command and return the output to the screen passthru($cmd); diff --git a/display.php b/display.php index 4ade6141..fa335c1d 100644 --- a/display.php +++ b/display.php @@ -9,7 +9,7 @@ * @param $return_desc The return link name * @param $page The current page * - * $Id: display.php,v 1.48 2005/03/04 02:27:38 chriskl Exp $ + * $Id: display.php,v 1.49 2005/05/02 15:47:23 chriskl Exp $ */ // Prevent timeouts on large exports (non-safe mode only) @@ -398,8 +398,10 @@ // Report views don't set a schema, so we need to disable create view in that case if (isset($_REQUEST['schema'])) echo " | href}\">{$lang['strcreateview']}\n"; - echo " | href}\">{$lang['strdownload']}\n"; + echo " | href}\">{$lang['strdownload']}\n"; } // Insert diff --git a/domains.php b/domains.php index f9d5ef3a..aa1d33a5 100644 --- a/domains.php +++ b/domains.php @@ -3,7 +3,7 @@ /** * Manage domains in a database * - * $Id: domains.php,v 1.19 2004/09/07 13:58:21 jollytoad Exp $ + * $Id: domains.php,v 1.20 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -424,6 +424,35 @@ echo "

href}\">{$lang['strcreatedomain']}

\n"; } + + /** + * Generate XML for the browser tree. + */ + function doTree() { + global $misc, $data, $PHP_SELF; + + $domains = &$data->getDomains(); + + $reqvars = $misc->getRequestVars('domain'); + + $attrs = array( + 'text' => field('domname'), + 'icon' => 'domains', + 'toolTip'=> field('domcomment'), + 'action' => url('domains.php', + $reqvars, + array( + 'action' => 'properties', + 'domain' => field('domname') + ) + ) + ); + + $misc->printTreeXML($domains, $attrs); + exit; + } + + if ($action == 'tree') doTree(); $misc->printHeader($lang['strdomains']); $misc->printBody(); diff --git a/functions.php b/functions.php index ded185b8..d24e0fad 100644 --- a/functions.php +++ b/functions.php @@ -3,7 +3,7 @@ /** * Manage functions in a database * - * $Id: functions.php,v 1.47 2004/09/18 11:59:40 soranzo Exp $ + * $Id: functions.php,v 1.48 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -470,12 +470,6 @@ global $data, $conf, $misc, $func; global $PHP_SELF, $lang; - function fnPre(&$rowdata) { - global $data; - $rowdata->f['+proproto'] = $rowdata->f['proname'] . " (" . $rowdata->f['proarguments'] . ")"; - $rowdata->f['+proreturns'] = ($data->phpBool($rowdata->f['proretset']) ? 'setof ' : '') . $rowdata->f['proresult']; - } - $misc->printTrail('schema'); $misc->printTabs('schema','functions'); $misc->printMsg($msg); @@ -485,12 +479,12 @@ $columns = array( 'function' => array( 'title' => $lang['strfunction'], - 'field' => '+proproto', + 'field' => 'proproto', 'type' => 'verbatim', ), 'returns' => array( 'title' => $lang['strreturns'], - 'field' => '+proreturns', + 'field' => 'proreturns', 'type' => 'verbatim', ), 'proglanguage' => array( @@ -509,33 +503,65 @@ $actions = array( 'properties' => array( 'title' => $lang['strproperties'], - 'url' => "redirect.php?section=function&action=properties&{$misc->href}&", - 'vars' => array('function' => '+proproto', 'function_oid' => 'prooid'), + 'url' => "redirect.php?subject=function&action=properties&{$misc->href}&", + 'vars' => array('function' => 'proproto', 'function_oid' => 'prooid'), ), 'alter' => array( 'title' => $lang['stralter'], 'url' => "{$PHP_SELF}?action=edit&{$misc->href}&", - 'vars' => array('function' => '+proproto', 'function_oid' => 'prooid'), + 'vars' => array('function' => 'proproto', 'function_oid' => 'prooid'), ), 'drop' => array( 'title' => $lang['strdrop'], 'url' => "{$PHP_SELF}?action=confirm_drop&{$misc->href}&", - 'vars' => array('function' => '+proproto', 'function_oid' => 'prooid'), + 'vars' => array('function' => 'proproto', 'function_oid' => 'prooid'), ), 'privileges' => array( 'title' => $lang['strprivileges'], 'url' => "privileges.php?{$misc->href}&subject=function&", - 'vars' => array('function' => '+proproto', 'function_oid' => 'prooid'), + 'vars' => array('function' => 'proproto', 'function_oid' => 'prooid'), ), ); - $misc->printTable($funcs, $columns, $actions, $lang['strnofunctions'], 'fnPre'); + $misc->printTable($funcs, $columns, $actions, $lang['strnofunctions']); echo "

href}\">{$lang['strcreateplfunction']} | "; echo "href}\">{$lang['strcreateinternalfunction']} | "; echo "href}\">{$lang['strcreatecfunction']}

\n"; } + /** + * Generate XML for the browser tree. + */ + function doTree() { + global $misc, $data; + + $funcs = &$data->getFunctions(); + + $proto = concat(field('proname'),' (',field('proarguments'),')'); + + $reqvars = $misc->getRequestVars('function'); + + $attrs = array( + 'text' => $proto, + 'icon' => 'functions', + 'toolTip' => field('procomment'), + 'action' => url('redirect.php', + $reqvars, + array( + 'action' => 'properties', + 'function' => $proto, + 'function_oid' => field('prooid') + ) + ) + ); + + $misc->printTreeXML($funcs, $attrs); + exit; + } + + if ($action == 'tree') doTree(); + $misc->printHeader($lang['strfunctions']); $misc->printBody(); diff --git a/groups.php b/groups.php index 8ba7318e..870c5914 100644 --- a/groups.php +++ b/groups.php @@ -3,7 +3,7 @@ /** * Manage groups in a database cluster * - * $Id: groups.php,v 1.19 2004/09/07 13:58:21 jollytoad Exp $ + * $Id: groups.php,v 1.20 2005/05/02 15:47:23 chriskl Exp $ */ // Include application functions @@ -41,6 +41,7 @@ echo "

", sprintf($lang['strconfdropmember'], $misc->printVal($_REQUEST['user']), $misc->printVal($_REQUEST['group'])), "

\n"; echo "\n"; + echo $misc->form; echo "\n"; echo "\n"; echo "\n"; @@ -105,7 +106,7 @@ echo "\n"; echo "\n"; - echo "

{$lang['strshowallgroups']}

\n"; + echo "

href}\">{$lang['strshowallgroups']}

\n"; } /** @@ -122,6 +123,7 @@ echo "

", sprintf($lang['strconfdropgroup'], $misc->printVal($_REQUEST['group'])), "

\n"; echo "\n"; + echo $misc->form; echo "\n"; echo "\n"; echo "\n"; @@ -155,6 +157,7 @@ $misc->printMsg($msg); echo "\n"; + echo $misc->form; echo "
\n"; echo "\t\n\t\t\n"; echo "\t\t\n\t\n"; @@ -162,7 +165,7 @@ echo "\t\n\t\t\n"; echo "\t\t
{$lang['strname']}_maxNameLen}\" name=\"name\" value=\"", htmlspecialchars($_POST['name']), "\" />
{$lang['strmembers']}\n"; - echo "\t\t\trecordCount()), "\">\n"; while (!$users->EOF) { $username = $users->f['usename']; echo "\t\t\t\t