getServerInfo(); return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']); } /** * Sets the href tracking variable */ function setHREF() { $this->href = $this->getHREF(); } /** * Get a href query string, excluding objects below the given object type (inclusive) */ 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 htmlentities($href); } function getSubjectParams($subject) { global $plugin_manager; $vars = array(); switch($subject) { case 'root': $vars = array ( 'params' => array( 'subject' => 'root' ) ); break; case 'server': $vars = array ('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'server' )); break; case 'role': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'role', 'action' => 'properties', 'rolename' => $_REQUEST['rolename'] )); break; case 'database': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'database', 'database' => $_REQUEST['database'], )); break; case 'schema': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'schema', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'] )); break; case 'table': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'table', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'table' => $_REQUEST['table'] )); break; case 'selectrows': $vars = array( 'url' => 'tables.php', 'params' => array( 'server' => $_REQUEST['server'], 'subject' => 'table', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'table' => $_REQUEST['table'], 'action' => 'confselectrows' )); break; case 'view': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'view', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'view' => $_REQUEST['view'] )); break; case 'fulltext': case 'ftscfg': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'fulltext', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'action' => 'viewconfig', 'ftscfg' => $_REQUEST['ftscfg'] )); break; case 'function': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'function', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'function' => $_REQUEST['function'], 'function_oid' => $_REQUEST['function_oid'] )); break; case 'aggregate': $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'aggregate', 'action' => 'properties', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'aggrname' => $_REQUEST['aggrname'], 'aggrtype' => $_REQUEST['aggrtype'] )); break; case 'column': if (isset($_REQUEST['table'])) $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'column', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'table' => $_REQUEST['table'], 'column' => $_REQUEST['column'] )); else $vars = array('params' => array( 'server' => $_REQUEST['server'], 'subject' => 'column', 'database' => $_REQUEST['database'], 'schema' => $_REQUEST['schema'], 'view' => $_REQUEST['view'], 'column' => $_REQUEST['column'] )); break; case 'plugin': $vars = array( 'url' => 'plugin.php', 'params' => array( 'server' => $_REQUEST['server'], 'subject' => 'plugin', 'plugin' => $_REQUEST['plugin'], )); if (!is_null($plugin_manager->getPlugin($_REQUEST['plugin']))) $vars['params'] = array_merge($vars['params'], $plugin_manager->getPlugin($_REQUEST['plugin'])->get_subject_params()); break; default: return false; } if (!isset($vars['url'])) $vars['url'] = 'redirect.php'; return $vars; } function getHREFSubject($subject) { $vars = $this->getSubjectParams($subject); return "{$vars['url']}?". http_build_query($vars['params'], '', '&'); } /** * Sets the form tracking variable */ function setForm() { $this->form = ''; if (isset($_REQUEST['server'])) { $this->form .= "\n"; if (isset($_REQUEST['database'])) { $this->form .= "\n"; if (isset($_REQUEST['schema'])) { $this->form .= "\n"; } } } } /** * Render a value into HTML using formatting rules specified * by a type name and parameters. * * @param $str The string to change * * @param $type Field type (optional), this may be an internal PostgreSQL type, or: * yesno - same as bool, but renders as 'Yes' or 'No'. * pre - render in a
 block.
		 *			nbsp     - replace all spaces with  's
		 *			verbatim - render exactly as supplied, no escaping what-so-ever.
		 *			callback - render using a callback function supplied in the 'function' param.
		 *
		 * @param $params Type parameters (optional), known parameters:
		 *			null     - string to display if $str is null, or set to TRUE to use a default 'NULL' string,
		 *			           otherwise nothing is rendered.
		 *			clip     - if true, clip the value to a fixed length, and append an ellipsis...
		 *			cliplen  - the maximum length when clip is enabled (defaults to $conf['max_chars'])
		 *			ellipsis - the string to append to a clipped value (defaults to $lang['strellipsis'])
		 *			tag      - an HTML element name to surround the value.
		 *			class    - a class attribute to apply to any surrounding HTML element.
		 *			align    - an align attribute ('left','right','center' etc.)
		 *			true     - (type='bool') the representation of true.
		 *			false    - (type='bool') the representation of false.
		 *			function - (type='callback') a function name, accepts args ($str, $params) and returns a rendering.
		 *			lineno   - prefix each line with a line number.
		 *			map      - an associative array.
		 *
		 * @return The HTML rendered value
		 */
		function printVal($str, $type = null, $params = array()) {
			global $lang, $conf, $data;

			// Shortcircuit for a NULL value
			if (is_null($str))
				return isset($params['null'])
						? ($params['null'] === true ? 'NULL' : $params['null'])
						: '';

			if (isset($params['map']) && isset($params['map'][$str])) $str = $params['map'][$str];

			// Clip the value if the 'clip' parameter is true.
			if (isset($params['clip']) && $params['clip'] === true) {
				$maxlen = isset($params['cliplen']) && is_integer($params['cliplen']) ? $params['cliplen'] : $conf['max_chars'];
				$ellipsis = isset($params['ellipsis']) ? $params['ellipsis'] : $lang['strellipsis'];
				if (mb_strlen($str, 'UTF-8') > $maxlen) {
					$str = mb_substr($str, 0, $maxlen-1, 'UTF-8') . $ellipsis;
				}
			}

			$out = '';

			switch ($type) {
				case 'int2':
				case 'int4':
				case 'int8':
				case 'float4':
				case 'float8':
				case 'money':
				case 'numeric':
				case 'oid':
				case 'xid':
				case 'cid':
				case 'tid':
					$align = 'right';
					$out = nl2br(htmlspecialchars($str));
					break;
				case 'yesno':
					if (!isset($params['true'])) $params['true'] = $lang['stryes'];
					if (!isset($params['false'])) $params['false'] = $lang['strno'];
					// No break - fall through to boolean case.
				case 'bool':
				case 'boolean':
					if (is_bool($str)) $str = $str ? 't' : 'f';
					switch ($str) {
						case 't':
							$out = (isset($params['true']) ? $params['true'] : $lang['strtrue']);
							$align = 'center';
							break;
						case 'f':
							$out = (isset($params['false']) ? $params['false'] : $lang['strfalse']);
							$align = 'center';
							break;
						default:
							$out = htmlspecialchars($str);
					}
					break;
				case 'bytea':
					$tag = 'div';
					$class = 'pre';
					$out = $data->escapeBytea($str);
					break;
				case 'errormsg':
					$tag = 'pre';
					$class = 'error';
					$out = htmlspecialchars($str);
					break;
				case 'pre':
					$tag = 'pre';
					$out = htmlspecialchars($str);
					break;
				case 'prenoescape':
					$tag = 'pre';
					$out = $str;
					break;
				case 'nbsp':
					$out = nl2br(str_replace(' ', ' ', htmlspecialchars($str)));
					break;
				case 'verbatim':
					$out = $str;
					break;
				case 'callback':
					$out = $params['function']($str, $params);
					break;
				case 'prettysize':
					if ($str == -1) 
						$out = $lang['strnoaccess'];
					else
					{
						$limit = 10 * 1024;
						$mult = 1;
						if ($str < $limit * $mult)
							$out = $str.' '.$lang['strbytes'];
						else
						{
							$mult *= 1024;
							if ($str < $limit * $mult)
								$out = floor(($str + $mult / 2) / $mult).' '.$lang['strkb'];
							else
							{
								$mult *= 1024;
								if ($str < $limit * $mult)
									$out = floor(($str + $mult / 2) / $mult).' '.$lang['strmb'];
								else
								{
									$mult *= 1024;
									if ($str < $limit * $mult)
										$out = floor(($str + $mult / 2) / $mult).' '.$lang['strgb'];
									else
									{
										$mult *= 1024;
										if ($str < $limit * $mult)
											$out = floor(($str + $mult / 2) / $mult).' '.$lang['strtb'];
									}
								}
							}
						}
					}
					break;
				default:
					// If the string contains at least one instance of >1 space in a row, a tab
					// character, a space at the start of a line, or a space at the start of
					// the whole string then render within a pre-formatted element (
).
					if (preg_match('/(^ |  |\t|\n )/m', $str)) {
						$tag = 'pre';
						$class = 'data';
						$out = htmlspecialchars($str);
					} else {
						$out = nl2br(htmlspecialchars($str));
					}
			}

			if (isset($params['class'])) $class = $params['class'];
			if (isset($params['align'])) $align = $params['align'];

			if (!isset($tag) && (isset($class) || isset($align))) $tag = 'div';

			if (isset($tag)) {
				$alignattr = isset($align) ? " style=\"text-align: {$align}\"" : '';
				$classattr = isset($class) ? " class=\"{$class}\"" : '';
				$out = "<{$tag}{$alignattr}{$classattr}>{$out}";
			}

			// Add line numbers if 'lineno' param is true
			if (isset($params['lineno']) && $params['lineno'] === true) {
				$lines = explode("\n", $str);
				$num = count($lines);
				if ($num > 0) {
					$temp = "\n
";
					for ($i = 1; $i <= $num; $i++) {
						$temp .= $i . "\n";
					}
					$temp .= "
{$out}
\n"; $out = $temp; } unset($lines); } return $out; } /** * A function to recursively strip slashes. Used to * enforce magic_quotes_gpc being off. * @param &var The variable to strip */ function stripVar(&$var) { if (is_array($var)) { foreach($var as $k => $v) { $this->stripVar($var[$k]); /* magic_quotes_gpc escape keys as well ...*/ if (is_string($k)) { $ek = stripslashes($k); if ($ek !== $k) { $var[$ek] = $var[$k]; unset($var[$k]); } } } } else $var = stripslashes($var); } /** * Print out the page heading and help link * @param $title Title, already escaped * @param $help (optional) The identifier for the help link */ function printTitle($title, $help = null) { global $data, $lang; echo "

"; $this->printHelp($title, $help); echo "

\n"; } /** * Print out a message * @param $msg The message to print */ function printMsg($msg) { if ($msg != '') echo "

{$msg}

\n"; } /** * Creates a database accessor */ function getDatabaseAccessor($database, $server_id = null) { global $lang, $conf, $misc, $_connection; $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( $server_info['host'], $server_info['port'], $server_info['sslmode'], $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 in $platform. $_type = $_connection->getDriver($platform); if ($_type === null) { printf($lang['strpostgresqlversionnotsupported'], $postgresqlMinVer); exit; } $this->setServerInfo('platform', $platform, $server_id); $this->setServerInfo('pgVersion', $_connection->conn->pgVersion, $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->platform = $_connection->platform; /* we work on UTF-8 only encoding */ $data->execute("SET client_encoding TO 'UTF-8'"); if ($data->hasByteaHexDefault()) { $data->execute("SET bytea_output TO escape"); } return $data; } /** * Prints the page header. If global variable $_no_output is * set then no header is drawn. * @param $title The title of the page * @param $script script tag */ function printHeader($title = '', $script = null, $frameset = false) { global $appName, $lang, $_no_output, $conf, $plugin_manager; if (!isset($_no_output)) { header("Content-Type: text/html; charset=utf-8"); // Send XHTML headers, or regular XHTML strict headers echo "\n"; if ($frameset == true) { echo "\n"; } else if (isset($conf['use_xhtml_strict']) && $conf['use_xhtml_strict']) { echo "\n"; } else { echo "\n"; } echo "\n"; echo "\n"; echo "\n"; // Theme echo "\n"; echo "\n"; echo "\n"; echo ""; echo "\n"; echo "", htmlspecialchars($appName); if ($title != '') echo htmlspecialchars(" - {$title}"); echo "\n"; if ($script) echo "{$script}\n"; $plugins_head = array(); $_params = array('heads' => &$plugins_head); $plugin_manager->do_hook('head', $_params); foreach($plugins_head as $tag) { echo $tag; } echo "\n"; } } /** * Prints the page footer * @param $doBody True to output body tag, false otherwise */ function printFooter($doBody = true) { global $_reload_browser, $_reload_drop_database; global $lang, $_no_bottom_link; if ($doBody) { if (isset($_reload_browser)) $this->printReload(false); elseif (isset($_reload_drop_database)) $this->printReload(true); if (!isset($_no_bottom_link)) echo "".$lang['strgotoppage'].""; echo "\n"; } echo "\n"; } /** * Prints the page body. * @param $doBody True to output body tag, false otherwise * @param $bodyClass - name of body class */ function printBody($bodyClass = '', $doBody = true ) { global $_no_output; if (!isset($_no_output)) { if ($doBody) { $bodyClass = htmlspecialchars($bodyClass); echo "\n"; } } } /** * Outputs JavaScript code that will reload the browser * @param $database True if dropping a database, false otherwise */ function printReload($database) { echo "\n"; } /** * Display a link * @param $link An associative array of link parameters to print * link = array( * 'attr' => array( // list of A tag attribute * 'attrname' => attribute value * ... * ), * 'content' => The link text * 'fields' => (optional) the data from which content and attr's values are obtained * ); * the special attribute 'href' might be a string or an array. If href is an array it * will be generated by getActionUrl. See getActionUrl comment for array format. */ function printLink($link) { if (! isset($link['fields'])) $link['fields'] = $_REQUEST; $tag = " $value) { if ($attr == 'href' and is_array($value)) { $tag.= 'href="'. htmlentities($this->getActionUrl($value, $link['fields'])).'" '; } else { $tag.= htmlentities($attr).'="'. value($value, $link['fields'], 'html') .'" '; } } $tag.= ">". value($link['content'], $link['fields'], 'html') ."\n"; echo $tag; } /** * Display a list of links * @param $links An associative array of links to print. See printLink function for * the links array format. * @param $class An optional class or list of classes seprated by a space * WARNING: This field is NOT escaped! No user should be able to inject something here, use with care. */ function printLinksList($links, $class='') { echo "
    \n"; foreach ($links as $link) { echo "\t
  • "; $this->printLink($link); echo "
  • \n"; } echo "
\n"; } /** * Display navigation tabs * @param $tabs The name of current section (Ex: intro, server, ...), or an array with tabs (Ex: sqledit.php doFind function) * @param $activetab The name of the tab to be highlighted. */ function printTabs($tabs, $activetab) { global $misc, $conf, $data, $lang; if (is_string($tabs)) { $_SESSION['webdbLastTab'][$tabs] = $activetab; $tabs = $this->getNavTabs($tabs); } echo "\n"; #echo "
\n"; if (count($tabs) > 0) $width = (int)(100 / count($tabs)).'%'; else $width = 1; foreach ($tabs as $tab_id => $tab) { $active = ($tab_id == $activetab) ? ' active' : ''; if (!isset($tab['hide']) || $tab['hide'] !== true) { $tablink = ''; if (isset($tab['icon']) && $icon = $this->icon($tab['icon'])) $tablink .= "\"{$tab['title']}\""; $tablink .= "{$tab['title']}"; echo "
\n"; #echo "\n"; } } echo "
"; #echo ""; if (isset($tab['help'])) $this->printHelp($tablink, $tab['help']); else echo $tablink; echo "
\n"; #echo "\n"; } /** * Retrieve the tab info for a specific tab bar. * @param $section The name of the tab bar. */ function getNavTabs($section) { global $data, $lang, $conf, $plugin_manager; $hide_advanced = ($conf['show_advanced'] === false); $tabs = array(); switch ($section) { case 'root': $tabs = array ( 'intro' => array ( 'title' => $lang['strintroduction'], 'url' => "intro.php", 'icon' => 'Introduction', ), 'servers' => array ( 'title' => $lang['strservers'], 'url' => "servers.php", 'icon' => 'Servers', ), ); break; case 'server': $hide_users = !$data->isSuperUser(); $tabs = array ( 'databases' => array ( 'title' => $lang['strdatabases'], 'url' => 'all_db.php', 'urlvars' => array('subject' => 'server'), 'help' => 'pg.database', 'icon' => 'Databases', ) ); if ($data->hasRoles()) { $tabs = array_merge($tabs, array( 'roles' => array ( 'title' => $lang['strroles'], 'url' => 'roles.php', 'urlvars' => array('subject' => 'server'), 'hide' => $hide_users, 'help' => 'pg.role', 'icon' => 'Roles', ) )); } else { $tabs = array_merge($tabs, array( 'users' => array ( 'title' => $lang['strusers'], 'url' => 'users.php', 'urlvars' => array('subject' => 'server'), 'hide' => $hide_users, 'help' => 'pg.user', 'icon' => 'Users', ), 'groups' => array ( 'title' => $lang['strgroups'], 'url' => 'groups.php', 'urlvars' => array('subject' => 'server'), 'hide' => $hide_users, 'help' => 'pg.group', 'icon' => 'UserGroups', ) )); } $tabs = array_merge($tabs, array( 'account' => array ( 'title' => $lang['straccount'], 'url' => $data->hasRoles() ? 'roles.php' : 'users.php', 'urlvars' => array('subject' => 'server', 'action' => 'account'), 'hide' => !$hide_users, 'help' => 'pg.role', 'icon' => 'User', ), 'tablespaces' => array ( 'title' => $lang['strtablespaces'], 'url' => 'tablespaces.php', 'urlvars' => array('subject' => 'server'), 'hide' => (!$data->hasTablespaces()), 'help' => 'pg.tablespace', 'icon' => 'Tablespaces', ), 'export' => array ( 'title' => $lang['strexport'], 'url' => 'all_db.php', 'urlvars' => array('subject' => 'server', 'action' => 'export'), 'hide' => (!$this->isDumpEnabled()), 'icon' => 'Export', ), )); break; case 'database': $tabs = array ( 'schemas' => array ( 'title' => $lang['strschemas'], 'url' => 'schemas.php', 'urlvars' => array('subject' => 'database'), 'help' => 'pg.schema', 'icon' => 'Schemas', ), 'sql' => array ( 'title' => $lang['strsql'], 'url' => 'database.php', 'urlvars' => array('subject' => 'database', 'action' => 'sql', 'new' => 1), 'help' => 'pg.sql', 'tree' => false, 'icon' => 'SqlEditor' ), 'find' => array ( 'title' => $lang['strfind'], 'url' => 'database.php', 'urlvars' => array('subject' => 'database', 'action' => 'find'), 'tree' => false, 'icon' => 'Search' ), 'variables' => array ( 'title' => $lang['strvariables'], 'url' => 'database.php', 'urlvars' => array('subject' => 'database', 'action' => 'variables'), 'help' => 'pg.variable', 'tree' => false, 'icon' => 'Variables', ), 'processes' => array ( 'title' => $lang['strprocesses'], 'url' => 'database.php', 'urlvars' => array('subject' => 'database', 'action' => 'processes'), 'help' => 'pg.process', 'tree' => false, 'icon' => 'Processes', ), 'locks' => array ( 'title' => $lang['strlocks'], 'url' => 'database.php', 'urlvars' => array('subject' => 'database', 'action' => 'locks'), 'help' => 'pg.locks', 'tree' => false, 'icon' => 'Key', ), 'admin' => array ( 'title' => $lang['stradmin'], 'url' => 'database.php', 'urlvars' => array('subject' => 'database', 'action' => 'admin'), 'tree' => false, 'icon' => 'Admin', ), 'privileges' => array ( 'title' => $lang['strprivileges'], 'url' => 'privileges.php', 'urlvars' => array('subject' => 'database'), 'hide' => (!isset($data->privlist['database'])), 'help' => 'pg.privilege', 'tree' => false, 'icon' => 'Privileges', ), 'languages' => array ( 'title' => $lang['strlanguages'], 'url' => 'languages.php', 'urlvars' => array('subject' => 'database'), 'hide' => $hide_advanced, 'help' => 'pg.language', 'icon' => 'Languages', ), 'casts' => array ( 'title' => $lang['strcasts'], 'url' => 'casts.php', 'urlvars' => array('subject' => 'database'), 'hide' => ($hide_advanced), 'help' => 'pg.cast', 'icon' => 'Casts', ), 'export' => array ( 'title' => $lang['strexport'], 'url' => 'database.php', 'urlvars' => array('subject' => 'database', 'action' => 'export'), 'hide' => (!$this->isDumpEnabled()), 'tree' => false, 'icon' => 'Export', ), ); break; case 'schema': $tabs = array ( 'tables' => array ( 'title' => $lang['strtables'], 'url' => 'tables.php', 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.table', 'icon' => 'Tables', ), 'views' => array ( 'title' => $lang['strviews'], 'url' => 'views.php', 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.view', 'icon' => 'Views', ), 'sequences' => array ( 'title' => $lang['strsequences'], 'url' => 'sequences.php', 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.sequence', 'icon' => 'Sequences', ), 'functions' => array ( 'title' => $lang['strfunctions'], 'url' => 'functions.php', 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.function', 'icon' => 'Functions', ), 'fulltext' => array ( 'title' => $lang['strfulltext'], 'url' => 'fulltext.php', 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.fts', 'tree' => true, 'icon' => 'Fts', ), 'domains' => array ( 'title' => $lang['strdomains'], 'url' => 'domains.php', 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.domain', 'icon' => 'Domains', ), 'aggregates' => array ( 'title' => $lang['straggregates'], 'url' => 'aggregates.php', 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.aggregate', 'icon' => 'Aggregates', ), 'types' => array ( 'title' => $lang['strtypes'], 'url' => 'types.php', 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.type', 'icon' => 'Types', ), 'operators' => array ( 'title' => $lang['stroperators'], 'url' => 'operators.php', 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.operator', 'icon' => 'Operators', ), 'opclasses' => array ( 'title' => $lang['stropclasses'], 'url' => 'opclasses.php', 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.opclass', 'icon' => 'OperatorClasses', ), 'conversions' => array ( 'title' => $lang['strconversions'], 'url' => 'conversions.php', 'urlvars' => array('subject' => 'schema'), 'hide' => $hide_advanced, 'help' => 'pg.conversion', 'icon' => 'Conversions', ), 'privileges' => array ( 'title' => $lang['strprivileges'], 'url' => 'privileges.php', 'urlvars' => array('subject' => 'schema'), 'help' => 'pg.privilege', 'tree' => false, 'icon' => 'Privileges', ), 'export' => array ( 'title' => $lang['strexport'], 'url' => 'schemas.php', 'urlvars' => array('subject' => 'schema', 'action' => 'export'), 'hide' => (!$this->isDumpEnabled()), 'tree' => false, 'icon' => 'Export', ), ); if (!$data->hasFTS()) unset($tabs['fulltext']); break; case 'table': $tabs = array ( 'columns' => array ( 'title' => $lang['strcolumns'], 'url' => 'tblproperties.php', 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'icon' => 'Columns', 'branch'=> true, ), 'browse' => array( 'title' => $lang['strbrowse'], 'icon'=>'Columns', 'url' => 'display.php', 'urlvars' => array ('subject' => 'table','table' => field('table')), 'return' => 'table', ), 'select' => array( 'title' => $lang['strselect'], 'icon' => 'Search', 'url' => 'tables.php', 'urlvars' => array('subject' => 'table', 'table' => field('table'),'action' => 'confselectrows',), 'help' => 'pg.sql.select', ), 'insert'=>array( 'title' => $lang['strinsert'], 'url' => 'tables.php', 'urlvars' => array ( 'action' => 'confinsertrow', 'table' => field('table') ), 'help' => 'pg.sql.insert', 'icon'=>'Operator' ), 'indexes' => array ( 'title' => $lang['strindexes'], 'url' => 'indexes.php', 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.index', 'icon' => 'Indexes', 'branch'=> true, ), 'constraints' => array ( 'title' => $lang['strconstraints'], 'url' => 'constraints.php', 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.constraint', 'icon' => 'Constraints', 'branch'=> true, ), 'triggers' => array ( 'title' => $lang['strtriggers'], 'url' => 'triggers.php', 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.trigger', 'icon' => 'Triggers', 'branch'=> true, ), 'rules' => array ( 'title' => $lang['strrules'], 'url' => 'rules.php', 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.rule', 'icon' => 'Rules', 'branch'=> true, ), 'admin' => array ( 'title' => $lang['stradmin'], 'url' => 'tables.php', 'urlvars' => array('subject' => 'table', 'table' => field('table'), 'action' => 'admin'), 'icon' => 'Admin', ), 'info' => array ( 'title' => $lang['strinfo'], 'url' => 'info.php', 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'icon' => 'Statistics', ), 'privileges' => array ( 'title' => $lang['strprivileges'], 'url' => 'privileges.php', 'urlvars' => array('subject' => 'table', 'table' => field('table')), 'help' => 'pg.privilege', 'icon' => 'Privileges', ), 'import' => array ( 'title' => $lang['strimport'], 'url' => 'tblproperties.php', 'urlvars' => array('subject' => 'table', 'table' => field('table'), 'action' => 'import'), 'icon' => 'Import', 'hide' => false, ), 'export' => array ( 'title' => $lang['strexport'], 'url' => 'tblproperties.php', 'urlvars' => array('subject' => 'table', 'table' => field('table'), 'action' => 'export'), 'icon' => 'Export', 'hide' => false, ), ); break; case 'view': $tabs = array ( 'columns' => array ( 'title' => $lang['strcolumns'], 'url' => 'viewproperties.php', 'urlvars' => array('subject' => 'view', 'view' => field('view')), 'icon' => 'Columns', 'branch'=> true, ), 'browse' => array( 'title' => $lang['strbrowse'], 'icon'=>'Columns', 'url' => 'display.php', 'urlvars' => array ( 'action' => 'confselectrows', 'return' => 'schema', 'subject' => 'view', 'view' => field('view') ), ), 'select' => array( 'title' => $lang['strselect'], 'icon' => 'Search', 'url' => 'views.php', 'urlvars' => array('action' => 'confselectrows', 'view' => field('view'),), 'help' => 'pg.sql.select', ), 'definition' => array ( 'title' => $lang['strdefinition'], 'url' => 'viewproperties.php', 'urlvars' => array('subject' => 'view', 'view' => field('view'), 'action' => 'definition'), 'icon' => 'Definition' ), 'rules' => array ( 'title' => $lang['strrules'], 'url' => 'rules.php', 'urlvars' => array('subject' => 'view', 'view' => field('view')), 'help' => 'pg.rule', 'icon' => 'Rules', 'branch'=> true, ), 'privileges' => array ( 'title' => $lang['strprivileges'], 'url' => 'privileges.php', 'urlvars' => array('subject' => 'view', 'view' => field('view')), 'help' => 'pg.privilege', 'icon' => 'Privileges', ), 'export' => array ( 'title' => $lang['strexport'], 'url' => 'viewproperties.php', 'urlvars' => array('subject' => 'view', 'view' => field('view'), 'action' => 'export'), 'icon' => 'Export', 'hide' => false, ), ); break; case 'function': $tabs = array ( 'definition' => array ( 'title' => $lang['strdefinition'], 'url' => 'functions.php', 'urlvars' => array( 'subject' => 'function', 'function' => field('function'), 'function_oid' => field('function_oid'), 'action' => 'properties', ), 'icon' => 'Definition', ), 'privileges' => array ( 'title' => $lang['strprivileges'], 'url' => 'privileges.php', 'urlvars' => array( 'subject' => 'function', 'function' => field('function'), 'function_oid' => field('function_oid'), ), 'icon' => 'Privileges', ), ); break; case 'aggregate': $tabs = array ( 'definition' => array ( 'title' => $lang['strdefinition'], 'url' => 'aggregates.php', 'urlvars' => array( 'subject' => 'aggregate', 'aggrname' => field('aggrname'), 'aggrtype' => field('aggrtype'), 'action' => 'properties', ), 'icon' => 'Definition', ), ); break; case 'role': $tabs = array ( 'definition' => array ( 'title' => $lang['strdefinition'], 'url' => 'roles.php', 'urlvars' => array( 'subject' => 'role', 'rolename' => field('rolename'), 'action' => 'properties', ), 'icon' => 'Definition', ), ); break; case 'popup': $tabs = array ( 'sql' => array ( 'title' => $lang['strsql'], 'url' => 'sqledit.php', 'urlvars' => array('subject' => 'schema', 'action' => 'sql'), 'help' => 'pg.sql', 'icon' => 'SqlEditor', ), 'find' => array ( 'title' => $lang['strfind'], 'url' => 'sqledit.php', 'urlvars' => array('subject' => 'schema', 'action' => 'find'), 'icon' => 'Search', ), ); break; case 'column': $tabs = array( 'properties' => array ( 'title' => $lang['strcolprop'], 'url' => 'colproperties.php', 'urlvars' => array( 'subject' => 'column', 'table' => field('table'), 'column' => field('column') ), 'icon' => 'Column' ), 'privileges' => array ( 'title' => $lang['strprivileges'], 'url' => 'privileges.php', 'urlvars' => array( 'subject' => 'column', 'table' => field('table'), 'column' => field('column') ), 'help' => 'pg.privilege', 'icon' => 'Privileges', ) ); break; case 'fulltext': $tabs = array ( 'ftsconfigs' => array ( 'title' => $lang['strftstabconfigs'], 'url' => 'fulltext.php', 'urlvars' => array('subject' => 'schema'), 'hide' => !$data->hasFTS(), 'help' => 'pg.ftscfg', 'tree' => true, 'icon' => 'FtsCfg', ), 'ftsdicts' => array ( 'title' => $lang['strftstabdicts'], 'url' => 'fulltext.php', 'urlvars' => array('subject' => 'schema', 'action' => 'viewdicts'), 'hide' => !$data->hasFTS(), 'help' => 'pg.ftsdict', 'tree' => true, 'icon' => 'FtsDict', ), 'ftsparsers' => array ( 'title' => $lang['strftstabparsers'], 'url' => 'fulltext.php', 'urlvars' => array('subject' => 'schema', 'action' => 'viewparsers'), 'hide' => !$data->hasFTS(), 'help' => 'pg.ftsparser', 'tree' => true, 'icon' => 'FtsParser', ), ); break; } // Tabs hook's place $plugin_functions_parameters = array( 'tabs' => &$tabs, 'section' => $section ); $plugin_manager->do_hook('tabs', $plugin_functions_parameters); return $tabs; } /** * Get the URL for the last active tab of a particular tab bar. */ function getLastTabURL($section) { global $data; $tabs = $this->getNavTabs($section); if (isset($_SESSION['webdbLastTab'][$section]) && isset($tabs[$_SESSION['webdbLastTab'][$section]])) $tab = $tabs[$_SESSION['webdbLastTab'][$section]]; else $tab = reset($tabs); return isset($tab['url']) ? $tab : null; } function printTopbar() { global $lang, $conf, $plugin_manager, $appName, $appVersion, $appLangFiles; $server_info = $this->getServerInfo(); $reqvars = $this->getRequestVars('table'); echo "
"; /* top right information when connected */ $toplinks = array ( 'sql' => array ( 'attr' => array ( 'href' => array ( 'url' => 'sqledit.php', 'urlvars' => array_merge($reqvars, array ( 'action' => 'sql' )) ), 'target' => "sqledit", 'id' => 'toplink_sql', ), 'content' => $lang['strsql'] ), 'history' => array ( 'attr'=> array ( 'href' => array ( 'url' => 'history.php', 'urlvars' => array_merge($reqvars, array ( 'action' => 'pophistory' )) ), 'id' => 'toplink_history', ), 'content' => $lang['strhistory'] ), 'find' => array ( 'attr' => array ( 'href' => array ( 'url' => 'sqledit.php', 'urlvars' => array_merge($reqvars, array ( 'action' => 'find' )) ), 'target' => "sqledit", 'id' => 'toplink_find', ), 'content' => $lang['strfind'] ), 'logout' => array( 'attr' => array ( 'href' => array ( 'url' => 'servers.php', 'urlvars' => array ( 'action' => 'logout', 'logoutServer' => "{$server_info['host']}:{$server_info['port']}:{$server_info['sslmode']}" ) ), 'id' => 'toplink_logout', ), 'content' => $lang['strlogout'] ) ); // Toplink hook's place $plugin_functions_parameters = array( 'toplinks' => &$toplinks ); $plugin_manager->do_hook('toplinks', $plugin_functions_parameters); echo ""; $sql_window_id = htmlentities('sqledit:'.$_REQUEST['server']); $history_window_id = htmlentities('history:'.$_REQUEST['server']); echo ""; } else { echo "{$appName}{$appVersion}"; } /* echo ""; */ echo "
"; if ($server_info && isset($server_info['platform']) && isset($server_info['username'])) { /* top left information when connected */ echo sprintf($lang['strtopbar'], ''.htmlspecialchars($server_info['platform']).'', ''.htmlspecialchars((empty($server_info['host'])) ? 'localhost':$server_info['host']).'', ''.htmlspecialchars($server_info['port']).'', ''.htmlspecialchars($server_info['username']).''); echo ""; $this->printLinksList($toplinks, 'toplink'); 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); } echo "
"; foreach ($trail as $crumb) { echo ""; } echo "
"; $crumblink = "icon($crumb['icon'])) $crumblink .= "\"{$iconalt}\""; $crumblink .= "" . htmlspecialchars($crumb['text']) . ""; if (isset($crumb['help'])) $this->printHelp($crumblink, $crumb['help']); else echo $crumblink; echo "{$lang['strseparator']}"; echo "
\n"; } /** * Create a bread crumb trail of the object hierarchy. * @param $object The type of object at the end of the trail. */ function getTrail($subject = null) { global $lang, $conf, $data, $appName, $plugin_manager; $trail = array(); $vars = ''; $done = false; $trail['root'] = array( 'text' => $appName, 'url' => 'redirect.php?subject=root', 'icon' => 'Introduction' ); if ($subject == 'root') $done = true; if (!$done) { $server_info = $this->getServerInfo(); $trail['server'] = array( 'title' => $lang['strserver'], 'text' => $server_info['desc'], 'url' => $this->getHREFSubject('server'), 'help' => 'pg.server', 'icon' => 'Server' ); } if ($subject == 'server') $done = true; if (isset($_REQUEST['database']) && !$done) { $trail['database'] = array( 'title' => $lang['strdatabase'], 'text' => $_REQUEST['database'], 'url' => $this->getHREFSubject('database'), 'help' => 'pg.database', 'icon' => 'Database' ); } elseif (isset($_REQUEST['rolename']) && !$done) { $trail['role'] = array( 'title' => $lang['strrole'], 'text' => $_REQUEST['rolename'], 'url' => $this->getHREFSubject('role'), 'help' => 'pg.role', 'icon' => 'Roles' ); } if ($subject == 'database' || $subject == 'role') $done = true; if (isset($_REQUEST['schema']) && !$done) { $trail['schema'] = array( 'title' => $lang['strschema'], 'text' => $_REQUEST['schema'], 'url' => $this->getHREFSubject('schema'), 'help' => 'pg.schema', 'icon' => 'Schema' ); } if ($subject == 'schema') $done = true; if (isset($_REQUEST['table']) && !$done) { $trail['table'] = array( 'title' => $lang['strtable'], 'text' => $_REQUEST['table'], 'url' => $this->getHREFSubject('table'), 'help' => 'pg.table', 'icon' => 'Table' ); } elseif (isset($_REQUEST['view']) && !$done) { $trail['view'] = array( 'title' => $lang['strview'], 'text' => $_REQUEST['view'], 'url' => $this->getHREFSubject('view'), 'help' => 'pg.view', 'icon' => 'View' ); } elseif (isset($_REQUEST['ftscfg']) && !$done) { $trail['ftscfg'] = array( 'title' => $lang['strftsconfig'], 'text' => $_REQUEST['ftscfg'], 'url' => $this->getHREFSubject('ftscfg'), 'help' => 'pg.ftscfg.example', 'icon' => 'Fts' ); } if ($subject == 'table' || $subject == 'view' || $subject == 'ftscfg') $done = true; if (!$done && !is_null($subject)) { switch ($subject) { case 'function': $trail[$subject] = array( 'title' => $lang['str'.$subject], 'text' => $_REQUEST[$subject], 'url' => $this->getHREFSubject('function'), 'help' => 'pg.function', 'icon' => 'Function' ); break; case 'aggregate': $trail[$subject] = array( 'title' => $lang['straggregate'], 'text' => $_REQUEST['aggrname'], 'url' => $this->getHREFSubject('aggregate'), 'help' => 'pg.aggregate', 'icon' => 'Aggregate' ); break; case 'column': $trail['column'] = array ( 'title' => $lang['strcolumn'], 'text' => $_REQUEST['column'], 'icon' => 'Column', 'url' => $this->getHREFSubject('column') ); break; default: if (isset($_REQUEST[$subject])) { switch ($subject) { case 'domain': $icon = 'Domain'; break; case 'sequence': $icon = 'Sequence'; break; case 'type': $icon = 'Type'; break; case 'operator': $icon = 'Operator'; break; default: $icon = null; break; } $trail[$subject] = array( 'title' => $lang['str'.$subject], 'text' => $_REQUEST[$subject], 'help' => 'pg.'.$subject, 'icon' => $icon, ); } } } // Trail hook's place $plugin_functions_parameters = array( 'trail' => &$trail, 'section' => $subject ); $plugin_manager->do_hook('trail', $plugin_functions_parameters); return $trail; } /** * Display the navlinks * * @param $navlinks - An array with the the attributes and values that will be shown. See printLinksList for array format. * @param $place - Place where the $navlinks are displayed. Like 'display-browse', where 'display' is the file (display.php) * @param $env - Associative array of defined variables in the scope of the caller. * Allows to give some environment details to plugins. * and 'browse' is the place inside that code (doBrowse). */ function printNavLinks($navlinks, $place, $env = array()) { global $plugin_manager; // Navlinks hook's place $plugin_functions_parameters = array( 'navlinks' => &$navlinks, 'place' => $place, 'env' => $env ); $plugin_manager->do_hook('navlinks', $plugin_functions_parameters); if (count($navlinks) > 0) { $this->printLinksList($navlinks, 'navlink'); } } /** * Do multi-page navigation. Displays the prev, next and page options. * @param $page - the page currently viewed * @param $pages - the maximum number of pages * @param $gets - the parameters to include in the link to the wanted page * @param $max_width - the number of pages to make available at any one time (default = 20) */ function printPages($page, $pages, $gets, $max_width = 20) { global $lang; $window = 10; if ($page < 0 || $page > $pages) return; if ($pages < 0) return; if ($max_width <= 0) return; unset ($gets['page']); $url = http_build_query($gets); if ($pages > 1) { echo "

\n"; if ($page != 1) { echo "{$lang['strfirst']}\n"; $temp = $page - 1; echo "{$lang['strprev']}\n"; } 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); for ($i = $min_page; $i <= $max_page; $i++) { #if ($i != $page) echo "$i\n"; if ($i != $page) echo "$i\n"; else echo "$i\n"; } if ($page != $pages) { $temp = $page + 1; echo "{$lang['strnext']}\n"; echo "{$lang['strlast']}\n"; } echo "

\n"; } } /** * Displays link to the context help. * @param $str - the string that the context help is related to (already escaped) * @param $help - help section identifier */ function printHelp($str, $help) { global $lang, $data; echo $str; if ($help) { echo "{$lang['strhelpicon']}"; } } /** * Outputs JavaScript to set default focus * @param $object eg. forms[0].username */ function setFocus($object) { 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 publicly available * function by Chris DeRose, here: http://www.php.net/manual/en/configuration.directives.php#ini.file-uploads * @param $strIniSize The PHP.INI variable * @return size in bytes, false on failure */ 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 unparsable. $a_IniParts = array(); if (!is_string($strIniSize)) return false; if (!preg_match ('/^(\d+)([bkm]*)$/i', $strIniSize,$a_IniParts)) return false; $nSize = (double) $a_IniParts[1]; $strUnit = strtolower($a_IniParts[2]); switch($strUnit) { case 'm': return ($nSize * (double) 1048576); case 'k': return ($nSize * (double) 1024); case 'b': default: return $nSize; } } /** * Returns URL given an action associative array. * NOTE: this function does not html-escape, only url-escape * @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 * @param $fields Field data from which 'urlfield' and 'vars' are obtained. */ function getActionUrl(&$action, &$fields) { $url = value($action['url'], $fields); if ($url === false) return ''; if (!empty($action['urlvars'])) { $urlvars = value($action['urlvars'], $fields); } else { $urlvars = array(); } /* set server, database and schema parameter if not presents */ if (isset($urlvars['subject'])) $subject = value($urlvars['subject'], $fields); else $subject = ''; if (isset($_REQUEST['server']) and !isset($urlvars['server']) and $subject != 'root') { $urlvars['server'] = $_REQUEST['server']; if (isset($_REQUEST['database']) and !isset($urlvars['database']) and $subject != 'server') { $urlvars['database'] = $_REQUEST['database']; if (isset($_REQUEST['schema']) and !isset($urlvars['schema']) and $subject != 'database') { $urlvars['schema'] = $_REQUEST['schema']; } } } $sep = '?'; foreach ($urlvars as $var => $varfield) { $url .= $sep . value_url($var, $fields) . '=' . value_url($varfield, $fields); $sep = '&'; } 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]), "&"; } } /** * Display a table of data. * @param $tabledata A set of data to be formatted, as returned by $data->getDatabases() etc. * @param $columns An associative array of columns to be displayed: * $columns = array( * column_id => array( * 'title' => Column heading, * 'class' => The class to apply on the column cells, * 'field' => Field name for $tabledata->fields[...], * 'help' => Help page for this column, * ), ... * ); * @param $actions Actions that can be performed on each object: * $actions = array( * * multi action support * * parameters are serialized for each entries and given in $_REQUEST['ma'] * 'multiactions' => array( * 'keycols' => Associative array of (URL variable => field name), // fields included in the form * 'url' => URL submission, * 'default' => Default selected action in the form. * if null, an empty action is added & selected * ), * * actions * * action_id => array( * 'title' => Action heading, * 'url' => Static part of URL. Often we rely * relative urls, usually the page itself (not '' !), or just a query string, * 'vars' => Associative array of (URL variable => field name), * 'multiaction' => Name of the action to execute. * Add this action to the multi action form * ), ... * ); * @param $place Place where the $actions are displayed. Like 'display-browse', where 'display' is the file (display.php) * and 'browse' is the place inside that code (doBrowse). * @param $nodata (optional) Message to display if data set is empty. * @param $pre_fn (optional) Name of a function to call for each row, * it will be passed two params: $rowdata and $actions, * it may be used to derive new fields or modify actions. * It can return an array of actions specific to the row, * or if nothing is returned then the standard actions are used. * (see tblproperties.php and constraints.php for examples) * The function must not must not store urls because * they are relative and won't work out of context. */ function printTable(&$tabledata, &$columns, &$actions, $place, $nodata = null, $pre_fn = null) { global $data, $conf, $misc, $lang, $plugin_manager; // Action buttons hook's place $plugin_functions_parameters = array( 'actionbuttons' => &$actions, 'place' => $place ); $plugin_manager->do_hook('actionbuttons', $plugin_functions_parameters); if ($has_ma = isset($actions['multiactions'])) $ma = $actions['multiactions']; unset($actions['multiactions']); if ($tabledata->recordCount() > 0) { // Remove the 'comment' column if they have been disabled if (!$conf['show_comments']) { unset($columns['comment']); } if (isset($columns['comment'])) { // Uncomment this for clipped comments. // TODO: This should be a user option. //$columns['comment']['params']['clip'] = true; } if ($has_ma) { echo "\n"; echo "
\n"; if (isset($ma['vars'])) foreach ($ma['vars'] as $k => $v) echo ""; } echo "\n"; echo "\n"; // Handle cases where no class has been passed if (isset($column['class'])) { $class = $column['class'] !== '' ? " class=\"{$column['class']}\"":''; } else { $class = ''; } // Display column headings if ($has_ma) echo ""; foreach ($columns as $column_id => $column) { switch ($column_id) { case 'actions': if (sizeof($actions) > 0) echo "\n"; break; default: echo "\n"; break; } } echo "\n"; // Display table rows $i = 0; while (!$tabledata->EOF) { $id = ($i % 2) + 1; unset($alt_actions); if (!is_null($pre_fn)) $alt_actions = $pre_fn($tabledata, $actions); if (!isset($alt_actions)) $alt_actions =& $actions; echo "\n"; if ($has_ma) { foreach ($ma['keycols'] as $k => $v) $a[$k] = $tabledata->fields[$v]; echo "\n"; } foreach ($columns as $column_id => $column) { // Apply default values for missing parameters if (isset($column['url']) && !isset($column['vars'])) $column['vars'] = array(); switch ($column_id) { case 'actions': foreach ($alt_actions as $action) { if (isset($action['disable']) && $action['disable'] === true) { echo "\n"; } else { echo "\n"; } } break; case 'comment': echo ""; break; default: echo ""; $val = value($column['field'], $tabledata->fields); if (!is_null($val)) { if (isset($column['url'])) { echo "printUrlVars($column['vars'], $tabledata->fields); echo "\">"; } $type = isset($column['type']) ? $column['type'] : null; $params = isset($column['params']) ? $column['params'] : array(); echo $misc->printVal($val, $type, $params); if (isset($column['url'])) echo ""; } echo "\n"; break; } } echo "\n"; $tabledata->moveNext(); $i++; } echo "
{$column['title']}"; if (isset($column['help'])) $this->printHelp($column['title'], $column['help']); else echo $column['title']; echo "
"; echo ""; echo ""; $action['fields'] = $tabledata->fields; $this->printLink($action); echo ""; $val = value($column['field'], $tabledata->fields); if (!is_null($val)) { echo htmlentities($val); } echo "
\n"; // Multi action table footer w/ options & [un]check'em all if ($has_ma) { // if default is not set or doesn't exist, set it to null if (!isset($ma['default']) || !isset($actions[$ma['default']])) $ma['default'] = null; echo "
\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
{$lang['stractionsonmultiplelines']}
"; echo "{$lang['strselectall']} / "; echo "{$lang['strunselectall']} ---> \n"; echo "\t\n"; echo "\n"; echo $misc->form; echo "
\n"; echo '
'; }; return true; } else { if (!is_null($nodata)) { echo "

{$nodata}

\n"; } return false; } } /** 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 * 'iconAction' - URL to visit when single clicking the icon 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 * @param $section The section where the branch is linked in the tree */ function printTree(&$_treedata, &$attrs, $section) { global $plugin_manager; $treedata = array(); if ($_treedata->recordCount() > 0) { while (!$_treedata->EOF) { $treedata[] = $_treedata->fields; $_treedata->moveNext(); } } $tree_params = array( 'treedata' => &$treedata, 'attrs' => &$attrs, 'section' => $section ); $plugin_manager->do_hook('tree', $tree_params); $this->printTreeXML($treedata, $attrs); } /** 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 * 'iconAction' - URL to visit when single clicking the icon 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; charset=UTF-8"); header("Cache-Control: no-cache"); echo "\n"; echo "\n"; if (count($treedata) > 0) { foreach($treedata as $rec) { echo "icon(value($attrs['icon'], $rec)); echo value_xml_attr('icon', $icon, $rec); echo value_xml_attr('iconaction', $attrs['iconAction'], $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"; } } else { $msg = isset($attrs['nodata']) ? $attrs['nodata'] : $lang['strnoobjects']; echo "icon('ObjectNotFound'), "\" />\n"; } echo "\n"; } function adjustTabsForTree(&$tabs) { include_once('./classes/ArrayRecordSet.php'); foreach ($tabs as $i => $tab) { if ((isset($tab['hide']) && $tab['hide'] === true) || (isset($tab['tree']) && $tab['tree'] === false)) { unset($tabs[$i]); } } return new ArrayRecordSet($tabs); } function icon($icon) { if (is_string($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'; } else { // Icon from plugins $path = "plugins/{$icon[0]}/images/{$icon[1]}"; 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 * @return The escaped string */ function escapeShellArg($str) { global $data, $lang; if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { // Due to annoying PHP bugs, shell arguments cannot be escaped // (command simply fails), so we cannot allow complex objects // to be dumped. if (preg_match('/^[_.[:alnum:]]+$/', $str)) return $str; else { echo $lang['strcannotdumponwindows']; exit; } } else return escapeshellarg($str); } /** * Function to escape command line programs * @param $str The string to escape * @return The escaped string */ function escapeShellCmd($str) { global $data; if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $data->fieldClean($str); return '"' . $str . '"'; } else return escapeshellcmd($str); } /** * Get list of servers' groups if existing in the conf * @return a recordset of servers' groups */ function getServersGroups($recordset = false, $group_id = false) { global $conf, $lang; $grps = array(); if (isset($conf['srv_groups'])) { foreach ($conf['srv_groups'] as $i => $group) { if ( (($group_id === false) and (! isset($group['parents']))) /* root */ or ( ($group_id !== false) and isset($group['parents']) and in_array($group_id,explode(',', preg_replace('/\s/', '', $group['parents']) )) ) /* nested group */ ) $grps[$i] = array( 'id' => $i, 'desc' => $group['desc'], 'icon' => 'Servers', 'action' => url('servers.php', array( 'group' => field('id') ) ), 'branch' => url('servers.php', array( 'action' => 'tree', 'group' => $i ) ) ); } if ($group_id === false) $grps['all'] = array( 'id' => 'all', 'desc' => $lang['strallservers'], 'icon' => 'Servers', 'action' => url('servers.php', array( 'group' => field('id') ) ), 'branch' => url('servers.php', array( 'action' => 'tree', 'group' => 'all' ) ) ); } if ($recordset) { include_once('./classes/ArrayRecordSet.php'); return new ArrayRecordSet($grps); } return $grps; } /** * Get list of servers * @param $recordset return as RecordSet suitable for printTable if true, * otherwise just return an array. * @param $group a group name to filter the returned servers using $conf[srv_groups] */ function getServers($recordset = false, $group = false) { global $conf; $logins = isset($_SESSION['webdbLogin']) && is_array($_SESSION['webdbLogin']) ? $_SESSION['webdbLogin'] : array(); $srvs = array(); if (($group !== false) and ($group !== 'all')) if (isset($conf['srv_groups'][$group]['servers'])) $group = array_fill_keys(explode(',', preg_replace('/\s/', '', $conf['srv_groups'][$group]['servers'])), 1); else $group = ''; foreach($conf['servers'] as $idx => $info) { $server_id = $info['host'].':'.$info['port'].':'.$info['sslmode']; if (($group === false) or (isset($group[$idx])) or ($group === 'all') ) { $server_id = $info['host'].':'.$info['port'].':'.$info['sslmode']; if (isset($logins[$server_id])) $srvs[$server_id] = $logins[$server_id]; else $srvs[$server_id] = $info; $srvs[$server_id]['id'] = $server_id; $srvs[$server_id]['action'] = url('redirect.php', array( 'subject' => 'server', 'server' => field('id') ) ); if (isset($srvs[$server_id]['username'])) { $srvs[$server_id]['icon'] = 'Server'; $srvs[$server_id]['branch'] = url('all_db.php', array( 'action' => 'tree', 'subject' => 'server', 'server' => field('id') ) ); } else { $srvs[$server_id]['icon'] = 'DisconnectedServer'; $srvs[$server_id]['branch'] = false; } } } 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; } /** * Validate and retrieve 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, $_reload_browser, $lang; 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'].':'.$info['sslmode']) { // Automatically use shared credentials if available if (!isset($info['username']) && isset($_SESSION['sharedUsername'])) { $info['username'] = $_SESSION['sharedUsername']; $info['password'] = $_SESSION['sharedPassword']; $_reload_browser = true; $this->setServerInfo(null, $info, $server_id); } return $info; } } if ($server_id === null){ return null; } else { // Unable to find a matching server, are we being hacked? echo $lang['strinvalidserverparam']; exit; } } /** * 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; } } /** * Set the current schema * @param $schema The schema name * @return 0 on success * @return $data->seSchema() on error */ function setCurrentSchema($schema) { global $data; $status = $data->setSchema($schema); if($status != 0) return $status; $_REQUEST['schema'] = $schema; $this->setHREF(); return 0; } /** * Save the given SQL script in the history * of the database and server. * @param $script the SQL script to save. */ function saveScriptHistory($script) { list($usec, $sec) = explode(' ', microtime()); $time = ((float)$usec + (float)$sec); $_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]["$time"] = array( 'query' => $script, 'paginate' => (!isset($_REQUEST['paginate'])? 'f':'t'), 'queryid' => $time, ); } /* * Output dropdown list to select server and * databases form the popups windows. * @param $onchange Javascript action to take when selections change. */ function printConnection($onchange) { global $data, $lang, $misc; echo "
\n"; echo ""; echo ": \n\n"; // Get the list of all databases $databases = $data->getDatabases(); if ($databases->recordCount() > 0) { echo "\n"; } else { $server_info = $misc->getServerInfo(); echo "\n"; } echo "
\n"; } /** * returns an array representing FKs definition for a table, sorted by fields * or by constraint. * @param $table The table to retrieve FK constraints from * @returns the array of FK definition: * array( * 'byconstr' => array( * constrain id => array( * confrelid => foreign relation oid * f_schema => foreign schema name * f_table => foreign table name * pattnums => array of parent's fields nums * pattnames => array of parent's fields names * fattnames => array of foreign attributes names * ) * ), * 'byfield' => array( * attribute num => array (constraint id, ...) * ), * 'code' => HTML/js code to include in the page for auto-completion * ) **/ function getAutocompleteFKProperties($table) { global $data; $fksprops = array( 'byconstr' => array(), 'byfield' => array(), 'code' => '' ); $constrs = $data->getConstraintsWithFields($table); if (!$constrs->EOF) { $conrelid = $constrs->fields['conrelid']; while(!$constrs->EOF) { if ($constrs->fields['contype'] == 'f') { if (!isset($fksprops['byconstr'][$constrs->fields['conid']])) { $fksprops['byconstr'][$constrs->fields['conid']] = array ( 'confrelid' => $constrs->fields['confrelid'], 'f_table' => $constrs->fields['f_table'], 'f_schema' => $constrs->fields['f_schema'], 'pattnums' => array(), 'pattnames' => array(), 'fattnames' => array() ); } $fksprops['byconstr'][$constrs->fields['conid']]['pattnums'][] = $constrs->fields['p_attnum']; $fksprops['byconstr'][$constrs->fields['conid']]['pattnames'][] = $constrs->fields['p_field']; $fksprops['byconstr'][$constrs->fields['conid']]['fattnames'][] = $constrs->fields['f_field']; if (!isset($fksprops['byfield'][$constrs->fields['p_attnum']])) $fksprops['byfield'][$constrs->fields['p_attnum']] = array(); $fksprops['byfield'][$constrs->fields['p_attnum']][] = $constrs->fields['conid']; } $constrs->moveNext(); } $fksprops['code'] = "\n"; $fksprops['code'] .= '
'; $fksprops['code'] .= '
'; $fksprops['code'] .= ''; } else /* we have no foreign keys on this table */ return false; return $fksprops; } } ?>